Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

08 — Form Specifications (Audit Module)

Every form field field-by-field. The Audit module has one form: the filter bar. There are no mutation forms — the module is append-only read (audit.controller.ts:17), so no create/update/delete DTOs exist. Validation mirrors the absence of server-side DTOs: AuditController.query() takes raw query params with defaults (audit.controller.ts:19-25) — there is no AuditQueryDto, hence no class-validator rules; the client self-validates.


1. Audit Filter Form (non-mandatory, all fields optional)

#FieldControlQuery paramServer handlingClient UX / validation
1ActionAppDropdown (searchable, free list)actionoptional string → filter.action (audit.controller.ts:22,27)values = distinct actions from data; free text allowed (enum is open — audit.handler.ts:36)
2Entity typeAppDropdown (searchable)entityTypeoptional string → filter.entityType (audit.controller.ts:23,28)exact match against entityType; helper note: rarely populated by emitters (OQ-1)
3ActorAppDropdown/AppTextFieldactorIdoptional string → filter.actorId (audit.controller.ts:24,29)exact actorId string; name→id resolution (proposed) via users module
4Pageimplicitpagedefault 1, cast Number(page) (audit.controller.ts:20,31)client keeps internally; non-numeric → server CastError → 400 (http-exception.filter.ts:47-55)
5Limitimplicitlimitdefault 50, cast Number(limit) (audit.controller.ts:20,32)client uses 50; unbounded server-side (no max clamp, OQ-7)
6Date range(planned) — no from/to params existblueprint promises date-range querying (AUDITING.md:86) — backend (planned)
7Search q(planned)shared convention q (00-shared/07 §5) not supported by this controller
8Sortnone (fixed)always occurredAt desc (audit-log.repository.ts:23); sort param unsupported

Filter combination rule (server): all present filters AND-combined into one Mongo filter object, always merged with the tenant scope: { tenantId, action?, entityType?, actorId? } (audit.controller.ts:26-29, audit.service.ts:45-48).

Form-level rules:

  • Submitting a filter → reset page=1 → reload; no debounce needed (explicit dropdown selection, not keystrokes); actor text field debounce 300 ms (AppSearchBar default).
  • "Clear filters" resets all three fields + page.
  • Double-submit: dropdowns single-select, no pending overlap; Load-more disabled while a request is in flight.
  • Optimistic: none — filter changes always hit the server (list is server-paginated).
  • Error priority (client, 00-shared/06 §5): 400/404 → keep filters, snackbar; 429 → countdown; 5xx → AppErrorState; 401 → session flow.

Empty-result copy: "No activity matches these filters" + Clear filters (not an error — total === 0 is a valid success state).