mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-25 23:18:51 -07:00
[api] audit logging
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
-- The audit log — one row per privileged action a staff account took. Owned by the `api`
|
||||
-- worker; WRITTEN by `notify`, which records every call to its admin-gated `/internal/*`
|
||||
-- endpoints here. Generated from packages/domain/src/audit-db.ts (AUDIT_LOG_SCHEMA_DDL) —
|
||||
-- keep in sync.
|
||||
--
|
||||
-- This is not the worker log. `logger.info` lines are for reading during an incident: they
|
||||
-- are sampled, they expire, and nothing can be asked of them later. The actions this table
|
||||
-- exists for leave no other trace on the database at all — a maintenance broadcast is a
|
||||
-- WebSocket frame and then nothing, and a coach message to every online player is
|
||||
-- deliberately not stored (see 0019_notification.sql) — so without a row here there is no
|
||||
-- answer at all to "who sent that, and when", a question that tends to arrive weeks later.
|
||||
--
|
||||
-- `player_id` is the ACTOR: the staff account that made the call, never whoever it was
|
||||
-- aimed at. A target, where there is one, lives inside `data` with the rest of what was
|
||||
-- asked for. The broadcasts have no target at all, so a column for one would be null on
|
||||
-- half the table and could not be the thing every row is filed under.
|
||||
--
|
||||
-- `data` is JSON as TEXT, and deliberately unstructured: each action records what it was
|
||||
-- asked to do, and those shapes have nothing in common beyond being worth keeping. It is
|
||||
-- nullable because an action whose whole content is its name has nothing to put there, and
|
||||
-- null says that where `{}` would only look like a payload that went missing. Capped at
|
||||
-- 4096 characters by the writer, since a request body's size is the caller's to choose;
|
||||
-- over that the row keeps the head of the JSON and says `truncated`.
|
||||
--
|
||||
-- `audit_log_id` is a plain rowid alias, not AUTOINCREMENT: the id never leaves the server
|
||||
-- (unlike `notification`'s, which is handed to the client) and nothing deletes from this
|
||||
-- table, so there are no freed rowids to be reused. Reads order by it rather than by
|
||||
-- `date`, which ties when two actions land in the same millisecond.
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
audit_log_id INTEGER PRIMARY KEY,
|
||||
player_id INTEGER NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
data TEXT,
|
||||
date TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- The two ways anyone asks this table anything: everything one staffer did, and every time
|
||||
-- a given action was taken. Both newest-first, which is the order an audit trail is read in.
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_player ON audit_log (player_id, audit_log_id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_action ON audit_log (action, audit_log_id DESC);
|
||||
Reference in New Issue
Block a user