Files
suaveplan/openspec/archive/2026-05-18-add-api-plugin-vault/tasks.md
2026-05-27 23:29:53 +01:00

3.8 KiB

Tasks — add-api-plugin-vault

1. Scaffold

  • 1.1 Create packages/api/api-plugin-vault/ with src/{plugin,routes,services,schemas,schema,error-codes,otel,types}/ + tests/{setup,integration}/
  • 1.2 package.json v0.1.0. Deps: @suaveplan/api-plugin @suaveplan/api-openapi @suaveplan/api-migrations @suaveplan/api-plugin-auth @suaveplan/vault @suaveplan/error @suaveplan/types tslib, hono @hono/zod-openapi (catalog:server), zod (catalog:forms), @opentelemetry/api
  • 1.3 10 subpath exports per the proposal
  • 1.4 tsconfigs + vite + vitest (100/100/100/100, testTimeout 60000 for integration)
  • 1.5 tests/setup/polyfills.ts

2. Implementation

  • 2.1 src/error-codes.{ts,test.ts,md,index.ts} — 9 VAULT_PLUGIN.* codes + VaultPluginError
  • 2.2 src/types/types.{ts,md,index.ts} — VaultPluginOptions, VaultPluginConfig, VaultHandle (opaque), VaultItem, VaultItemSummary
  • 2.3 src/schemas/options.{ts,test.ts,md,index.ts} — VaultPluginOptionsSchema
  • 2.4 src/schemas/vault-item.{ts,test.ts,md,index.ts} — 6 schemas (item / summary / response / list response / create body / update body strict-mode)
  • 2.5 src/otel/instruments.{ts,test.ts,md,index.ts} — 4 counters + 1 histogram
  • 2.6 src/schema/schema.{ts,test.ts,md,index.ts} — VAULT_OWNERSHIP_SCHEMA (two tables + indexes) + applyVaultSchema(adapter) helper
  • 2.7 src/services/vault-service.{ts,test.ts,md,index.ts} — VaultService interface + impl wrapping @suaveplan/vault; ServiceRegistry augmentation
  • 2.8 src/plugin/unlock.{ts,test.ts,md,index.ts} — headerExtractor("X-Vault-Unlock") default + extractUnlock(c, options) helper; no logging guard
  • 2.9 src/routes/build-routes.{ts,test.ts,md,index.ts} — buildVaultRoutes(vaultService, authService) returning 5 PluginRouteEntry via RouteBuilder; every route uses requireAuth() upstream
  • 2.10 src/plugin/plugin.{ts,test.ts,md,index.ts} — createVaultPlugin(options) factory; dependencies: ["auth"]
  • 2.11 src/index.ts — named re-exports only

3. Tests

  • 3.1 Co-located *.test.ts per spec scenario
  • 3.2 src/api-plugin-vault.spec-conformance.test.ts — every VAULT_PLUGIN.* code thrown; expectTypeOf on VaultService, VaultHandle is opaque
  • 3.3 tests/integration/full-boot.test.ts — real PluginRegistry + auth + this plugin + real @suaveplan/vault with in-memory DriveLike + SurrealDB testcontainer; sign-up → vault CRUD roundtrip
  • 3.4 tests/integration/openapi-doc.test.ts — served /openapi.json includes 5 vault routes
  • 3.5 tests/integration/cross-user-isolation.test.ts — user A cannot see / modify / delete user B's items (404 not 403)
  • 3.6 tests/property.test.ts — fast-check 200 runs on CreateVaultItemBodySchema (size invariant: payloads over maxItemSizeBytes always rejected)
  • 3.7 tests/dep-graph.test.ts
  • 3.8 All tests via @suaveplan/testing/runner, { timeout: 5000 } (60000 for integration)

4. Documentation

  • 4.1 Sibling .md per impl (≥200 words)
  • 4.2 README.md — install + defineApp().use(authPlugin).use(vaultPlugin({ storage })) example; X-Vault-Unlock header semantics + alternatives (jwt-bound, derived from password etc); cross-user isolation security note (404 not 403); schema apply notes

5. Gates

  • 5.1 bunx turbo lint typecheck test --filter=@suaveplan/api-plugin-vault --force
  • 5.2 Coverage 100/100/100/100
  • 5.3 bun scripts/openspec-conformance.ts @suaveplan/api-plugin-vault exit 0
  • 5.4 Build green
  • 5.5 Banned-pattern + no export * + no direct runner imports

6. Archive

  • 6.1 Fold spec → openspec/specs/api-plugin-vault/spec.md
  • 6.2 mv change → openspec/archive/<date>-add-api-plugin-vault/
  • 6.3 DO NOT refresh MANIFEST or STATUS — orchestrator consolidates