Developer Page Specifications
QC Checklist
Per-route gates. Date chip never collapses. Timezone fixed-clock regression. Status persistence drift = critical.
Complete
Per-route QC. Severity per §11.1.
Landing page
- MSC-LAND-001 · blocker · /en/calendar + /ar/calendar return 200.
- MSC-LAND-002 · blocker · This-week rail renders events with startDate within ±7 days. Empty state when 0 events.
- MSC-LAND-003 · blocker · Closing-soon rail renders events where computed status = closing-soon. Warning-tinted deadline chips.
- MSC-LAND-004 · critical · 16 country tiles render with correct live event counts.
- MSC-LAND-005 · critical · 17 category tiles render with correct counts.
- MSC-LAND-006 · major · Spotlight renders only when ≥1 event has editorialPriority=spotlight.
Listing pages (8 scope variants)
- MSC-LIST-001 · blocker · All 8 listing routes return 200 (events, countries/{x16}, categories/{x17}, audiences/{x9}, stages/{x7}, this-week, closing-soon).
- MSC-LIST-002 · blocker · Filter rail (country, category, audience, stage, status, mode) updates URL queryParams and re-fetches.
- MSC-LIST-003 · critical · Date chip on cards never collapses below 320px viewport. Card flips to horizontal layout on mobile.
- MSC-LIST-004 · critical · Status badge tints match computed status (upcoming, open, closing-soon, live, completed, postponed, cancelled).
- MSC-LIST-005 · blocker · Mobile / RTL parity.
Details page
- MSC-DTL-001 · blocker · /en/calendar/events/{slug} + AR return 200 for every IsActive event. Unknown slug → 404.
- MSC-DTL-002 · blocker · Status computation uses event.Timezone, NOT visitor clock. Fixed-clock regression confirms.
- MSC-DTL-003 · critical · Register/Apply CTA opens correct URL in new tab. Closing-soon upgrade ("Apply (closing soon)") when applicationDeadline within 7 days.
- MSC-DTL-004 · critical · Add-to-calendar generates valid .ics that imports into Google Calendar + Apple Calendar without warnings.
- MSC-DTL-005 · critical · Postponed / Cancelled banner renders correctly. Cancelled disables all CTAs.
- MSC-DTL-006 · critical · Cross-module sidebar renders 5 relation types (founders, startups, editorial, opportunities, files). Stale IDs stripped at render.
- MSC-DTL-007 · critical · Coverage section renders every CoverageArticle with parentEventId = this.id, sorted by publishedAt DESC.
- MSC-DTL-008 · blocker · JSON-LD validates against Google Rich Results Test for Event subtype matching Event.Category.
- MSC-DTL-009 · blocker · Mobile / RTL parity.
Submit flow
- MSC-SUB-001 · blocker · Form validates required fields + bilingual title + at least one outbound URL + endDate >= startDate.
- MSC-SUB-002 · critical · Submit POSTs to /api/calendar/events/submissions, returns 201, submitter receives confirmation email.
- MSC-SUB-003 · critical · Rate limit: 3/IP/day enforced. CAPTCHA after 2nd submission.
- MSC-SUB-004 · critical · Newly-submitted events default verificationStatus=pending and DO NOT appear on public listings until admin verifies.
Integration
- MSC-INT-001 · critical · Every CalendarEvent.RelatedXxxId resolves to an active row in the target module. Integrity sweep (§10.8) reports 0 broken.
- MSC-INT-002 · critical · Re-verification job auto-flags events older than 30d since lastVerified OR within 14d of startDate.
- MSC-INT-003 · critical · Status persistence job (nightly) re-computes Status for every IsActive event. Drift = critical defect.
- MSC-INT-004 · major · Sitemap.xml includes every IsActive event URL in both locales.
