feat: revamp to dynamic database-first architecture and cleanup phase docs
CI / typecheck + build (turbo) (push) Canceled after 0s
CI / typecheck + build (turbo) (push) Canceled after 0s
- Migrate document fetching and CRUD to be PostgreSQL-authoritative - Remove static section enums and add dynamic listSections query - Support custom sections and metadata across API, MCP, and Web UI - Add /api/sections endpoint and update Header, Sidebar, and Forms - Remove obsolete phase planning docs and modernize README/AGENTS
This commit is contained in:
@@ -8,14 +8,6 @@ import type {
|
||||
DocumentMeta,
|
||||
} from "@mcpedia/types";
|
||||
|
||||
const SECTIONS: DocSection[] = ["docs", "writeups", "research", "notes"];
|
||||
|
||||
const VALID_TYPES: DocType[] = [
|
||||
"documentation",
|
||||
"writeup",
|
||||
"research",
|
||||
"note",
|
||||
];
|
||||
|
||||
// Standard frontmatter keys that are rendered explicitly in the UI template.
|
||||
// Any other key in frontmatter becomes a dynamic "extra field" badge.
|
||||
@@ -41,13 +33,16 @@ export function parseFile(absPath: string, relPath: string): ParsedFile {
|
||||
const raw = readFileSync(absPath, "utf8");
|
||||
const { data, content } = matter(raw);
|
||||
|
||||
const parts = relPath.split("/");
|
||||
const derivedSection = parts.length > 1 ? parts[0] : "docs";
|
||||
const section: DocSection =
|
||||
(SECTIONS.find((s) => relPath.startsWith(s + "/")) as DocSection | undefined) ??
|
||||
"docs";
|
||||
typeof data.section === "string" && data.section.trim() !== ""
|
||||
? data.section.trim()
|
||||
: derivedSection;
|
||||
|
||||
const slug = relPath.replace(/\.mdx?$/, "");
|
||||
|
||||
const type = (VALID_TYPES.includes(data.type) ? data.type : "documentation") as DocType;
|
||||
const type = (typeof data.type === "string" && data.type.trim() !== "" ? data.type.trim() : "documentation") as DocType;
|
||||
const status = (data.status === "draft" ? "draft" : "published") as DocStatus;
|
||||
|
||||
const tags: string[] = Array.isArray(data.tags)
|
||||
|
||||
@@ -57,13 +57,20 @@ test("parseFile: section derived from top-level dir", () => {
|
||||
expect(writeDoc("notes/baz.md", "---\ntitle: C\n---\nbody").meta.section).toBe("notes");
|
||||
});
|
||||
|
||||
test("parseFile: invalid type/status fall back to defaults", () => {
|
||||
const { meta } = writeDoc(
|
||||
test("parseFile: dynamic type and status with defaults", () => {
|
||||
const { meta: m1 } = writeDoc(
|
||||
"docs/x.md",
|
||||
"---\ntitle: X\ntype: bogus\nstatus: bogus\n---\n",
|
||||
"---\ntitle: X\ntype: custom-type\nstatus: draft\n---\n",
|
||||
);
|
||||
expect(meta.type).toBe("documentation");
|
||||
expect(meta.status).toBe("published");
|
||||
expect(m1.type).toBe("custom-type");
|
||||
expect(m1.status).toBe("draft");
|
||||
|
||||
const { meta: m2 } = writeDoc(
|
||||
"docs/y.md",
|
||||
"---\ntitle: Y\n---\n",
|
||||
);
|
||||
expect(m2.type).toBe("documentation");
|
||||
expect(m2.status).toBe("published");
|
||||
});
|
||||
|
||||
test("parseFile: missing optional fields get sane defaults", () => {
|
||||
|
||||
Reference in New Issue
Block a user