first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
# 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
```ts
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
```ts
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.