HUB-METADATA-BULK-OPS.md markdown
56 lines 5.4 KB
Raw
sha256:87f84653ce4706be8c65b0c4494ed6fb891213cca82db2b1824772cddc41a752 feat(auth): durable MCP OAuth refresh via shared strong sto… Agent minor 58 days ago

Hub metadata bulk operations (project slug)

This document records the product decision and API shape for bulk delete/rename driven by effective project slug (frontmatter project: and/or path under projects/<slug>/), as defined in SPEC.md. It complements HUB-API.md, which also documents the HTTP routes.

Implementation status: Self-hosted (Node Hub) — shipped on main (PR #63): lib/hub-bulk-metadata.mjs, Hub routes, tests, Settings UI. Hosted — the gateway implements the same two POST routes in hub/gateway/metadata-bulk-canister.mjs (orchestrates the canister: GET /notes, per-path DELETE / POST /notes, proposal discards). Motoko still has no dedicated routes for these ops; behavior matches self-hosted via shared effectiveProjectSlug in lib/vault.mjs. PR #65: web/hub/hub.js no longer short-circuits hosted users before POST /notes/delete-by-project or rename-project — production needs both a gateway build with bulk handlers and a static Hub deploy with that client. See PARITY-MATRIX-HOSTED.md.

Path prefix vs project slug

Mechanism Matches Use when
POST /api/v1/notes/delete-by-prefix Vault-relative note path string (same key as POST /notes) Notes live under a folder layout you want to remove (e.g. projects/acme/).
POST /api/v1/notes/delete-by-project Effective project (same as GET /notes?project=) Notes are tagged with a project in frontmatter or path inference, regardless of folder.

Hosted (ICP): There is no disk, but each note still has a stored path string; delete-by-prefix is implemented in Motoko and proxied from the gateway. delete-by-project and rename-project are not Motoko routes; the gateway runs them against the canister using existing list/delete/write/discard APIs (see hub/gateway/metadata-bulk-canister.mjs).

Product decision (hosted)

Chosen strategy: Gateway-assisted execution (implemented): the gateway handles the two POST paths before the catch-all canister proxy, lists notes with the same auth headers as the rest of the Hub (X-User-Id / X-Actor-Id / X-Vault-Id), matches effective project slug (frontmatter + projects/<slug>/ path inference), applies team scope when hosted-context provides it, then issues per-note canister calls. Optional later: Motoko-native bulk endpoints if instruction limits or payload size require it.

  • Self-hosted Node Hub: Implements delete-by-project and rename-project by scanning the vault (lib/hub-bulk-metadata.mjs via runListNotes + delete/write).
  • Hosted gateway: Same API contract and responses; web/hub/hub.js uses the same Settings controls for canister-backed vaults.
  • Alternative (not in-repo): Single Motoko upgrade that iterates stable storage and parses JSON frontmatter in-canister — higher complexity and cycle limits for large vaults.

API contract (explicit modes)

These are separate endpoints (not a single mode query parameter) so mis-invocation is obvious and logs stay clear.

POST /api/v1/notes/delete-by-project

  • Auth: JWT; role editor or admin (hosted: viewer denied; member treated as editor per gateway JWT/bridge role).
  • Body: { "project": "my-slug" } — slug normalized like list-notes (normalizeSlug).
  • Response: { "deleted": number, "paths": string[], "proposals_discarded": number }.
  • Errors: 400 if project missing/invalid after normalization.

POST /api/v1/notes/rename-project

  • Auth: JWT; role editor or admin (hosted: same as delete-by-project).
  • Body: { "from": "old-slug", "to": "new-slug" } — both required; normalized; from === to is a no-op (updated: 0).
  • Response: { "updated": number, "paths": string[] }.
  • Behavior: Updates YAML frontmatter project: only; does not rename path keys or move notes between folders. Operators who need path moves should use a separate path-prefix workflow or a dedicated migration tool.

Confirmations (Hub UI)

The Settings panel requires typing DELETE to confirm destructive deletes (path prefix and project slug) and RENAME for rename-project. API clients should implement their own confirmation UX; the server does not require a magic string in the JSON body.

Vault rename (different feature)

Renaming a vault id or adding a display label is orthogonal to project slug housekeeping. See VAULT-RENAME-SPEC.md.

File History 5 commits
sha256:87f84653ce4706be8c65b0c4494ed6fb891213cca82db2b1824772cddc41a752 feat(auth): durable MCP OAuth refresh via shared strong sto… Agent minor 58 days ago
sha256:873e30b7fafe601346295f8f4289f388f21d8f715f28584d5481899ba2b714fc Merge pull request #249 from aaronrene/muse-mirror Agent 74 days ago
sha256:d8c648b20a4d53b2673c5c082ee7edfa7b2fc9b11080832da1f38807b6bf940b fix(7C-L1b): route hosted delegation proposals through cani… Human minor 77 days ago
sha256:2827ba9e7632a4b141c50caf1e8f7d77abbc3515be20e7465f2bccb0ac4edf91 fix: repair endpoint now sets has_active_subscription when … Human minor 97 days ago