# UOMysticmoon Website — Wiki Upgrade Spec > Branch: **`wiki-upgrade`**. This document is the contract for upgrading the CMS > wiki from a flat single-table page store into a feature-complete wiki. > It follows the project workflow: **design (this doc) → build in phases → verify**. > > Companion to [`BACKEND_DESIGN.md`](BACKEND_DESIGN.md); reuses its stack, auth, > logging, and Docker decisions unchanged. --- ## 1. Goal & scope Turn the wiki into something that behaves like a typical wiki, while staying inside the existing Node/Express + MariaDB + React/Vite architecture and the **staff-only** auth model (admin/editor — no new roles, no public contributions). **In scope** | Feature | Summary | |---|---| | Rich-text editing | TipTap (ProseMirror) WYSIWYG in the admin; outputs HTML | | Sanitization | Server-side allowlist on save **and** client-side on render (fixes today's stored-XSS gap) | | Categories / sections | First-class `wiki_categories` table; replaces hardcoded frontend blurbs | | Drafts & publish | `published` + `published_at`, mirroring the `posts` pattern | | Tags | Many-to-many tags with filtering | | Internal links | `[[slug]]`-style links authored in the editor; red-link detection | | Backlinks | "Linked from" list, maintained on save | | Inline images | Reuse/generalize the existing multer upload for in-body images | | Search | MariaDB `FULLTEXT` over title + body | | Revision history | Per-save snapshots with view / diff / restore | **Out of scope (this branch)** - Public/player editing or suggestion workflow, moderation/review queues. - New roles or per-page ACLs (all staff with a login can edit all pages). - Real-time collaborative editing, comments/discussion pages, file attachments other than images, page templates/transclusion, multilingual pages. **Decisions locked from planning** - Editor: **TipTap**, storing **HTML** (not Markdown, not JSON). - Search: **MariaDB FULLTEXT** (no new infrastructure). - Revision history and search are **included** (recommended additions beyond the minimum requested set). - Authoring is **admin + editor** (`isLoggedIn`); no anonymous edits. --- ## 2. Current state (baseline being replaced) | Layer | Today | File | |---|---|---| | Schema | flat `wiki_pages(slug,title,body,updated_by,timestamps)` | [server/db/schema.sql:31](server/db/schema.sql) | | Model | thin CRUD by slug | [server/src/model/wiki/wiki.db.js](server/src/model/wiki/wiki.db.js), [wiki.model.js](server/src/model/wiki/wiki.model.js) | | Public API | `GET /public/wiki`, `GET /public/wiki/:slug` | [public.controller.js:53](server/src/router/v1/public/public.controller.js) | | Admin API | `GET/POST/PUT/DELETE /admin/wiki[...]` | [admin.controller.js:163](server/src/router/v1/admin/admin.controller.js), [admin.routes.js:68](server/src/router/v1/admin/admin.routes.js) | | Public UI | card grid (hardcoded blurbs + Roman numerals), article w/ auto-TOC | [Wiki.jsx](client/src/routes/wiki/Wiki.jsx), [WikiArticle.jsx](client/src/routes/wiki/WikiArticle.jsx) | | Admin UI | raw-HTML `