Attribute Devii AI spend to its invoking action, fix quiz question-at-a-time review, DB API/isslop result routes, workspace docs, and drop redundant docstrings

- Route Devii-driven AI gateway cost to the action/tool that triggered
  it instead of a blanket "internal" bucket, so per-feature AI spend
  is attributable.
- Fix the quiz attempt review to show one previously-answered question
  at a time instead of all of them at once, and stop a quiz endpoint
  linked from the quiz flow from responding with raw JSON.
- Add DB API async query result route and AI Usage Analyzer annotated
  source/media routes, with traversal-safe uid/path handling and
  matching tests.
- Add Code Farm action audit logging (plant/harvest/buy-plot/upgrade/
  fertilize) and related admin workspace/services/trash/gateway route
  and doc touch-ups.
- Drop redundant docstrings from access_tokens.py per the no-comments
  convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VL9Xn57W5UR3HZbbuuzxdK
This commit is contained in:
2026-09-03 08:47:57 +02:00
co-authored by Claude Sonnet 5
parent 9d7b3db314
commit 57087536e5
76 changed files with 805 additions and 338 deletions
+28 -11
View File
@@ -2,7 +2,7 @@
retoor <retoor@molodetz.nl>
Every state-changing action in DevPlace records one append-only row through `devplacepy/services/audit/record.py` (`record` for a request-scoped actor, `record_system` for a background one). This file is the authoritative catalogue of the 331 event keys currently emitted, grouped by the category `services/audit/categories.py` `category_for` resolves them to.
Every state-changing action in DevPlace records one append-only row through `devplacepy/services/audit/record.py` (`record` for a request-scoped actor, `record_system` for a background one). This file is the authoritative catalogue of the 355 event keys currently emitted, grouped by the category `services/audit/categories.py` `category_for` resolves them to.
## Rules
@@ -25,19 +25,19 @@ Every state-changing action in DevPlace records one append-only row through `dev
| `auth` | 8 |
| `backup` | 2 |
| `cli` | 43 |
| `container` | 36 |
| `container` | 41 |
| `content` | 37 |
| `database` | 4 |
| `devii` | 18 |
| `email` | 6 |
| `engagement` | 23 |
| `game` | 6 |
| `engagement` | 28 |
| `game` | 19 |
| `ingress` | 1 |
| `message` | 2 |
| `moderation` | 12 |
| `news` | 9 |
| `notification` | 4 |
| `project` | 11 |
| `project` | 12 |
| `project_files` | 14 |
| `pubsub` | 1 |
| `push` | 2 |
@@ -48,7 +48,7 @@ Every state-changing action in DevPlace records one append-only row through `dev
| `telegram` | 5 |
| `tools` | 12 |
**Total: 331 keys.**
**Total: 355 keys.**
## Account and profile (`account`)
@@ -199,10 +199,14 @@ Every state-changing action in DevPlace records one append-only row through `dev
| `container.instance.create` | `routers/admin/containers.py`, `routers/projects/containers/instances.py` |
| `container.instance.delete` | `routers/admin/containers.py`, `routers/projects/containers/instances.py` |
| `container.instance.exec` | `routers/projects/containers/instances.py`, `services/devii/actions/dispatcher.py` |
| `container.instance.pause` | `routers/admin/containers.py`, `routers/projects/containers/instances.py`, `services/devii/actions/dispatcher.py` |
| `container.instance.restart` | `routers/admin/containers.py`, `routers/projects/containers/instances.py`, `services/devii/actions/dispatcher.py` |
| `container.instance.resume` | `routers/admin/containers.py`, `routers/projects/containers/instances.py`, `services/devii/actions/dispatcher.py` |
| `container.instance.shell.close` | `routers/projects/containers/instances.py` |
| `container.instance.shell.open` | `routers/projects/containers/instances.py` |
| `container.instance.start` | `docs_api/groups/admin.py` |
| `container.instance.start` | `routers/admin/containers.py`, `routers/projects/containers/instances.py`, `services/devii/actions/dispatcher.py` |
| `container.instance.status` | `services/containers/service.py` |
| `container.instance.stop` | `routers/admin/containers.py`, `routers/projects/containers/instances.py`, `services/devii/actions/dispatcher.py` |
| `container.instance.sync` | `routers/admin/containers.py`, `routers/projects/containers/instances.py` |
| `container.reconcile.action` | `services/containers/service.py` |
| `container.tunnel.cert.failure` | `services/containers/workspace_service.py` |
@@ -212,10 +216,10 @@ Every state-changing action in DevPlace records one append-only row through `dev
| `container.tunnel.failure` | `services/containers/workspace_service.py` |
| `container.tunnel.suspend` | `services/containers/workspace_service.py` |
| `container.workspace.create` | `routers/projects/containers/workspace.py` |
| `container.workspace.delete` | `routers/projects/containers/workspace.py` |
| `container.workspace.delete` | `routers/projects/containers/workspace.py`, `routers/admin/workspaces.py` |
| `container.workspace.editor.update` | `routers/projects/containers/workspace.py`, `routers/admin/workspaces.py` |
| `container.workspace.flag.dismiss` | `routers/admin/workspaces.py` |
| `container.workspace.flag.raise` | `services/containers/workspace_service.py` |
| `container.workspace.flag.raise` | `routers/admin/workspaces.py` |
| `container.workspace.flag.resolve` | `routers/admin/workspaces.py` |
| `container.workspace.idle.stop` | `services/containers/workspace_service.py` |
| `container.workspace.idle.warn` | `services/containers/workspace_service.py` |
@@ -224,10 +228,10 @@ Every state-changing action in DevPlace records one append-only row through `dev
| `container.workspace.quota.block` | `routers/projects/containers/workspace.py` |
| `container.workspace.quota.warn` | `services/containers/workspace_service.py` |
| `container.workspace.restore` | `routers/admin/workspaces.py` |
| `container.workspace.resume` | `routers/projects/containers/workspace.py` |
| `container.workspace.resume` | `routers/admin/workspaces.py` |
| `container.workspace.retention.warn` | `services/containers/workspace_service.py` |
| `container.workspace.settings.update` | `routers/admin/workspaces.py` |
| `container.workspace.stop` | `routers/projects/containers/workspace.py` |
| `container.workspace.stop` | `routers/projects/containers/workspace.py`, `routers/admin/workspaces.py` |
| `container.workspace.suspend` | `routers/admin/workspaces.py` |
| `container.workspace.unsuspend` | `routers/admin/workspaces.py` |
| `container.schedule.create` | `routers/projects/containers/schedules.py`, `services/devii/actions/dispatcher.py` |
@@ -355,12 +359,25 @@ Every state-changing action in DevPlace records one append-only row through `dev
| Event key | Recorded in |
|---|---|
| `game.ci.upgrade` | `routers/game/index.py` |
| `game.cosmetic.buy` | `routers/game/index.py` |
| `game.cosmetic.equip` | `routers/game/index.py` |
| `game.daily.claim` | `routers/game/index.py` |
| `game.defense.downgrade` | `routers/game/index.py` |
| `game.defense.upgrade` | `routers/game/index.py` |
| `game.fertilize` | `routers/game/index.py` |
| `game.grant.claim` | `routers/game/index.py` |
| `game.harvest` | `routers/game/index.py` |
| `game.infrastructure.buy` | `routers/game/index.py` |
| `game.legacy.upgrade` | `routers/game/index.py` |
| `game.mastery.upgrade` | `routers/game/index.py` |
| `game.perk.upgrade` | `routers/game/index.py` |
| `game.plant` | `routers/game/index.py` |
| `game.plot.buy` | `routers/game/index.py` |
| `game.prestige` | `routers/game/index.py` |
| `game.quest.claim` | `routers/game/index.py` |
| `game.steal` | `routers/game/farm.py` |
| `game.water` | `routers/game/farm.py` |
## Container ingress (`ingress`)