Audit Logs & Activity Tracking
Relevant source files
The following files were used as context for generating this wiki page:
The Audit Logs & Activity Tracking system within Outmanage provides a comprehensive trail of all significant entity changes and user actions. This system is critical for maintaining accountability, debugging operational discrepancies, and meeting compliance requirements in an outbound logistics environment. It captures granular details including "who" performed an action, "what" changed (capturing both old and new data states), and "when" the event occurred, standardized to the Jakarta timezone (UTC+7).
The tracking mechanism is integrated directly into the service layer, ensuring that every creation, update, or deletion of core entities—such as Warehouses, Delivery Orders, Shipments, and Products—is recorded. This data is exposed through specialized logging endpoints, allowing administrators to review the history of specific resources or view a global activity stream across the entire organization.
Sources: src/services/warehouseLogService.ts:31-40, comprehensive-swagger-api.json:1140-1150, CLAUDE.md:25-26
Architectural Overview
The logging architecture utilizes a service-oriented pattern where dedicated log services (e.g., WarehouseLogService, DeliveryOrderLogService) handle the persistence of audit records. These services are typically called within Prisma database transactions inside the main entity services to ensure that an entity change and its corresponding log entry are treated as an atomic operation.
The diagram above illustrates the typical flow where logging is encapsulated within the same transaction as the primary data modification.
Sources: src/services/warehouseService.ts:160-185, src/services/shipmentService.ts:285-315
Key Components & Log Services
The system segments audit logs by entity type, providing specialized services for each major module.
Warehouse Logging
The warehouseLogService tracks lifecycle events for warehouse facilities. It explicitly handles JSON data transformation to ensure that complex relationships, such as assigned users, are recorded clearly. When a warehouse is created or updated, the service calculates a Jakarta-offset timestamp (Date() + 7 hours) to maintain local time accuracy in the database.
Key functions include:
logWarehouseCreation: Captures the initial state of a warehouse.logWarehouseUpdate: Records specific changed fields and the previous state (oldDatavsnewData).logWarehouseDeletion: Records final state before a hard delete.
Sources: src/services/warehouseLogService.ts:41-85, src/services/warehouseService.ts:210-230
Delivery Order (DO) Logging
The deliveryOrderLogService monitors customer order changes. It includes specific logic for post-weighing events, such as customer reassignment or quantity revisions due to vehicle capacity limits.
| Log Event | Logic Description |
|---|---|
| Creation/Update | Standard entity state tracking. |
| Customer Change | Specifically logs oldCustomerId vs newCustomerId after weighing is finalized. |
| DO Revision | Detailed mapping of item changes, explicitly listing ${productName} (${oldQty} → ${newQty}). |
| Transfer Items | Records the creation of new DOs derived from remaining items in finished shipments. |
Sources: src/services/deliveryOrderLogService.ts:100-150, src/services/deliveryOrderLogService.ts:160-180
Shipment Logging
Shipment tracking is the most complex component, recording logistics statuses through various stages: PENDING, PROSES, and SELESAI. It captures critical operational milestones such as:
- Product Selection: When items are "Chosen" for loading.
- Weighing Events: Individual and bulk weighing metrics (Gross, Tare, Net).
- Plate Verification: Both AI-powered (Gemini) and manual plate number match results.
Sources: src/services/shipmentService.ts:1050-1100, src/services/shipmentService.ts:1250-1280
Data Schema & Persistence
Audit logs are stored in dedicated tables within the MySQL database via Prisma. Each log entry follows a consistent structure to allow for uniform query patterns across different entity types.
The diagram above represents the logical structure shared by all logging entities.
Log Entry Fields
| Field | Type | Description |
|---|---|---|
performedById | UUID | The user who initiated the action (foreign key to User). |
action | Enum | CREATE, UPDATE, or DELETE. |
oldData | JSON | Snapshot of the entity before the change. |
newData | JSON | Snapshot of the entity after the change or the created record. |
description | String | A human-readable summary of the action (e.g., "Membuat gudang baru: Gudang A"). |
Sources: src/services/warehouseLogService.ts:10-20, src/services/deliveryOrderLogService.ts:15-30
API Access & Retrieval
The system provides paginated access to audit trails through the /api/ route prefix. Most logging endpoints follow a standard query parameter pattern for page and limit.
Pagination Logic
The services use Prisma.$queryRaw or standard Prisma finders with skip and take to manage large log volumes. For example, getAllWarehouseLogs calculates skip = (page - 1) * limit.
// Example of raw query logging with JSON object construction
prisma.$queryRaw<RawWarehouseLog[]>`
SELECT wl.*,
JSON_OBJECT('id', w.id, 'name', w.name) as warehouse,
JSON_OBJECT('id', u.id, 'name', u.name) as performedBy
FROM WarehouseLog wl
LEFT JOIN Warehouse w ON wl.warehouseId = w.id
LEFT JOIN User u ON wl.performedById = u.id
ORDER BY wl.createdAt DESC
LIMIT ${skip}, ${limit}
`
Sources: src/services/warehouseLogService.ts:100-125, comprehensive-swagger-api.json:1150-1200
Available Audit Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/warehouses/logs | GET | Global warehouse activity. |
/api/warehouses/logs/{id} | GET | Audit trail for a specific warehouse facility. |
/api/delivery-orders/logs | GET | All DO related changes. |
/api/shipments/logs | GET | Comprehensive shipment lifecycle events. |
/api/products/logs | GET | Inventory/Product modifications. |
Sources: comprehensive-swagger-api.json:1140-1160, comprehensive-swagger-api.json:1550-1570
Timezone Management
A critical aspect of the activity tracking system is the consistency of timestamps. Since the project operates primarily in the Jakarta region, all log services manually adjust the server's UTC time.
// Consistent pattern found across all log services
const jakartaTime = new Date();
jakartaTime.setHours(jakartaTime.getHours() + 7);
// Saved to createdAt and updatedAt in log tables
This ensures that when operational staff view logs, the "Activity Time" matches their local clock, preventing confusion during shift changes or delivery audits.
Sources: src/services/warehouseLogService.ts:31-35, src/services/deliveryOrderLogService.ts:18-22, src/index.ts:100-105
Conclusion
The Audit Logs & Activity Tracking module is a robust subsystem designed for high-fidelity data preservation. By capturing JSON snapshots of entity states and enforcing atomic logging within database transactions, it provides a reliable source of truth for the system's history. The integration of Jakarta timezone offsets and specialized handlers for complex events like bulk weighing or DO transfers ensures that the tracking is both technically accurate and operationally relevant.