TFD-0022: Client Review Panel — Architecture Decisions

TFD-0022: Client Review Panel — Architecture Decisions

Status: Accepted Date: 2026-05-19 Decision maker: Oscar (CEO) · Facilitated by Philippe (Consulting Director) Scope: CON-0013

Context

JCT editorial deliverables (DAE, ITSA, blueprints) have no formal browser-side review cycle. Feedback comes via email, Word docs, or verbal walkthrough, then the producer re-edits manually. v1 introduces a reusable in-page comment panel; track-changes and accept-to-publish remain v2.

Pilot consumer: DAE-0007 (Transgesco). Six open architecture questions surfaced during the brainstorm. This TFD records the chosen path.

Decisions

  1. Storage backend — Cloudflare D1. SQL gives a clean schema (comments table keyed by page_id, anchor_id, email, body, ts, status) and supports the producer triage view without N+1 reads. Consistent with the EA catalog precedent (project_ea-catalog-architecture). One D1 database per client portal repo.

  2. Anchor stability — data-comment-anchor attributes at publish-time. The install skill walks each page's block-level elements (h1-h4, p, li, figure, .card, .grid item) and stamps a stable id (a-{slug}-{n}). The panel pins comments to these ids. Text-range fallback when the user selects a sub-string within an anchored element (offset + length stored alongside).

  3. Triage view — per-deliverable /_review/ page. Same site, CF Access protects it (admin email allowlist in the route). Lists open comments grouped by source page, with email + timestamp + anchor preview. No factory-wide cross-deliverable dashboard in v1.

  4. Install skill — JCT-namespaced (/jct:add-review-panel). v1 is JCT-only. Generalize to /deliverable:add-review-panel once a second consumer (intranet) needs it.

  5. CF Access identity — JWT pass-through, claim trust. Pages Function reads cf-access-jwt-assertion header and decodes the email claim. No signature verification in v1: Cloudflare already gates the request before it reaches the function. Sign-verify added in v2 when the panel handles edits, not just comments.

  6. On/off toggle. Panel reads window.__REVIEW_PANEL__ (set in a small review-config.js shipped per-deliverable). Set enabled: false to hide the panel without removing the assets. Allows fast disable during client demos.

Architecture summary

Editorial page (index.html, page1.html, ...)
  └─ <script src="/_review/panel.js" defer></script>
  └─ <link rel="stylesheet" href="/_review/panel.css">
  └─ data-comment-anchor="a-xxx-N" stamped on block elements

/_review/
  ├─ panel.js          (composer + voice + anchor pinning)
  ├─ panel.css         (warm cream + navy, Fraunces — matches editorial)
  ├─ index.html        (producer triage view)
  └─ config.js         (window.__REVIEW_PANEL__ = { enabled, apiBase })

functions/api/comments.ts   (Cloudflare Pages Function — POST/GET/PATCH)
schema.sql                  (D1 migration)
wrangler.toml               (D1 binding)

Out of scope (v2)

Track-changes inline diff, literal-edit & instruction-mode AI rewrites, client-side Accept/Reject → git auto-commit, audio file storage, comment threads/replies, cross-deliverable search.

Risk

Low — drop-in client-side bundle, no impact on existing publishing flow when disabled. D1 is single-tenant per client portal (no cross-client leakage). CF Access already enforces identity.

References

  • departments/consulting/requests/CON-0013-client-review-panel/request.md
  • departments/consulting/requests/CON-0013-client-review-panel/input/brainstorm-2026-05-19.md
  • TFD-0017 (JCT portal architecture)
  • Memory: project_jct-web-publishing, feedback_interactive-capsule-pattern