Configuration
Configuration keys
Every admin.* configuration key:
| Key | Type | Default | Description |
|---|---|---|---|
admin.enabled | bool | false | Whether the Accent Author admin shell is mounted at runtime. |
admin.token | Option<String> | None | Admin token required for /_admin/reload and the admin shell login flow. |
admin.brand_name | Option<String> | None | Optional brand name shown on the login card and top bar (falls back to “Accent Author” when unset). |
admin.brand_logo | Option<String> | None | Optional brand logo URL shown on the login card and top bar, resolved as a normal asset URL. |
admin.dev_assets_path | Option<PathBuf> | None | Optional override that makes the admin shell read templates and static assets from disk instead of the embedded binary snapshot. |
admin.audit_log_path | Option<PathBuf> | None | Optional override for the audit log path where successful page writes are appended as JSONL lines. |
admin.media | AdminMediaConfig | (defaults below) | Media upload settings: size limits, allowed types, and folder pattern. |
admin.media.max_upload_mb | u64 | 20 | Maximum file size in megabytes per uploaded file. |
admin.media.allowed_mime_prefixes | Vec<String> | ["image/", "application/pdf", "video/mp4", "audio/mpeg"] | MIME-type prefixes the upload endpoint accepts. |
admin.media.upload_folder_pattern | String | "uploads/{YYYY}-{MM}/" | Folder pattern for uploaded files relative to the content root, with UTC date replacement. |
The admin token may also be set via the ACCENT_ADMIN_TOKEN environment variable, which takes precedence over admin.token.
Audit log
Every successful mutation appends one line to an append-only JSONL audit log (one JSON object per line) with a stable field order: ts (RFC3339 UTC), actor, action, path, an optional fields array (the frontmatter fields that changed, omitted when empty), and optional from / to for workflow transitions.
- Location — when
admin.audit_log_pathis unset, the log defaults to<content_dir>/.admin/audit.log. When the key is set, its value is honored verbatim. The containing directory (.admin/) is created on demand, and the starter templates’.gitignoreexcludes.admin/from version control by default. - Actions — page edits record
update_page(with the changed-field names); workflow transitions recordworkflow_transition(withfrom/to); page operations recordcreate_page,move_page, anddelete_page; media operations recordmedia_upload,media_rename(with reference count and old/new URLs), andmedia_delete. - Best-effort writes — audit logging never breaks a save. The on-disk content write is committed first; if opening or writing the audit file fails, the system logs a warning and discards the audit line. A read-only audit volume cannot block the save path.
Conflict resolution
A conflict is detected when the __mtime recorded at the time the editor form was opened no longer matches the file’s current on-disk mtime — for example, because another author, a CLI tool, or a git pull changed the file in the meantime. When this happens the save handler returns 409 with no write, and renders a conflict modal.
The modal uses role="alertdialog" so assistive technologies announce it. It displays the page URL and the current on-disk mtime as metadata, and offers two choices:
- Reload — discards your pending edits and fetches the latest version via an
hx-getto/_admin/pages{page_url}, which returns the editor form with the fresh content and an updated mtime. - Force save — overwrites the on-disk changes. The button first updates the hidden mtime input to the fresh on-disk value, then submits the form, so the follow-up POST carries the current mtime and succeeds.
Mobile usage
The admin shell is responsive and usable on phones and small laptops. The editor adapts its layout to the viewport: wider screens place the form and live preview side by side, while narrower screens stack them into a single column and move the preview into a summonable overlay so the form has full width. Touch interactions follow the same actions as the desktop pointer flow — tap a row to open it, tap a thumbnail to open the media detail drawer, and use the modal buttons for move, delete, and conflict resolution. The mobile preview path uses the same POST /_admin/preview-render endpoint as the desktop side pane.