Admin Panel holds the global
platform configuration —
a singleton with shared settings and AI budgets. The AI-resource registry
(providers, models, their assignment by function, spend, tools,
system prompt) is factored out into the cross-cutting module
AI Foundation,
and notifications (channels, routes, personal preferences, delivery feed) — into
Notifications.
The singleton's ORM model lives in Knowledge Store
(knowledge_store/models.py); Admin is a thin facade package
(schemas + service + routes) on top of it. Consumers — Harvester,
Query Engine, Agent Engine, Auth — read the model directly; nobody
imports admin, and there are no cycles between modules.
| id | BigInteger | PKCHECK | always 1 · → Singleton |
| org_name | Text | NOT NULLDEFAULT | DEFAULT 'Achilles' |
| org_logo_url | Text | NULL | — |
| org_description | Text | NULL | — |
| accent_color | Text | NOT NULLDEFAULT | hex · DEFAULT '#6366f1' · → Branding |
| timezone | Text | NOT NULLDEFAULT | IANA tz · DEFAULT 'UTC' |
| locale | Text | NOT NULLDEFAULTCHECK | DEFAULT 'ru' · ru · en |
| date_format | Text | NOT NULLDEFAULTCHECK | DEFAULT 'DD.MM.YYYY' |
| access_token_ttl | Integer | NOT NULLDEFAULTCHECK | sec · DEFAULT 900 (15 min) · → Session TTLs |
| refresh_token_ttl | Integer | NOT NULLDEFAULTCHECK | sec · DEFAULT 2592000 (30 days) |
| session_absolute_ttl | Integer | NOT NULLDEFAULTCHECK | sec · DEFAULT 7776000 (90 days) |
| maintenance_mode | Boolean | NOT NULLDEFAULT | DEFAULT false · → Maintenance mode |
| mcp_enabled | Boolean | NOT NULLDEFAULT |
DEFAULT true · kill switch for the MCP door · closed ⇒ a request to /mcp is rejected before the key check ·
→ MCP
|
| ai_monthly_budget | Numeric | NULL |
monthly spend threshold · NULL = not set ·
→ AI budget
|
| ai_budget_alert_enabled | Boolean | NOT NULLDEFAULTCHECK |
alert · DEFAULT false · CHECK: on ⇒ amount set
|
| curation_frequency | Text | NOT NULLDEFAULTCHECK |
cadence of the platform curation run · DEFAULT
'daily' · daily · weekly ·
→ Curation Pass
|
| curation_weekday | Integer | NULLCHECK | 0–6 (Mon–Sun) · weekly only · NULL for daily |
| curation_time | Text | NOT NULLDEFAULT |
'HH:MM' in the organization's local time · DEFAULT
'04:00' · heavy run during quiet hours
|
| agent_weekly_token_budget | BigInteger | NULLCHECK |
weekly per-user token cap for agents · blocking ·
NULL = no limit · spend = SUM(tokens_used) over runs ·
→ AI usage ·
→ Agent Engine
|
| chat_weekly_token_budget | BigInteger | NULLCHECK |
weekly per-user token cap for chat · informational in v1
(tracked without blocking) · NULL = no limit · spend =
SUM(tokens_used) over messages ·
→ AI usage
|
| agent_iteration_cap | Integer | NOT NULLDEFAULTCHECK |
cap on steps in a single run · DEFAULT 15 ·
a safeguard against looping, not a budget ·
→ Agent Engine
|
| agent_max_concurrency | Integer | NOT NULLDEFAULTCHECK |
cap on concurrent LLM calls on the agents' background lane ·
DEFAULT 4 · isolated from live chat ·
→ Agent Engine
|
| created_at | DateTime(tz) | DEFAULT | server_default=now() |
| updated_at | DateTime(tz) | DEFAULT | now() + trigger |
CHECK (id = 1) guarantees uniqueness. The migration
inserts the row with defaults right away — the application always
reads / updates, never creates.
session_absolute_ttl is the maximum
lifetime of a token family (= absolute_expires_at in
the auth module). Auth imports the model from core and reads the TTLs when
issuing tokens.
accent_color — a hex color applied to the login screen
and the header via a CSS custom property. The theme (dark / light) is set
on the client: the first visit follows the system preference
(prefers-color-scheme), and the choice is stored in localStorage.
PlatformSettings ORM model lives in
knowledge_store/models.py, not in admin. Admin
provides the CRUD API (settings service / routes); auth and
other modules import the model to read it. Dependencies flow
admin → KS/auth — no cycles.
locale,
date_format) are Text + CHECK, not a
native PostgreSQL ENUM.
ALTER TYPE ADD VALUE cannot be rolled back inside a transaction —
Alembic migrations are simpler this way.
smtp_settings model (fields, password encryption,
migration) lives with the
Email transport.
Here — only the editing screen
(→ SMTP screen),
which writes the settings through the API.
ai_monthly_budget +
ai_budget_alert_enabled), next to
maintenance_mode. The CHECK prevents enabling the alert
without an amount set. The control sits on the
AI usage screen —
a shared home for limits, next to the weekly token caps; the monthly
bill by model is accumulated by the AI-resource registry
(model_usage,
aggregated by model · function · day) and shown as a
breakdown by model there too.
When the threshold is reached a Budget-type notification is raised — the channel
is owned by the notifications module. The models and their assignments — also in
AI Foundation.
agent_runs.tokens_used
(via agents.user_id), chat — from
messages.tokens_used
(via conversations.user_id). There is no separate per-user counter
table — the cap is derived, like the agent budget.
Both weekly caps
(agent_weekly_token_budget · chat_weekly_token_budget)
live here, in the singleton; the agent one blocks runs, chat is informational in v1.
Indexing and RAG search are not tied to a person — their aggregate is held by
model_usage
(by model · function · day); the same screen shows them as a
breakdown by model, not by person.
Monetary cost per person, a daily user_usage aggregate
as load grows, and chat blocking are
v2.
alembic/versions/NNN_core_platform_settings.py
platform_settings table and, in the same step,
runs an INSERT of the initial row with defaults —
the singleton exists from the first launch, and the application never
creates it. downgrade() — DROP TABLE.