forked from Qortal/q-blog
268 lines
8.8 KiB
Markdown
268 lines
8.8 KiB
Markdown
**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.
|
||
|
||
- State/data flows:
|
||
|
||
- Standardize async lifecycles (`idle/loading/success/error`) and empty states; unify error objects (message + code + recoverability).
|
||
|
||
- 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 `pressed` state; forms have programmatic labels and error/help text wiring.
|
||
|
||
- Live updates & motion:
|
||
|
||
- Polite live region for async progress; respect `prefers-reduced-motion`; avoid seizure risk (no flashing).
|
||
|
||
- 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`.
|
||
|
||
---
|
||
|
||
## 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.
|