ZDDC/zddc/internal/apps
ZDDC 45005d164e feat(zddc-server): reviewing/ virtual aggregator + mdedit at the URL
Implements the reviewing/ aggregator described in the saved
project memory (~/.claude/projects/-home-user-src-zddc/memory/
project_reviewing_folder_design.md). reviewing/ stays in
VirtualOnlyCanonicalNames — never materialised on disk — and is
served as a join over archive/<party>/received/, archive/<party>/
issued/, and staging/, recomputed on every read.

Two depths, both trailing-slash:

  GET <project>/reviewing/?json=1
    → array of virtual <tracking>/ entries, one per submittal in
      archive/<party>/received/ that doesn't yet have a matching
      archive/<party>/issued/ entry. Sorted by tracking. URLs stay
      under reviewing/ so the user can drill into the per-submittal
      view. ACL: per-party, filtered like fs.ListDirectory.

  GET <project>/reviewing/<tracking>/?json=1
    → array of two virtual entries, received/ + staged/, with
      canonical URLs pointing back to archive/<party>/received/...
      and staging/... respectively. staged/ is omitted when no
      response draft exists yet.

When the response moves staging/ → archive/<party>/issued/, the
entry vanishes from depth-0 on the next listing. No mutation of
the reviewing/ subtree itself; pure join, recomputed on read.

Front-end at <project>/reviewing[/<tracking>/] is mdedit (per
user request). DefaultAppAt + AppAvailableAt extended to recognise
"reviewing" as a canonical mdedit-bearing folder. The polyfill in
shared/zddc-source.js is updated to follow listing entries' explicit
url field when present (absolute or root-relative) — that's how
mdedit's tree follows the depth-1 received/ + staged/ links into
the canonical archive/staging subtrees.

Dispatcher routing in zddc-server/main.go:
  - GET <project>/reviewing/[<tracking>/] with Accept: json
    → ServeReviewing
  - GET <project>/reviewing/[<tracking>/] with Accept: html
    → mdedit (rooted at the virtual path; polyfill fetches the
      JSON listing on its own)
  - GET <project>/reviewing (no slash) → mdedit (via DefaultAppAt)
  - GET <project>/reviewing/<tracking> (no slash) → 301 to slash form

Tests:
  - handler/reviewinghandler_test.go (6 cases): IsReviewingPath
    classification + ServeReviewing depth-0/depth-1 with and without
    staged drafts + 404 on unknown tracking + empty when archive/ is
    absent.
  - apps/availability_test.go updated: reviewing/ now expects mdedit
    rather than "" (no default).
  - cmd/zddc-server/main_test.go: TestDispatchEmptyCanonicalProjectFolders
    extended to assert reviewing → mdedit at the no-slash form;
    older "no-slash/reviewing → 301" test removed.

Future work (not in this commit): write translation. Editing a file
under reviewing/<tracking>/staged/<f>.md works today because the
polyfill rewrites to /<project>/staging/<response>/<f>.md before
fetching — the user's URL bar moves to the canonical path on click.
A virtual-filesystem mode where the URL bar stays under reviewing/
throughout would require server-side write rewriting (translate
PUT/DELETE on reviewing/.../staged/... into the canonical staging/
path). Not needed for the MVP — links in mdedit's tree work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 21:37:08 -05:00
..
embedded chore(embedded): cut v0.0.17-beta 2026-05-09 21:13:24 -05:00
apps.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
apps_test.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
availability.go feat(zddc-server): reviewing/ virtual aggregator + mdedit at the URL 2026-05-09 21:37:08 -05:00
availability_test.go feat(zddc-server): reviewing/ virtual aggregator + mdedit at the URL 2026-05-09 21:37:08 -05:00
cache.go fix(apps): cache key now includes scheme + full host:port (no collisions) 2026-05-04 17:57:28 -05:00
cache_test.go fix(apps): cache key now includes scheme + full host:port (no collisions) 2026-05-04 17:57:28 -05:00
embed.go perf(server): ETag + max-age=0 on embedded HTML responses 2026-05-04 07:49:17 -05:00
fetch.go feat(apps): code-signed URL fetches; dev chart overlays prod data RO 2026-05-04 21:59:07 -05:00
handler.go perf(server): ETag + max-age=0 on embedded HTML responses 2026-05-04 07:49:17 -05:00
handler_test.go feat(apps): code-signed URL fetches; dev chart overlays prod data RO 2026-05-04 21:59:07 -05:00
singleflight.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
singleflight_test.go feat(zddc-server): apps fetch+cache subsystem with cascade overrides 2026-05-01 15:25:25 -05:00
verify.go feat(apps): code-signed URL fetches; dev chart overlays prod data RO 2026-05-04 21:59:07 -05:00
verify_test.go feat(apps): code-signed URL fetches; dev chart overlays prod data RO 2026-05-04 21:59:07 -05:00
versions.go feat(zddc-server): CLI flags, --version, CWD-default ZDDC_ROOT 2026-05-01 15:43:31 -05:00