feat(api): add GET /content/schema/{post,collection,author} endpoints#180
feat(api): add GET /content/schema/{post,collection,author} endpoints#180bbornino wants to merge 2 commits into
Conversation
Exposes the sync worker's TypeBox frontmatter schemas directly so downstream consumers have a single source of truth for valid post, collection, and author frontmatter shape.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughThree new content schema routes are added for post, collection, and author frontmatter, all built through a shared route factory. The app registers the new routes, and each endpoint has a corresponding test. ChangesContent Schema Routes
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant createApp
participant createSchemaRoute
participant Fastify
participant Client
createApp->>Fastify: register schema route plugins
createSchemaRoute->>Fastify: define GET /content/schema/*
Client->>Fastify: GET request
Fastify-->>Client: 200 JSON schema response
Related PRs: None. Suggested labels: api, enhancement Suggested reviewers: None. Poem: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/api/src/routes/content/schema-post.ts (2)
5-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueStashing the real schema in
examplesis semantically off.
examplesis meant to hold sample response instances, not the schema definition itself. Consumers/tools generating OpenAPI docs or client SDKs fromexamplesmay render the schema object as if it were example data, which is confusing. If avoiding Fastify's response validation is the real goal, consider a dedicated OpenAPI vendor extension (e.g.x-schema) instead of repurposingexamples.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/routes/content/schema-post.ts` around lines 5 - 12, The SchemaPostResponseSchema definition is using examples to store the schema itself, which is the wrong semantic for response examples. Update the SchemaPostResponseSchema in schema-post.ts so the real schema is not placed in examples; instead, use a dedicated OpenAPI vendor extension like x-schema or another non-example metadata field while keeping the response shape and description intact.
5-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate this route-registration boilerplate across all three schema route files.
schema-post.ts,schema-collection.ts, andschema-author.tsare structurally identical apart from path, description, and schema reference. Consider extracting a small factory, e.g.createSchemaRoute(path, description, schema), to avoid triplicated logic and keep future changes (e.g., adjusting the response-schema workaround) in one place.♻️ Example factory approach
// apps/api/src/routes/content/createSchemaRoute.ts import type { FastifyPluginAsync } from "fastify"; import { Type, type TSchema } from "typebox"; export function createSchemaRoute( path: string, description: string, schema: TSchema, ): FastifyPluginAsync { const ResponseSchema = Type.Object( {}, { additionalProperties: true, description, examples: [schema] }, ); return async (fastify) => { fastify.get( path, { schema: { description, response: { description: "Successful", content: { "application/json": { schema: ResponseSchema } }, }, }, }, }, async (_request, reply) => { reply.code(200); reply.send(schema); }, ); }; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/routes/content/schema-post.ts` around lines 5 - 38, The three schema route files duplicate the same Fastify route-registration logic, so extract a shared factory like createSchemaRoute and use it from schema-post, schema-collection, and schema-author. Move the common fastify.get setup, response-schema workaround, and reply.send behavior into the factory, parameterized by path, description, and the schema reference (e.g. PostMetaSchema/CollectionMetaSchema/AuthorMetaSchema), so future changes only happen in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@apps/api/src/routes/content/schema-post.ts`:
- Around line 5-12: The SchemaPostResponseSchema definition is using examples to
store the schema itself, which is the wrong semantic for response examples.
Update the SchemaPostResponseSchema in schema-post.ts so the real schema is not
placed in examples; instead, use a dedicated OpenAPI vendor extension like
x-schema or another non-example metadata field while keeping the response shape
and description intact.
- Around line 5-38: The three schema route files duplicate the same Fastify
route-registration logic, so extract a shared factory like createSchemaRoute and
use it from schema-post, schema-collection, and schema-author. Move the common
fastify.get setup, response-schema workaround, and reply.send behavior into the
factory, parameterized by path, description, and the schema reference (e.g.
PostMetaSchema/CollectionMetaSchema/AuthorMetaSchema), so future changes only
happen in one place.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f2f16cea-4877-4b83-ad4b-7b4e7b52e628
📒 Files selected for processing (7)
apps/api/src/createApp.tsapps/api/src/routes/content/schema-author.test.tsapps/api/src/routes/content/schema-author.tsapps/api/src/routes/content/schema-collection.test.tsapps/api/src/routes/content/schema-collection.tsapps/api/src/routes/content/schema-post.test.tsapps/api/src/routes/content/schema-post.ts
Addresses CodeRabbit's suggestion on PR playfulprogramming#180 to de-duplicate the identical route/response-wrapper boilerplate across schema-post.ts, schema-collection.ts, and schema-author.ts.
Summary
GET /content/schema/post,GET /content/schema/collection,GET /content/schema/author— each returning the corresponding TypeBox frontmatter schema (PostMetaSchema,CollectionMetaSchema,AuthorMetaSchema) directly as the response body.schema-post.ts,schema-collection.ts,schema-author.ts), following the existingprofiles.tspattern and the project's one-route-per-file convention.createApp.tsalongside the existing content routes.These three schemas are exposed as-is with no transformation — downstream consumers should treat them as the source of truth for frontmatter shape, since they're the exact schemas the sync worker validates against.
Implementation note
Each route's
response[200]schema is a permissive object (additionalProperties: true) with the realMetaSchemaattached viaexamples, rather than using theMetaSchemaitself as the response schema. Using the frontmatter schema directly as the Fastify response schema causes a 500 (fast-json-stringifytreats it as the shape of post/collection/author data, not a JSON Schema document, and complains about missing required fields liketitle). The permissive-wrapper approach keeps runtime serialization working and still surfaces the real schema shape in the generated OpenAPI docs.Design question for James
These three route files import
PostMetaSchema/CollectionMetaSchema/AuthorMetaSchemadirectly fromapps/worker/src/tasks/*/types.tsvia a relative path, since that's where the schemas already live. This is the first cross-app import in the codebase — elsewhere, sharing goes throughpackages/*, with apps depending on packages rather than on each other directly. Flagging in case you'd rather these schemas move intopackages/common(or a new small package) as a follow-up; Docker builds both apps from the same checkout today, but that's not a guarantee this pattern should rely on long-term.Test plan
pnpm test:unitpasses (lint, knip, publint, sherif, vitest across all NX projects)pnpm prettier --check .passes on all changed files/openapi.jsonto confirm the response is documented sensibly (permissive schema + concrete example) rather than misleadingly requiring frontmatter fields on the response itselfSummary by CodeRabbit
New Features
/content/schema/*.Tests