diff --git a/apps/web/app/api/docs/[...slug]/route.ts b/apps/web/app/api/docs/[...slug]/route.ts index daf0ecd..9410d2a 100644 --- a/apps/web/app/api/docs/[...slug]/route.ts +++ b/apps/web/app/api/docs/[...slug]/route.ts @@ -24,15 +24,15 @@ const STANDARD_FIELDS = new Set([ function splitPayload(body: Record): { standard: Record; - extraFields: Record; + extraFields: Record; } { const standard: Record = {}; - const extraFields: Record = {}; + const extraFields: Record = {}; for (const [key, value] of Object.entries(body)) { if (STANDARD_FIELDS.has(key)) { standard[key] = value; } else if (value !== undefined && value !== null) { - extraFields[key] = typeof value === "string" ? value : JSON.stringify(value); + extraFields[key] = value; } } return { standard, extraFields }; diff --git a/apps/web/app/api/docs/route.ts b/apps/web/app/api/docs/route.ts index 024d669..d30c08e 100644 --- a/apps/web/app/api/docs/route.ts +++ b/apps/web/app/api/docs/route.ts @@ -68,14 +68,7 @@ export async function POST(req: NextRequest) { try { const { standard, extraFields } = splitPayload(body); - // Coerce all extra field values to strings (form sends strings; API/MCP may send objects). - const stringExtra: Record = {}; - for (const [k, v] of Object.entries(extraFields)) { - if (v !== undefined && v !== null) { - stringExtra[k] = typeof v === "string" ? v : JSON.stringify(v); - } - } - const doc = await createDocument({ ...standard, extraFields: stringExtra } as any); + const doc = await createDocument({ ...standard, extraFields } as any); return NextResponse.json({ ok: true, slug: doc.slug, doc }); } catch (err) { const msg = err instanceof Error ? err.message : String(err); diff --git a/content/notes/test/dynamic-field-types.md b/content/notes/test/dynamic-field-types.md new file mode 100644 index 0000000..c9206fd --- /dev/null +++ b/content/notes/test/dynamic-field-types.md @@ -0,0 +1,19 @@ +--- +title: "Dynamic Field Types Test" +type: "note" +section: "notes" +status: "published" +author: "asep" +tags: ["test"] +path: "notes/test/dynamic-field-types.md" +created_at: "2026-08-20T17:45:07.294Z" +updated_at: "2026-08-20T17:45:07.294Z" +priority: "5" +resolved: "true" +os: "linux" +complexity: "medium" +tags_list: "[\"alpha\",\"beta\"]" +metadata: "{\"owner\":\"team-a\",\"tier\":2}" +--- +# Dynamic Field Types Test +Testing various field value types. \ No newline at end of file diff --git a/packages/core/src/document.service.ts b/packages/core/src/document.service.ts index 2f9622a..80fa245 100644 --- a/packages/core/src/document.service.ts +++ b/packages/core/src/document.service.ts @@ -128,7 +128,7 @@ export interface CreateDocInput { status?: DocStatus; author?: string; tags?: string[]; - extraFields?: Record; + extraFields?: Record; } export interface UpdateDocInput { @@ -138,7 +138,7 @@ export interface UpdateDocInput { status?: DocStatus; tags?: string[]; author?: string; - extraFields?: Record; + extraFields?: Record; } /** Validate that a slug is safe (no path traversal, only [a-z0-9/_-]). */ diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index a15349f..ff012f5 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -16,7 +16,8 @@ export interface DocumentMeta { updatedAt: string; // ISO // Dynamic custom frontmatter fields (e.g. CTF: event, challenge, category, // difficulty, points). Content creators add arbitrary key-value pairs. - extraFields?: Record; + // Values can be strings, numbers, booleans, arrays, or objects. + extraFields?: Record; } export interface Document extends DocumentMeta {