Feature: Audit Log #29
Labels
No labels
area:api
area:core
area:docs
area:infra
area:ux
dependencies
documentation
duplicate
good first issue
help wanted
invalid
question
rust
status:complete
status:partial
status:planned
type:bug
type:design
type:feature
type:infra
type:refactor
type:research
type:ux
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
icub3d/decentcom#29
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Migrated from GitHub issue icub3d/decentcom#29
Original Author: @icub3d
Original Date: 2026-04-15T14:15:59Z
Feature: Audit Log
Overview
The audit log is an append-only record of administrative and moderator actions on the server. Every privileged action (role changes, kicks, bans, channel modifications, permission updates, server setting changes) is logged with the actor, action, target, timestamp, and details. The log is queryable via a REST API and viewable in the client's admin panel.
Background
The server-model doc (
docs/design/server-model.md) lists an audit log for admin actions as a moderation feature and includes "View audit log" as an admin operation. The storage doc (docs/design/storage.md) categorizes audit logs as append-only data. The log should be tamper-resistant — entries are never modified or deleted through normal operations.Depends on:
roles(feature #11),membership(feature #13), all Phase 1 and Phase 2 features.Requirements
view_audit_logpermission can access the audit logDesign
API / Interface Changes
REST endpoints:
/api/v1/admin/audit-log/api/v1/admin/audit-log/{entry_id}Query parameters for
GET /api/v1/admin/audit-log:action_typemember_kick,role_update)actor_idtarget_idbeforeafterlimitResponse:
Action types:
member_kickmember_banmember_unbanrole_createrole_updaterole_deleterole_assignrole_revokechannel_createchannel_updatechannel_deletechannel_permission_updatemessage_deletemessage_pinmessage_unpininvite_createinvite_deleteserver_updatekey_rotationData Model Changes
New table:
audit_logidaction_typeactor_idtarget_typeuser,channel,role,message,invite,server)target_iddetailscreated_atIndexes:
(action_type, created_at)— for filtering by action type(actor_id, created_at)— for filtering by actor(target_type, target_id, created_at)— for filtering by target(created_at)— for paginationComponent Changes
Server (
server/):server/src/models/audit.rs— new model:AuditLogEntrystruct,ActionTypeenum, serializationserver/src/storage/trait.rs— extend withAuditStoretrait:append(entry),query(filters, pagination),get(id)server/src/storage/sqlite/audit.rs— SQLite implementation ofAuditStoreserver/src/storage/postgres/audit.rs— PostgreSQL implementation ofAuditStore(if postgres feature is available)server/src/audit.rs— new module:AuditLoggerservice that is injected into route handlers; provideslog_action()methodserver/src/routes/admin.rs— add audit log query endpointsAuditLogger::log_action():server/src/routes/members.rs— kick, ban, unbanserver/src/routes/roles.rs— create, update, delete, assign, revokeserver/src/routes/channels.rs— create, update, delete, permission overridesserver/src/routes/messages.rs— moderator delete, pin, unpinserver/src/routes/invites.rs— create, deleteserver/src/routes/settings.rs— server config changesClient (
client/src/):client/src/components/admin/AuditLog.tsx— new component: audit log viewer with table layout, action type icons, actor/target linksclient/src/components/admin/AuditLogFilters.tsx— new component: filter controls (action type dropdown, actor search, date range)client/src/components/admin/AuditLogEntry.tsx— new component: expanded view of a single audit log entry with full detailsclient/src/hooks/useAuditLog.ts— new hook: fetches audit log entries with filters and paginationclient/src/stores/adminStore.ts— extend with audit log state (or new dedicated store)Task List
Phase A: Data Model and Storage
audit_logtable migration for SQLite (server/migrations/012_audit_log.sql)audit_logtable migration for PostgreSQL (deferred)AuditLogEntrystruct added toserver/src/storage/models.rsAuditStoretrait +AuditLogQuerydefined inserver/src/storage/traits.rsserver/src/storage/sqlite/audit.rsPhase B: Audit Logger Service
server/src/audit/mod.rs—log_action()free function; errors are logged but never propagatePhase C: Query API
GET /api/v1/admin/audit-logwith filters (action_type,actor_id,target_id,beforecursor,limit)GET /api/v1/admin/audit-log/{entry_id}— single entryVIEW_AUDIT_LOGpermission (bit 12) enforced on both endpointsPhase D: Client UI
client/src/hooks/useAuditLog.ts— fetch, filter, and paginate audit log entriesclient/src/components/admin/AuditLog.tsx— main audit log viewer with infinite scroll or paginationclient/src/components/admin/AuditLogFilters.tsx— filter controlsclient/src/components/admin/AuditLogEntry.tsx— detailed entry viewTest List
AuditLogEntryserialization/deserialization round-trips correctlyappend()inserts an entry and it is retrievable viaget()query()with no filters returns entries in reverse chronological orderquery()withaction_typefilter returns only matching entriesquery()withactor_idfilter returns only matching entriesquery()withtarget_idfilter returns only matching entriesquery()pagination (cursor-based) returns correct pagesmember_kickaudit log entry with correct actor and targetmember_banaudit log entrychannel_createaudit log entryrole_updateaudit log entryview_audit_logpermissionOpen Questions