fix(operation-trace): repair export URL, drop dead action, prune unused keys

- Export download failed because the URL builder appended the path to a
  "/" base, producing a protocol-relative "//api/..." URL that the browser
  read as host "api"; the request never reached the backend. Resolve the
  base to the current origin, mirroring the other URL builders.
- Remove the orphan ``clear_prune`` action: the branch has no prune/clear
  route and no route rule maps to it, so it could never be produced. Its
  i18n key is removed too.
- Remove ``tamperedCount``, now unreferenced after the verification badge
  was split into integrity/chain counters. The operationTrace catalogue is
  now free of unproduced keys.
- Correct the settings controller docstring: only governance, operation
  logs, filters and export routes exist; there is no on-demand delete.

Verified: no producer for clear_prune, classify() can no longer emit it,
operationTrace orphan scan returns none, tsc/check-i18n/prettier/py_compile
all pass.
This commit is contained in:
TyperBody
2026-09-26 02:43:48 +08:00
parent cf28b5694d
commit abca2e7bff
11 changed files with 18 additions and 30 deletions
@@ -2,12 +2,15 @@
Exposes the "成员操作日志溯源" (member operation traceability) surface:
* ``GET /api/v1/settings/governance`` read level + template table
* ``PUT /api/v1/settings/governance`` change level / retention
* ``GET /api/v1/settings/operation-logs`` page through records
* ``GET /api/v1/settings/operation-logs/filters`` available filter values
* ``POST /api/v1/settings/operation-logs/prune`` enforce retention now
* ``DEL /api/v1/settings/operation-logs`` clear records
* ``GET /api/v1/settings/governance`` read level + template table
* ``PUT /api/v1/settings/governance`` change level / retention
* ``GET /api/v1/settings/operation-logs`` page through records
* ``GET /api/v1/settings/operation-logs/filters`` available filter values
* ``GET /api/v1/settings/operation-logs/export`` download the filtered CSV
Operation records are append-only and there is no route to delete them on
demand: retention is the only deletion path, and it runs automatically when
the governance settings change and from the maintenance loop.
Every route requires ``audit.view``, which is granted to the Workspace owner
and admin only. Write routes additionally require an owning/admin role so a
@@ -212,12 +212,6 @@ ACTION_RULE_TABLE: typing.Final[tuple[ActionRule, ...]] = (
bucket='audit',
resource_type='operation_log',
),
ActionRule(
action='clear_prune',
category='audit',
bucket='write',
resource_type='operation_log',
),
ActionRule(
action='settings_update',
category='settings',