Files
skills/docs/api-stack/api/api-plugin-vault/src/schemas/vault-item.md
2026-05-29 08:20:56 +01:00

3.8 KiB

schemas/vault-item

Purpose

Zod schemas describing the wire shape of every body, parameter, and response handled by the 5 vault routes. Every schema is the single source of truth: RouteBuilder registers them on the OpenAPI document, Hono's c.req.valid("json") inference flows from them, and downstream test fixtures derive sample data from them via z.infer.

The schemas exist at the boundary, not inside the encrypted container — they describe what clients send and receive, not what is persisted on disk. Persistence schemas live with @suaveplan/vault itself.

Features

  • 8 schemas: VaultItemMetadataSchema, VaultItemSummarySchema, VaultItemSchema, VaultItemResponseSchema, VaultItemListResponseSchema, CreateVaultItemBodySchema, UpdateVaultItemBodySchema (strict mode), DeleteVaultItemResponseSchema, plus VaultItemParamsSchema for the URL {id} segment.
  • UpdateVaultItemBodySchema uses .strict() so unknown fields cause a Zod parse error — protects against typos and prevents schema-drift by silently accepting client-side keys the server does not understand.
  • body is z.string() so clients can carry arbitrary JSON, base64, or text; size enforcement happens at the route layer against options.maxItemSizeBytes.
  • Paginated response carries meta: { total } — sufficient for v1; a cursor field will land in a follow-up change once the underlying vault library exposes one.

Usage: Basic

import { CreateVaultItemBodySchema } from "@suaveplan/api-plugin-vault";

const parsed = CreateVaultItemBodySchema.parse({
    title: "API key",
    kind: "credential",
    body: JSON.stringify({ user: "alice", key: "k..." }),
});

Usage: Advanced

import {
    type CreateVaultItemBody,
    type UpdateVaultItemBody,
    UpdateVaultItemBodySchema,
} from "@suaveplan/api-plugin-vault";

const result = UpdateVaultItemBodySchema.safeParse({
    title: "X",
    evil: "Y",
});
// result.success === false; result.error lists "Unrecognized key(s): evil"

API Reference

VaultItemSummarySchema

Object with id, ownerId, title (1..512), kind (1..128), metadata (optional record), createdAt, updatedAt.

VaultItemSchema

Extends VaultItemSummarySchema with body: string.

VaultItemResponseSchema, VaultItemListResponseSchema,

DeleteVaultItemResponseSchema

Envelope responses returned by the 5 routes. The success envelope is the standard { success: true, data } shape used across suaveplan; errors use the shared ErrorResponseSchema from @suaveplan/api-openapi.

CreateVaultItemBodySchema

POST body: title, kind, body, optional metadata. All four fields validated as non-empty/length-bounded where applicable.

UpdateVaultItemBodySchema

PATCH body (strict). Every field optional; metadata may be set to omit. Unknown fields rejected.

VaultItemParamsSchema

URL params: { id: string }.

Type aliases

VaultItemSummaryType, VaultItemType, VaultItemResponseType, VaultItemListResponseType, CreateVaultItemBody, UpdateVaultItemBody, DeleteVaultItemResponseType, VaultItemParams.

Implementation Notes

  • metadata uses z.record(z.string(), z.unknown()) rather than an explicit nested shape because callers attach app-specific fields (tags, labels, custom expiry hints) that vary across consumers. The strict UpdateVaultItemBodySchema mode does NOT recurse into metadata — strict only blocks unknown top-level keys.
  • createdAt/updatedAt are ISO-8601 strings, not numbers. SurrealDB serialises datetime as ISO strings; the wire matches the persistence layer.
  • body is intentionally string-typed, not byte-typed. Clients base64-encode binary payloads before sending. This keeps the wire JSON-safe and consistent across HTTP/2, HTTP/3, and SSE transports without forcing a multipart envelope.