ZDDC/zddc/internal/handler
ZDDC 050902fa9e chore: elevation slot in every tool + docs + helper file splits + smell cleanup
Polish pass after the big refactor in 2d114fc.

== Header elevation slot propagated ==

shared/elevation.{js,css} surface a header checkbox for admins.
30-minute sudo-style cookie window (Max-Age=1800, SameSite=Lax).
Only renders when /.profile/access reports can_elevate=true; quiet
for non-admins. Slot added to all 7 tool templates and concat'd
into all 7 build.sh files; admin in any tool now sees the toggle.

Three text-rename ride-alongs in archive/classifier/transmittal
templates: "Add Local Directory" → "Use Local Directory" (the same
rename that landed in browse earlier in this branch).

== Docs ==

- CLAUDE.md gets an "Admin elevation is sudo-style" paragraph in
  the "Things that bite if you forget" section.
- AGENTS.md gets a dedicated "Admin elevation (sudo-style)" section
  alongside "Bearer tokens" — same depth as the existing auth docs.

== Helper file splits ==

The retired form editor's shared helpers got bundled into a single
zddc_admin.go in the cleanup; that name is now misleading. Split by
concern:

- admin_helpers.go: hasAnyAdminScope (the only admin-specific helper)
- paths.go: resolvePath, urlPathOf, chainDirs (URL ↔ filesystem path
  math — used by several profile / zddc-file handlers)
- profile_assets.go (renamed from zddc_admin_assets.go): custom CSS
  pipeline. URL renamed from /.profile/zddc/assets/ → /.profile/assets/
  since /.profile/zddc/ no longer hosts an editor.
- treeEntry moves to profilehandler.go (alongside AccessView, its
  only consumer).
- writeError moves to profileprojects.go (its only consumer).

== Smell cleanup ==

- zddc.HasAnyAdminGrant(fsRoot, email) — new elevation-independent
  primitive that walks the cascade and reports whether email is named
  in any admin: list anywhere. Replaces the synthetic-elevated probe
  hack in enumerateAccess (`Principal{Email, Elevated: true}` was
  "lying" to the elevation gate to ask what it would say). The handler's
  hasAnyAdminScope collapses to a 4-line wrapper that gates on
  p.Elevated and delegates.
- Access-log middleware records `elevated` per request, so forensics
  can distinguish "admin acting as user" from "admin exercising power."
- browse/js/app.js's ?file= deep link walks multi-segment paths. Each
  intermediate segment is matched + expanded; the leaf gets
  selected/previewed. Auto-shows hidden when any segment starts with
  . or _. Silently no-ops on unresolved segments.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:15:41 -05:00
..
admin_helpers.go chore: elevation slot in every tool + docs + helper file splits + smell cleanup 2026-05-14 12:15:41 -05:00
archivehandler.go refactor(zddc-server): demote routing-shape redirects from 301 to 302 2026-05-10 14:37:02 -05:00
archivehandler_test.go feat(archive): canonicalize deep .archive URLs + permissions follow the file 2026-05-07 06:28:07 -05:00
authcheck.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
authcheck_test.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
converthandler.go feat(zddc): MD→{docx,html,pdf} server-side conversion via stock pandoc + chromium containers 2026-05-13 10:33:56 -05:00
cors.go feat(server): authenticated CRUD + verb-based RBAC with WORM archive folders 2026-05-05 15:58:04 -05:00
cors_test.go feat(zddc-server): admin debug page + X-Auth-Request-Email default + hidden-segment guard 2026-04-28 14:02:06 -05:00
default-mdl.form.yaml feat(mdl): default columns mirror tracking-number components + customizable 2026-05-09 11:09:31 -05:00
default-mdl.table.yaml feat(mdl): default columns mirror tracking-number components + customizable 2026-05-09 11:09:31 -05:00
directory.go feat(browse): "Show hidden" toggle — list .-prefixed and _-prefixed entries 2026-05-13 14:45:41 -05:00
directory_test.go fix(zddc-server): mdl slash form serves browse; .zddc viewable at every depth 2026-05-11 12:45:16 -05:00
fileapi.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
fileapi_test.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
formhandler.go refactor(tables): in-dir convention + unified table+form HTML bundle 2026-05-09 09:15:26 -05:00
formhandler_test.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
logring.go feat(zddc-server): user profile page replaces /.admin/ 2026-04-29 16:32:02 -05:00
logring_test.go feat(zddc-server): admin debug page + X-Auth-Request-Email default + hidden-segment guard 2026-04-28 14:02:06 -05:00
middleware.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
middleware_test.go feat(server): self-issued bearer tokens + --no-auth flag 2026-05-08 07:40:28 -05:00
paths.go chore: elevation slot in every tool + docs + helper file splits + smell cleanup 2026-05-14 12:15:41 -05:00
profile_assets.go chore: elevation slot in every tool + docs + helper file splits + smell cleanup 2026-05-14 12:15:41 -05:00
profilehandler.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
profilehandler_test.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
profilepage.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
profileprojects.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
projecthandler.go refactor(zddc-server): demote routing-shape redirects from 301 to 302 2026-05-10 14:37:02 -05:00
projecthandler_test.go refactor(landing): project landing is now a single-file SPA, not server-rendered 2026-05-10 07:57:30 -05:00
projectshandler.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
reviewinghandler.go chore: retire mdedit tool — markdown editor lives in browse now 2026-05-13 10:34:31 -05:00
reviewinghandler_test.go Round of UX fixes: tool strip removed, MDL routing, browse markdown layout, reviewing depth-2 2026-05-11 12:30:34 -05:00
singleflight.go feat(zddc): MD→{docx,html,pdf} server-side conversion via stock pandoc + chromium containers 2026-05-13 10:33:56 -05:00
static.go Initial commit 2026-04-27 11:05:47 -05:00
subtreezip.go feat(zddc): GET /dir/?zip=1 — stream an ACL-filtered .zip of a subtree 2026-05-12 12:59:17 -05:00
subtreezip_test.go feat(zddc): GET /dir/?zip=1 — stream an ACL-filtered .zip of a subtree 2026-05-12 12:59:17 -05:00
tablehandler.go chore(zddc): remove dead canonical-folder predicates 2026-05-11 16:01:43 -05:00
tablehandler_test.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
tables.html refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
tokenhandler.go feat(server): self-issued bearer tokens + --no-auth flag 2026-05-08 07:40:28 -05:00
tokenhandler_test.go feat(server): self-issued bearer tokens + --no-auth flag 2026-05-08 07:40:28 -05:00
zddcfile.go refactor: unified listing protocol + form-editor retirement + admin elevation 2026-05-14 12:15:07 -05:00
zddcfile_test.go fix(zddc-server): mdl slash form serves browse; .zddc viewable at every depth 2026-05-11 12:45:16 -05:00
ziphandler.go feat(zddc): serve a .zip as a virtual directory (zipfs + dispatch intercept) 2026-05-12 12:17:47 -05:00
ziphandler_test.go feat(zddc): serve a .zip as a virtual directory (zipfs + dispatch intercept) 2026-05-12 12:17:47 -05:00