feat(api-docs): generate OpenAPI components/schemas from Go structs

A new emit_jsonschema.go walks the same allow-listed structs as the zod/types/examples emitters and writes generated/schemas.ts (SCHEMAS). build-openapi mounts it under components.schemas and points each typed response obj at a $ref instead of an untyped {} blob, so Swagger renders real models and openapi-generator can emit clients.

Also add a vitest guard that safeParses every EXAMPLES entry against its generated zod schema, reviving the previously unused generated/zod.ts and catching drift between the example and schema emitters.
This commit is contained in:
MHSanaei
2026-06-06 16:22:21 +02:00
parent e56f6c63f6
commit a014c01725
5 changed files with 2026 additions and 4 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,30 @@
import { describe, it, expect } from 'vitest';
import type { ZodType } from 'zod';
import { EXAMPLES } from '@/generated/examples';
import * as zodSchemas from '@/generated/zod';
const registry = zodSchemas as unknown as Record<string, ZodType>;
const names = Object.keys(EXAMPLES);
describe('generated response examples', () => {
it('has at least one example to validate', () => {
expect(names.length).toBeGreaterThan(0);
});
it('pairs every example with a generated zod schema', () => {
const missing = names.filter((name) => typeof registry[`${name}Schema`]?.safeParse !== 'function');
expect(missing).toEqual([]);
});
it.each(names)('EXAMPLES.%s satisfies its generated zod schema', (name) => {
const schema = registry[`${name}Schema`];
const result = schema.safeParse(EXAMPLES[name]);
if (!result.success) {
throw new Error(
`EXAMPLES.${name} does not match ${name}Schema:\n${JSON.stringify(result.error.issues, null, 2)}`,
);
}
expect(result.success).toBe(true);
});
});