feat(web): full layout overhaul — Linear design system
CI / typecheck + build (turbo) (push) Canceled after 0s

Complete UI/UX overhaul, not just style changes:

Layout:
- Dark-mode-first (near-black #08090a canvas, whiteOpacity borders)
- Sticky header with brand + nav + theme toggle
- Sticky sidebar (xl+) with hierarchical doc tree
- Main content in max-w-3xl centered column
- Inter font system (via @font-face + CSS vars)
- Font feature settings cv01/ss03 for Linear-geometric Inter

Components rewritten in Linear aesthetic:
- Homepage: editorial-style doc listing with tags, section headers
- Doc page: breadcrumb-style nav links, metadata bar (author/date/tags),
  clean prose, Related + History sections
- TOC: rehype-slug heading anchors + github-slugger matching
- Create/Edit: inline form with Linear-style inputs/buttons
- Login: centered card-style, brand-indigo CTA button
- Docs index: sectioned listing with tag previews
- Search: dark-themed search with result cards + snippets
- ThemeToggle: system-default + localStorage persistence

Typography:
- prose with custom Tailwind classes matching Linear's:
  headings #f7f8f8 font-light, body #d0d6e0,
  links #7170ff with hover #828fff,
  code blocks #191a1b bg with #23252a border

New deps: rehype-slug (heading anchors), github-slugger (TOC matching)
Files: layout.tsx (overhaul), page.tsx, create/, login/, docs/,
       [section]/[...slug]/page.tsx, Sidebar.tsx, ThemeToggle.tsx,
       TOC.tsx, DocForm.tsx, Markdown.tsx, Search page
This commit is contained in:
asepharyana
2026-08-20 16:57:30 +07:00
parent f8b525d10c
commit 167d95c5e8
13 changed files with 517 additions and 375 deletions
+55 -55
View File
@@ -1,67 +1,67 @@
# MCPedia Phase 11 — CRUD + Auth + UI/UX Improvement
# MCPedia Phase 11 — CRUD + Auth + Web UI
## STATUS: ✅ ALL DONE (committed f8b525d, CI+Deploy success)
## Plan (spec BEFORE implementation, per user rule)
### Scope: 4 areas
1. **CRUD**: Create/Read/Update/Delete documents from web UI + MCP
2. **Auth**: Session-based auth for web edits; API key auth for MCP writes
3. **UI/UX**: Polish doc page, edit forms, search UX, dark mode
4. **Agent integration**: MCP tools for CRUD with auth
2. **Authentication**: MCP/API writes (x-webhook-secret), Web CRUD (cookie-based ADMIN_PASSWORD)
3. **Web + Agent access**: Web forms + MCP write tools
4. **UI/UX**: Edit forms, TOC, dark mode
## Requirements:
1. **Source of truth is the filesystem** — each doc is a markdown file under `content/{section}/{slug}.md` with YAML frontmatter (parsed/striped by gray-matter).
2. **DB mirrors disk** — `documents` table has slug/title/section/body/status/tags/etc; `document_chunks` stores embeddings; `document_revisions` snapshots body+meta.
3. **Single indexing path** — `indexContentFile` in `@mcpedia/core` writes DB + revisions + chunks; CRUD ops call it (or its pieces) after writing the file.
4. **Auth** — MCP/API writes require `x-webhook-secret` matching `WEBHOOK_SECRET` (Phase 4 pattern). Web CRUD uses cookie-based auth (Phase 11 addition: `ADMIN_PASSWORD`).
5. **Slug rules** — `[a-z0-9][a-z0-9/_-]*`, no `//`, no path traversal (`..`). The slug in the URL is `<section>/<slug-parts>`.
6. **No breaking existing features** — read tools/routes unchanged; existing 32 tests still green.
7. **UI/UX** — edit button on doc pages (auth-gated), `?edit=1` inline form, `/create` page, login page, table of contents auto-generated from h2, dark mode toggle.
### Requirements:
1. Source of truth = filesystem (markdown files in content/{section}/{slug}.md)
2. DB mirrors disk (documents, document_chunks, document_revisions tables)
3. Single indexing path: indexContentFile in @mcpedia/core
4. Auth: MCP/API writes use WEBHOOK_SECRET; Web uses ADMIN_PASSWORD cookie
5. Slug rules: [a-z0-9][a-z0-9/_-]*, no //, no .. traversal
6. No breaking existing features (32 original tests still green)
7. UI/UX: edit button on doc pages, ?edit=1 inline form, /create page, login, TOC, dark mode
### Schema changes:
- Optional: `users` table if auth is user-based
- OR: simple `WEB_AUTH_TOKEN` env for admin access (simpler, fits single-author KB)
### Implementation
### Backend surface:
- **Web auth**: Cookie-based session OR single admin token in localStorage
- Simpler approach: `POST /api/auth/login` (checks `ADMIN_PASSWORD` env) → sets cookie
- Edit UI gated behind cookie check in server components
- **MCP auth**: `x-api-key` header for write tools (create/update/delete)
- Read tools (list, get, search) — public
- Write tools (create, update, delete, index_document, reindex_all, restore_revision) — require key
- `createMcpServer(authKey?)` threads the header, same pattern as `x-webhook-secret`
#### Backend
- `packages/parser`: added `stringifyFile()` (writes markdown with frontmatter)
- `packages/core`: `createDocument`, `updateDocument`, `deleteDocument` (file I/O + DB + revision + chunks)
- `apps/api`: tRPC CRUD routers (`requireWriteAuth`), fixed `requireWriteAuth` env-constant bug (now uses `ctx.expectedSecret` injected from `createApp(deps)`)
- `apps/mcp`: 3 new write tools (`create_document`, `update_document`, `delete_document`) gated by `x-webhook-secret`
### CRUD operations:
- **Create**: `POST /trpc/createDocument` (title, slug, section, body, tags)
- Writes markdown file to `content/{section}/{slug}.md`
- Triggers indexer (enqueues job or calls directly)
- **Update**: `POST /trpc/updateDocument` (slug, body, title, tags, status)
- Updates file + creates revision + reindexes
- **Delete**: `POST /trpc/deleteDocument` (slug)
- Removes file, DB rows, chunks; creates revision tombstone
- All mutations require auth (web cookie OR webhook secret OR MCP api-key)
#### Web UI
- `apps/web/app/api/auth/login/route.ts`: POST login → verify ADMIN_PASSWORD, set `mcpedia_admin` cookie
- `apps/web/app/api/docs/route.ts`: POST (create)
- `apps/web/app/api/docs/[...slug]/route.ts`: PUT (update), DELETE (delete)
- `apps/web/app/components/DocForm.tsx`: shared create/edit form
- `apps/web/app/create/page.tsx`: create form
- `apps/web/app/login/page.tsx`: login form
- `apps/web/app/[section]/[...slug]/page.tsx`: `?edit=1` inline edit, TOC, dark mode, Edit button
- `apps/web/app/docs/page.tsx`: docs index listing
- `apps/web/app/components/TOC.tsx`: auto-generated TOC from h2/h3 headings
- `apps/web/app/components/ThemeToggle.tsx`: dark mode toggle (localStorage + system default)
### UI improvements:
- Edit button on doc pages (auth-gated) → link to `/docs/{slug}/edit`
- Create page: `/docs/create` with form (section dropdown, slug, title, tags, markdown editor)
- Edit page: `/docs/{slug}/edit` pre-fills from getDocument
- Search page: live search results with keyboard nav, better empty states
- Doc page: table of contents (auto-generated from h2), dark mode toggle
#### New deps (minimal — only for UX):
- `rehype-slug` (heading anchors for TOC links)
- `github-slugger` (matching slug algorithm for TOC client-side)
### Verification steps:
1. TDD: write failing tests for each new API endpoint/method first
2. `bun run typecheck` — green
3. `bun run test` — 32 existing + new tests green
4. `bun run build` — green
5. CI + Deploy passes
6. Browser: create doc → search sees it → edit doc → changes reflect → delete doc → gone
7. MCP: create_document tool with key → doc appears; without key → unauthorized
### Gotchas (learned the hard way)
1. tRPC fetch adapter expects input directly as JSON body, NOT JSON-RPC envelope
2. requireWriteAuth compared `ctx.webhookSecret !== WEBHOOK_SECRET` (module-level env constant) — untestable. Fixed: `ctx.webhookSecret !== ctx.expectedSecret` (injected per-app via deps).
3. Next.js catch-all routes: `[...slug]/edit/` is INVALID (catch-all must be last). Used `?edit=1` query param instead.
4. Next.js App Router: PUT/DELETE on `/api/docs/route.ts` doesn't match `/api/docs/{slug}` — need dynamic route `/api/docs/[...slug]/route.ts`.
5. `@env.example` should be updated.
6. `ADMIN_PASSWORD` must be set in VPS `.env` (deployed separately).
### Acceptance criteria:
- [ ] createDocument tRPC + MCP
- [ ] updateDocument tRPC + MCP
- [ ] deleteDocument tRPC + MCP
- [ ] Web auth (cookie-based login)
- [ ] MCP write-tool auth (api-key)
- [ ] UI: edit/create pages
- [ ] UI: TOC + dark mode on doc pages
- [ ] All tests green, CI+Deploy passes
### Verification
- Typecheck: ✅ 4/4 apps green
- Tests: ✅ 40 tests green (32 original + 8 new), no DB/Redis
- Build: ✅ web compiled
- CI: ✅ success → Deploy: ✅ success
- Live: all 9 endpoints 200, 13 MCP tools live, CRUD e2e verified (login → create → view → delete via cookie auth), MCP create_document verified via header auth
- Test docs cleaned up (404 confirmed)
### Commits
1. `57f9001` feat: Phase 11 — CRUD + auth + web UI
2. `1dd16eb` feat(web): Phase 11 UI/UX — TOC, dark mode toggle, /docs index
3. `98437cb` fix(web): /api/docs accepts cookie OR header (not both required)
4. `8ed8c67` fix(web): split PUT/DELETE into /api/docs/[...slug]/route.ts
5. `f8b525d` chore: remove test docs