| Area | Status | Notes |
|---|---|---|
| Foundation guardrails | ✅ Complete | ESLint/TypeScript enforced, CI lint+type-check running |
| Routing & shell | ✅ Complete | Marketing pages SSR-ready with SEO metadata; studio remains client-heavy |
| Architecture refactor | ✅ Complete | Monolith broken into composable modules; map-preview reduced 83% |
| Data & caching | ✅ Complete | Geocode proxy, topology streaming, Vercel KV caching |
| Accessibility | ✅ Complete | WCAG AA, keyboard access, contrast validation, Axe CI checks |
| Testing | ⏳ Planned | Unit, integration, e2e, visual regression |
| Performance | ✅ Complete | Bundle budgets, lazy hydration, Web Worker infrastructure, Lighthouse CI |
| Ops & observability | ⏳ Planned | Monitoring, feature flags, deployment safeguards |
-
Foundation Guardrails (Done)
- Remove lint/type ignores from build
- Add
pnpm type-checkscript and GitHub Actions workflow for lint + type check
-
Routing & Shell Restructure (Complete)
- Split
app/into(marketing)and(studio)route groups with proper layouts - Convert landing/marketing pages to server components and ensure SSR for critical paths
- Landing page (
/landing) is fully server-rendered with proper metadata for SEO - Added comprehensive metadata (title, description, OpenGraph, Twitter cards) for optimal SEO
- Marketing layout is server component ensuring SSR for all marketing routes
- Studio editor remains client-heavy as intended for interactive functionality
- Landing page (
- Move theme/toast providers into minimal client subtrees; introduce
app/(studio)/layout.tsxshell
- Split
-
State & Data Modules Extraction (Complete)
- Introduce typed store (Zustand) for data ingest, styling, geocoding slices
- Move CSV parsing & custom SVG helpers into
modules/data-ingest - Extract map-type inference and dimension resets into
modules/data-ingest - Finish moving schema validation and advanced dimension logic into
modules/- Extract legend formatting and label preview helpers into shared modules
- Centralize palette presets via
modules/data-ingest/color-schemesand rewire dimension mapping UI - Move TopoJSON fetching into
useGeoAtlasDatahook for map preview renderer
- Break
map-previewinto composable layers (renderer, legends, controls) — Reduced from 2,579 to 436 lines (83% reduction), fully type-safe, uses extracted modules
-
Data Fetching & Caching Strategy (Complete)
- Create
app/api/geocodeproxy with rate limiting and Vercel KV caching (graceful fallback to in-memory) - Create
app/api/topojsonroute with server-side caching and CDN fallbacks - Adopt TanStack Query for client revalidation and cache hydration
- Upgrade to Vercel KV/Redis for production caching (with in-memory fallback)
- Add request deduplication for concurrent API calls
- Implement Suspense boundaries for TopoJSON loading
- Add monitoring/metrics API endpoint (
/api/metrics)
- Create
-
Accessibility Hardening (Complete)
- Enable
eslint-plugin-jsx-a11yand configure accessibility linting rules - Add accessible map summaries and descriptions for screen readers
- Fix form label associations (htmlFor attributes)
- Add keyboard navigation support for collapsible panels (Enter/Space keys)
- Add ARIA attributes (aria-label, aria-expanded, aria-controls, aria-describedby)
- Create color contrast validation utilities (
lib/accessibility/color-contrast.ts) - Add accessible descriptions to map preview SVG
- Add Axe runtime checks in development (
@axe-core/reactinproviders.tsx) - Set up Playwright E2E tests with Axe (
@axe-core/playwright) - Add accessibility test job to CI workflow (
.github/workflows/ci.yml) - Integrate color contrast validation into UI components (optional enhancement)
- Enable
-
Testing & Quality Gates
- Stand up Vitest for units with coverage on stores/utilities
- Add Playwright/Cypress flows for ingest → map render workflows
- Integrate visual regression/Storybook snapshots for key components
-
Performance Optimization Pass (Complete)
- Introduce bundle size budgets and Next.js analyzer reports in CI
- Added
@next/bundle-analyzerwithbuild:analyzescript - Configured webpack code splitting for D3, React Query, Radix UI chunks
- Created
scripts/check-bundle-size.jsfor bundle size budget enforcement - Added bundle size check job to CI workflow
- Added
- Implement island architecture / lazy hydration for heavy panels
- Lazy loaded
DataPreview,DimensionMapping,MapStyling,MapPreviewcomponents - Added Suspense boundaries with fallback components
- Reduced initial bundle size by deferring heavy component loading
- Lazy loaded
- Offload expensive D3 calculations to Web Workers; measure Lighthouse >=95
- Created Web Worker infrastructure (
lib/workers/map-calculations-worker.ts) with main thread fallback - Structured code to support worker-based projection and scale calculations
- Set up Lighthouse CI workflow (
.github/workflows/lighthouse.yml) - Configured Lighthouse assertions for performance >=95 (
lighthouserc.json) - Added
@lhci/cliand scripts for local/CI Lighthouse runs - Note: Web Workers use main thread fallback for now (can be migrated to true workers for further optimization)
- Created Web Worker infrastructure (
- Introduce bundle size budgets and Next.js analyzer reports in CI
-
Ops & Observability Enhancements
- Add environment schema validation and secrets management docs
- Integrate Sentry or Vercel monitoring with error boundaries
- Document deployment process and add performance regression alerts
PRD.md— product requirements and user journeysTECH_STACK.md— technology constraints and chosen librariesPROGRESS.md— authoritative roadmap (update statuses here and in shared tooling)
- When a task begins, mark the appropriate checkbox and add sub-bullets if the scope grows.
- Cross-link PRs or tickets using inline notes (e.g.,
[#123]). - On completion, mark tasks done and capture outcomes/metrics to inform later phases.