8.8 KiB
TL;DR: Below is a higher-level, technical “how we’ll do it” roadmap for Phases 0–10. It explains approaches, contracts, guardrails, and sequencing—no filenames or concrete code yet.
Q-Blog → 1.0.0: Technical Roadmap (Conceptual “How”)
Phase 0 — Orientation & Quality Bar
How:
- Define protected user journeys and SLIs/SLOs (e.g., time-to-interactive, save success rate, keyboard reachability).
- Adopt a single “definition of done” template (accessibility, tests, docs, telemetry hook, error state).
- Establish a lightweight decision record format (context → options → decision → impact) for any cross-cutting choice.
Phase 1 — Project Docs & Working Agreements
How:
- Author concise, source-of-truth docs: a high-level architecture map (UI/state/data flows), a testing strategy pyramid, an accessibility standard, and contribution rules.
- Record initial decisions (editor stack, state mgmt, theming, data shape conventions).
- Add a changelog discipline (human-readable entries grouped by “Added/Changed/Fixed/Removed/Docs/Tests”).
- Define semantic labels for issues/PRs (type, area, effort) to enable predictable triage.
Phase 2 — Test Harness & Linting Baseline
How:
-
Testing layers:
- Unit & component: Vitest + JSDOM + React Testing Library; global test setup for matchers/mocks.
- Integration/smoke (later): small number of Playwright/Happy-path flows (create/edit/publish).
-
Coverage:
- Enforce thresholds at the package level; exclude generated/fixture code; surface a coverage report artifact.
-
Linting/formatting:
- ESLint (flat config) with TypeScript, React, and jsx-a11y; Prettier for formatting; consistent import ordering.
-
Fast feedback:
- Watch mode locally; pre-push hooks run lint + typecheck + tests (changed files).
-
CI scaffolding (conceptual):
- Separate jobs for install/cache, lint/typecheck, unit/component tests, and (later) e2e smoke; cache node modules; artifact uploads for coverage.
Phase 3 — Correctness Sweep
How:
-
Dependency hygiene:
- Align UI toolkit imports to current major; remove legacy namespaces; verify peer-dep ranges; lock versions for determinism.
-
Type safety:
- Replace broad
any/suppressed regions with minimal interfaces and discriminated unions where helpful. - Introduce a “strict mode budget”: upgrades gated by keeping type errors at zero.
- Replace broad
-
State/data flows:
- Standardize async lifecycles (
idle/loading/success/error) and empty states; unify error objects (message + code + recoverability).
- Standardize async lifecycles (
-
Image/media safety:
- Enforce text alternatives policy; handle failed loads with fallbacks; guard upload constraints (size/type).
-
Cross-browser sanity:
- Run a small matrix (Chromium/WebKit/Firefox) in CI for a smoke render test.
Phase 4 — Accessibility Baseline
How:
-
Semantics & landmarks:
- Use structural regions (header/nav/main/footer) and a skip-to-content anchor; ensure a single H1 per view.
-
Keyboard & focus:
- Trap focus in modals/popovers, restore focus on close, visible outlines; consistent Tab/Shift+Tab order; Esc closes transient UI.
-
Names/roles/states:
- Deterministic accessible names for controls; toggles use
pressedstate; forms have programmatic labels and error/help text wiring.
- Deterministic accessible names for controls; toggles use
-
Live updates & motion:
- Polite live region for async progress; respect
prefers-reduced-motion; avoid seizure risk (no flashing).
- Polite live region for async progress; respect
-
Testing:
- Automated axe checks in component tests for critical views; a short manual keyboard checklist per protected journey.
Phase 5 — UX & IA Touch-up
How:
-
Navigation model:
- Clarify primary vs. secondary navigation; ensure routes map cleanly to the data model (current blog scope).
-
Consistency system:
- Define tokens for spacing/typography/contrast; standardize button/empty/error patterns; unify iconography.
-
Editor ergonomics:
- Deterministic toolbar enable/disable; clear state for draft vs. published; undo/redo affordances; autosave with visible status.
-
Content lifecycle:
- Uniform toasts/banners for success/failure; retry affordances on transient failures; protective confirms on destructive actions.
Phase 6 — Data Model Extension: Multiple Blogs per Name
How:
-
Domain relationships:
- Name (account) 1..N Blog; Post 1..1 Blog; keep Post → Blog immutable after creation (prevents cross-blog drift).
-
Identifiers & URLs:
- Introduce stable blog handles (human-friendly, unique per name) that compose into routes; add collision policy and normalization rules.
-
State management:
- Represent “current blog” as first-class app state; selector scoping so lists/metrics derive from the active blog.
-
Migrations:
- Backfill: create a default blog per name and attach historical posts; record migration version on the data root to allow repeatable ops.
-
UX:
- Blog switcher in global nav; “create blog” guided flow with handle validation and preview; clearly scoped creation forms.
-
Indexing & constraints (backend/API expectations):
- Unique composite index (name, blog handle); foreign key from posts to blog id; server rejects cross-blog updates.
Phase 7 — Permissions Model: Shared Blogs
How:
-
Role model (lean start):
- Owner (full control), Editor (edit any post, manage drafts), Author (create/edit own posts), Viewer (public, implicit).
-
Invitations:
- Tokenized invite flow with expiration; acceptance binds a name to a role on a blog; owner can revoke.
-
Enforcement:
- All write endpoints check role → operation matrix; UI gates controls (disable/hide) but never trusts the client.
-
Attribution & activity:
- Store author id and updated-by on posts; optional lightweight activity log for edits/publishes; surface attribution in UI.
-
Conflicts:
- Last-writer-wins with ETag/if-match semantics or revision numbers; reject stale writes; small conflict UI with diff view (stretch goal).
Phase 8 — Performance & Resilience
How:
-
Rendering:
- Keep lists virtualized; hydrate only what’s visible; memoize high-churn components; defer non-critical work with idle callbacks.
-
Network:
- Structured fetch layer with timeouts, abort support, and retry/backoff on idempotent GETs; idempotency keys on create/update to prevent dupes.
-
Perceived speed:
- Optimistic UI where safe (e.g., draft saves); skeletons/spinners with progress semantics; prefetch likely next views.
-
Failure handling:
- Standard error surface (banner/toast + inline details); retry path; offline detection with queued drafts.
-
Metrics:
- Track Web Vitals and action latencies; set budgets (e.g., LCP, INP) and regressions fail CI perf checks (can be a nightly).
Phase 9 — Internationalization & Theming Consistency
How:
-
Strings:
- Centralize UI strings under a namespace scheme; ensure interpolation is safe; default English bundle with stubs for others.
-
Formatting:
- Use Intl APIs for dates/numbers/plurals; avoid manual formatting; prepare RTL-safe layouts (logical properties).
-
Themes:
- Single source for color/spacing/typography tokens; verify contrast programmatically; support
prefers-color-scheme.
- Single source for color/spacing/typography tokens; verify contrast programmatically; support
Phase 10 — Observability, Security & Release Readiness
How:
-
Observability:
- Error boundaries with user-friendly fallback views; structured client logs (level, code, context) routed to a collector; anonymized action breadcrumbs for repro.
-
Security posture:
- Input validation at boundaries; sanitize rich text; content-security-policy hardening; permission checks at every write; least-privilege tokens.
-
Migrations & backups:
- Versioned migrations with idempotent steps; pre-prod dry run; exportable backup of critical entities; rollback procedure.
-
Release discipline:
- SemVer tags; changelog; migration notes; upgrade guide; “go/no-go” checklist (tests green, a11y checks pass, metrics within budget).
Cross-cutting Technical Principles
- Contracts first: Define data and role contracts before wiring UI; document them in the repo and tests.
- Small vertical slices: Ship changes end-to-end (schema → API → state → UI → tests) in thin increments.
- One source of truth: Centralize constants (roles, statuses, limits) and import them everywhere.
- Guardrails by default: Lint/type/test/a11y checks run locally and in CI; merges require green gates.
- Telemetry with restraint: Collect only what’s necessary for quality; feature-flag any new collection.
Assumptions & Risks
- We control both client and API contracts (or can negotiate them).
- Current data fits a clean migration to per-name default blogs without manual reconciliation.
- Editor content can be sanitized without breaking required formatting.
- Minimal E2E is enough for confidence; we can expand later if flakiness appears.