CQL WorkbenchDocs
Docs contents
Admin

Admin console

How admins set up model connections, manage accounts and roles, and back up and restore the system settings.

The admin console is under the 管理 (Admin) menu on the left. Only admins can see it, and its APIs accept only admins. The menu also has system status, background jobs, prompt templates and other pages; this page covers LLM settings, users and settings backup.

LLM settings

Each model connection used for analysis is called a profile. Under 管理 → LLM 設定 (Admin → LLM settings) you can set up several, then pick a pool strategy that decides which one each call goes to.

FieldWhat it does
Name 名稱A name to tell profiles apart.
ProviderOllama, or an OpenAI-compatible service.
Base URLThe service address. For an OpenAI-compatible service it may include /v1.
API KeyThe list shows only the last four characters. When editing, leave it empty to keep the current key. Ollama usually doesn’t need one.
Model 模型Press 抓取 (Fetch) to list the models the service offers.
Enabled 啟用A disabled profile takes no part in analysis.
Allow parallel requests 允許並行請求When off, calls to this profile go one at a time and the rest wait in the backend.
PriorityFor fallback, lower numbers are tried first. Default 100.
WeightThe load-balancing weight. Default 1.
Timeout (seconds) Timeout(秒)Timeout for a single call. Default 300.
Temperature, Top PLeave empty to use the service’s default.

There are two pool strategies:

FallbackTries profiles by priority, lowest first, and uses the first successful response. Suits a primary with a standby.
Load balanceEvery call draws a new weighted-random order. Suits several equivalent services sharing traffic.

Both strategies use only enabled profiles. If one fails, the next is tried; a call fails only when all of them do.

Saved settings take effect immediately: profiles are read again for every call, so there is no backend restart. The test buttons (測試 in the list, 測試連線 in the edit dialog) send a ping and show whether the service answers and how fast.

Mind the concurrency: up to 4 tasks of a document are analyzed at once, and each task runs up to 3 per-condition cross-check calls at once. Both can be changed with ANALYSIS_CONCURRENCY and NODE_REVIEW_CONCURRENCY. For a local model that handles one request at a time, such as Ollama or llama.cpp on a single GPU, turn off parallel requests; otherwise requests pile up inside the model server with their timeouts still running, and end up timing out.

If the database has no enabled profile, the backend falls back to the Ollama set by the environment variables OLLAMA_HOST and OLLAMA_MODEL.

The prompt for every analysis stage is under 管理 → Prompt 範本 (Admin → Prompt templates); a saved version replaces the built-in one. For what each stage does, see the analysis pipeline.

Users and roles

Accounts have one of three roles:

RoleWhat it can do
Admin 管理員Everything, including the whole admin console and unlocking locked clauses.
Reviewer 審核者Upload and analyze documents, edit tasks, review each condition and sign off on clauses, edit logic, re-analyze conditions, and send approved clauses back for re-review.
Viewer 檢視者Sees documents, the clause review page and the tools pages, but can’t upload, analyze, sign off or edit logic.

Permissions are enforced by the backend, not just by hiding buttons: apart from the health check, sign-in and sign-out, every API requires a signed-in user, and write actions are further limited by role.

Under 管理 → 使用者 (Admin → Users) you can add accounts, change roles, reset passwords, and disable or re-enable accounts. Usernames are 2–64 letters, digits or . _ @ -, passwords are 8–128 characters, and new accounts default to reviewer.

Accounts can’t be deleted, only disabled. Review history and sign-offs record who did them, and deleting the account would destroy that history. A disabled account can’t sign in, and all its records stay.

You can’t disable your own account, and at least one enabled admin must remain.

Disabling an account or changing its role doesn’t wait for the user to sign out: every request checks whether the account is still enabled and what its role is now.

Replace the default admin before go-live: when the users table is empty, the backend creates an admin on startup. Its username and password can be set with SEED_ADMIN_USER and SEED_ADMIN_PASSWORD; otherwise it uses the development defaults.

Sign-in and lockout

After sign-in, the session is kept in an httpOnly cookie, and users must sign in again after 24 hours.

After 10 failed sign-ins for the same account from the same IP within 15 minutes, further attempts are blocked until 15 minutes have passed since the first failure, and the screen says how many minutes to wait. A successful sign-in resets the count.

The count is kept per account and IP, so someone guessing one account’s password doesn’t lock out everyone else in the same office.

Every failure is written to audit_log (auth.login_failed) with the source IP.

The count lives in the backend’s memory, so restarting the backend resets it.

Settings backup

管理 → 設定備份 (Admin → Settings backup) exports the system settings to one encrypted file that you can restore on another host or after a rebuild. The file contains:

  • Every LLM profile and the pool strategy, including API keys.
  • Every user account, including its argon2 password hash (not the plain password), so users keep their passwords after a restore.
  • A few other system settings.

To export, set an encryption passphrase of at least 12 characters, enter it twice, and download the .cqlbak file. It is encrypted with AES-256-GCM, with the key derived from the passphrase by scrypt. The only unencrypted parts are the export time and the number of LLM profiles and accounts, so you can tell files apart.

Importing takes two steps, and the first writes nothing:

  1. Choose the backup file, enter its passphrase and press 解密並預覽 (Decrypt and preview). The screen shows what the file contains and what the import would delete or disable.
  2. If that looks right, type REPLACE and press 確認匯入並覆蓋 (Confirm import and overwrite).

An import overwrites; it doesn’t merge:

ItemAfter import
LLM profiles and pool strategyReplaced wholesale: every current profile is deleted and the file’s profiles take their place, along with its strategy.
Accounts in the fileCreated if missing; otherwise their password hash, display name, role and enabled state are overwritten.
Accounts not in the fileDisabled, not deleted; their review history stays.
Other system settingsOverwritten with the file’s contents.
Prompt templates Prompt 範本Not in the backup; an import leaves them alone.

The import is refused when:

  • The file has no enabled admin. After the import nobody could get into the admin console.
  • The passphrase is wrong, or the file is damaged or tampered with. Decryption can’t tell these apart, so both are refused.
  • The backup file comes from a newer version than the running system.
  • An account has no password hash or a hash that isn’t argon2, or an LLM profile lacks a name, model or Base URL.

The import runs in a single database transaction: either all of it applies or nothing changes.

Keep backup files safe: they hold working API keys and every account’s password hash. The passphrase isn’t stored anywhere in the system and can’t be recovered if lost; keep it apart from the file.