Workspaces Payload collection with the PAT as a write-only field: access.read () => false strips it from every access-controlled read path, and a field-level beforeChange hook encrypts on write with AES-256-GCM (scrypt key from VEECT_SECRET, random per-value salt + IV, v1 storage format) via node:crypto only. The real repository replaces the phase-1 stub with payload create/findByID; toDomain never maps the credential, and getDecryptedCredential(id) is the single server-side decrypt path for the runner handoff (story 07). Contract suite now covers create, write-only behaviour, and the decrypt path against both the mock and the Payload impl (stub runs the real collection hooks). Missing VEECT_SECRET fails production bind/boot with an actionable message; dev-seed boots without it. Env declared in turbo.json globalEnv + .env.example. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
17 lines
576 B
TypeScript
17 lines
576 B
TypeScript
import { describe, it, expect } from "vitest";
|
|
import config from "./payload.config";
|
|
|
|
describe("payloadConfig composition", () => {
|
|
it("registers all feature collections", async () => {
|
|
const resolved = await config;
|
|
const slugs = resolved.collections?.map((c) => c.slug) ?? [];
|
|
expect(slugs).toEqual(expect.arrayContaining(["users", "workspaces"]));
|
|
});
|
|
|
|
it("registers no feature globals (none remain)", async () => {
|
|
const resolved = await config;
|
|
const slugs = resolved.globals?.map((g) => g.slug) ?? [];
|
|
expect(slugs).toEqual([]);
|
|
});
|
|
});
|