Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/CodexaCP/DG_BACK/llms.txt

Use this file to discover all available pages before exploring further.

Dragon Guard records an immutable audit log for every create, update, and delete operation that flows through the API. Audit entries are written automatically by the database context using EF Core’s change-tracker, and additional manual entries cover actions that occur outside of normal entity saves — such as user registration and password changes. The result is a complete, append-only history of all warehouse data mutations, queryable by tenant, table, user, or date range.

How Auditing Works

WmsDbContext overrides SaveChangesAsync to intercept EF Core ChangeTracker entries before and after each save. For every entity that is added, modified, or deleted, the context records:
  • The table name (schema-qualified, e.g., core.RfidTagRegistry)
  • The action: Insert, Update, or Delete
  • The entity ID (primary key of the changed record)
  • The company ID extracted directly from the entity’s CompanyId property
  • A JSON snapshot of old values (previous state before the change)
  • A JSON snapshot of new values (state after the change)
  • The comma-separated list of changed columns
  • The user email, user role, and user ID from the active HTTP context JWT
  • The client app (Web, Handheld, API, or System) inferred from the X-Client-App header or User-Agent
  • The request path and HTTP method of the originating API call
  • The timestamp (createdAt) in UTC
The audit write itself is a second SaveChangesAsync call, and audit log entities are explicitly excluded from triggering further audit entries, preventing infinite recursion.

Manual audit entries

For actions that occur outside of EF (such as user registration or a password change), services call WmsDbContext.AddManualAuditLog() directly:
AddManualAuditLog(
    tableName: "auth.Users",
    action:    "PasswordChanged",
    entityId:  userId,
    companyId: companyId,
    oldValues: null,
    newValues: null);

AuditLog Fields

id
guid
required
Unique identifier of the audit record.
tableName
string
required
Schema-qualified table name of the affected entity (e.g., core.Items, core.RfidTagRegistry).
action
string
required
The operation that triggered this entry. One of Insert, Update, Delete, or a manual action label such as PasswordChanged.
entityId
guid
Primary key of the changed record.
companyId
guid
Tenant scope of the changed record. null for system-level events with no tenant.
oldValues
string (JSON)
JSON object containing field values before the change. null for inserts.
newValues
string (JSON)
JSON object containing field values after the change. null for deletes.
changedColumns
string
Comma-separated, alphabetically sorted list of column names that changed.
userId
guid
ID of the user who performed the operation.
userEmail
string
Email address of the user who performed the operation.
userRole
string
Role of the user at the time of the operation (e.g., ADMIN, SUPERVISOR, SUPERADMIN_SUPREMO).
requestPath
string
The HTTP request path that triggered the change (e.g., /api/items/123).
httpMethod
string
HTTP method of the originating request (POST, PUT, DELETE, etc.).
clientApp
string
Detected client type: Web, Handheld, API, or System.
userAgent
string
Raw User-Agent string from the originating request.
createdAt
datetime (UTC)
required
Timestamp when the audit record was written.
In API responses, each AuditLogDto also includes three computed display fields:
friendlyModule
string
Human-readable module name derived from tableName (e.g., "RFID Tag Registry").
friendlyAction
string
Human-readable action label (e.g., "Created", "Updated", "Deleted").
description
string
Auto-generated sentence summarising the event (e.g., "[email protected] created a record in Items").

Audit Endpoints

GET /api/audit/logs

Returns a paginated list of audit records. Results are ordered by createdAt descending (most recent first) and capped at 100 records per page.
companyId
guid
Filter by tenant. SUPERADMIN_SUPREMO can pass any tenant ID; regular users are always scoped to their own company.
tableName
string
Exact table name to filter on (e.g., core.RfidTagRegistry).
action
string
Exact action to filter on (e.g., Insert, Update, Delete).
userEmail
string
Partial match on the user email that performed the operation.
entityId
guid
Filter to audit records for a specific entity (record) ID.
clientApp
string
Exact client app label (Web, Handheld, API, System).
Full-text search across tableName, action, userEmail, changedColumns, requestPath, oldValues, and newValues.
from
datetime (UTC)
Include only records with createdAt >= from.
to
datetime (UTC)
Include only records with createdAt <= to (inclusive end of range).
pageNumber
integer
default:"1"
Page number (1-based).
pageSize
integer
default:"25"
Number of records per page. Maximum is 100.
# Fetch the first page of Insert events for the RFID Tag Registry table
GET /api/audit/logs?tableName=core.RfidTagRegistry&action=Insert&pageSize=25
Authorization: Bearer <token>

GET /api/audit/modules

Returns the distinct table names (modules) that have audit records, along with a human-readable label for each — suitable for populating filter dropdowns in a UI.
[
  { "value": "core.Items",           "label": "Items" },
  { "value": "core.RfidTagRegistry", "label": "RFID Tag Registry" },
  { "value": "auth.Users",           "label": "Users" }
]
The legacy alias /api/audit/tables is preserved for backward compatibility and delegates directly to /api/audit/modules.

GET /api/audit/action-options

Returns all known action types with their human-readable labels. Useful for building action-filter dropdowns.

Access Control

RoleAccess
SUPERADMIN_SUPREMOCan view audit logs across all tenants by passing any companyId
ADMIN, SUPERVISOR, DIRECTOR, GENERAL, GENERAL_SUPERVISORCan view audit logs scoped to their own company only
All other rolesAccess denied (403 Forbidden)
Audit logs are append-only. There are no delete or modify endpoints. This is by design — the audit trail must remain tamper-evident.

Practical Usage Tips

Use the tableName and action filters together to narrow down noisy result sets. For example, tableName=core.RfidTagRegistry&action=Insert shows only newly registered RFID tags.
Combine from and to with userEmail to reconstruct what a specific operator did during a shift. Pass ISO 8601 UTC timestamps to avoid timezone ambiguity (e.g., from=2024-06-01T06:00:00Z&to=2024-06-01T14:00:00Z).
The clientApp field lets you distinguish activity from warehouse handheld scanners (Handheld) from back-office UI changes (Web) or direct API integrations (API).

Build docs developers (and LLMs) love