Adds 开发工具 → 数据库管理台, which exchanges the admin bearer token for a
single-use entry link (POST /api/admin/v1/internal-surfaces/db-studio/session)
and opens it in a new tab. The link sets an HttpOnly session cookie on the
console's own hostname, so it has to be opened by the browser rather than
fetched — the nginx gate in front of the console then re-checks the permission
on every request.
The tab is opened synchronously inside the click handler, before the request
resolves, or the popup blocker kills it; `noopener` is unusable there since it
makes window.open return null, so the opener is detached manually.
Gated on auth:db-studio:access. That key is `auth:`-prefixed rather than
`admin:` on purpose — PermissionSeeder syncs the admin role to every `admin:%`
key, which would grant database-owner SQL access to every admin account.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- /roles — role table with create dialog and a permission-matrix sheet:
collapsible per-module sections (selected/total counts, role's own
modules start expanded) and a key/description filter that force-
expands matches; super-admin role is read-only
- /admin-users — user search (Enter to run) with role assignment
dialog; editing your own roles is blocked
Both nav items gate on auth:role:* keys, which only super-admin holds.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The store's can()/useCan() helpers existed but were unused. Now:
- src/auth/permissions.ts PERM catalog mirrors backend keys
- every nav item carries a permission; sidebar filter reuses can()
- requirePermission() beforeLoad guard on all child routes (direct URLs
redirect home when the session lacks the key)
- useCan() hides/disables mutation buttons: moderation actions,
retranslate, robot-author edit/pause, category + locale CRUD, and the
reserved-SID assign path (admin:sid:override hint)
- 403 responses toast 无权限执行此操作; can() unit tests added
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New Dimzou 内容 pages against the Dimzou admin API:
- /dimzou/documents — state filter (活跃/已归档/回收站), detail sheet
with versions, translations and pending review counts
- /dimzou/publications — visibility filter, detail from row data
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New nav group with four pages against the Exc admin API:
- /exc/demands — status/mode filters, detail sheet with related
services, quotes and dispatch rounds
- /exc/dispatches — status/round filters
- /exc/orders — status/payment filters, detail sheet with items and
状态流转 audit trail
- /exc/providers — status/verified filters, detail sheet with dispatch
settings and status logs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rework 内容审核 pages around reported resources instead of individual
reports, matching the new backend endpoints: rows group all reports on
one comment/event, with a slide-over listing report details and
per-row actions 通过并屏蔽 (approve) / 驳回举报 (reject) / 撤销屏蔽
(revert). Filters: 待处理 / 已屏蔽 / 全部.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New 内容审核 nav group covering the remaining admin API groups:
- /comment-reports — status filter; hide/delete comment or dismiss
- /event-reports — status filter; hide/delete/resolve/dismiss
- /dimzou-translations — language/status filters, draft block progress,
requeue machine translation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Robot-author edit form and detail drop positioning/target_readers (now
series-level); persona + styles stay (routed to the account profile via the
admin API). Series detail shows positioning/target_readers. Types updated;
admin API types regenerated.
Adds a 预览 action (enabled once an article has a Dimzou document) opening a
sheet that fetches and renders the draft — cover, title, summary, and body HTML
(typography/prose). Re-enables the @tailwindcss/typography plugin for prose.
Adds an "编辑" action opening a sheet form to edit a robot author's status,
persona, positioning, target readers, and the article/image/publishing style
objects (JSON-validated as objects). Saves via the existing admin PUT endpoint,
then refetches the enriched list.
- searchable CategoryPicker (Popover+Command) reusable across studio pages,
plus useCategoryOptions hook (shared tree query + id→name resolver)
- filter bar with category + status filters and a reset action
- new columns: account (avatar + display_name + uid), category name; persona
demoted to a secondary column; display_name/category surfaced in detail sheet