Modules Documentation
Admin management
Admin pages, permissions, workflow.
Complete
Admin surfaces for Coverage live under the Founder Account dashboard (admin role) and follow a strict pipeline: queue → draft → fact-check → publish. The pipeline is gated at every step — no shortcut from draft to publish, no publish without the second-editor fact-check approval.
Coverage queue
- Auto-populated from CalendarEvents with coverageEligible=true + coverageStatus='planned'. Sorted by event startDate (most recent past events first, since coverage is post-event).
- Per row: parent event title + date + country + category + assigned editor (if any) + status (planned / drafting / fact-check / published).
- Action: "Create draft" opens the draft editor pre-populated with parent event metadata + an empty bodyHtml.
Draft editor
- Form mirrors the CoverageArticle interface — 15 fields. Bilingual fields show side-by-side EN | AR inputs.
- parentEventId picker: type-ahead search across CalendarEvents where coverageEligible=true. Selected event renders as a non-removable chip — every coverage article needs a parent.
- kind selector: 5-button toggle. Switching to sponsor-spotlight auto-inserts the disclosure ribbon into bodyHtml + prompts for sponsor identification.
- Rich-text editor for bodyHtml.en + .ar: WYSIWYG with the allowed-tag whitelist (h2-h4, p, ul/ol, blockquote, figure, a, em, strong, code). Output is sanitised HTML stored to bodyHtml.
- Mention pickers: type-ahead search across Founders / Startups / Opportunities / Files. Each selection renders as a removable chip with preview.
- Save action persists the draft (publishedAt remains null). readingTimeMinutes is auto-computed from bodyHtml.en word count on every save.
Fact-check + publish
- Drafter clicks "Submit for fact-check". Status flips to 'fact-check' and a second editor (anyone with admin role except the drafter) gets notified.
- Fact-checker walks through 3 gates with an explicit checklist (entity names verified / quantitative claims sourced / quotes confirmed). All 3 must be checked.
- On approve: publishedAt is set to now; status flips to 'published'; parentEvent.coverageStatus auto-flips to 'covered'; the article goes live + reverse-lookup rails on connected entities light up.
- On reject: status flips back to 'drafting' + a rejection note attaches to the draft. The drafter revises and resubmits.
