Immutable version rows
document_versions has UNIQUE(document_id, version_number) and is never updated. History is forever.
Versioned SOPs, training records, calibration certificates and supplier qualification - under one row-level-secure roof, with a tamper-evident audit log.

A bad SOP rollout can stop the line. With Tracegence, you upload v2 alongside v1 - neither is ever deleted. If v2 introduces a regression, one click on v1 makes it current again. The document_versions table is immutable, the audit log records the swap, and your line keeps running.
Training records, calibration certificates, internal audit reports, mock-recall reports - same primitive, same controls, same audit trail. No special "SOP module" with its own quirks; one repository, role-gated and tagged.
document_versions has UNIQUE(document_id, version_number) and is never updated. History is forever.
Pointer flips to the version you choose. Audit log captures the swap with both version IDs.
30/14/7/1 day notifications scheduled when a doc with an expiry lands. Re-upload bumps the cycle.
Five-role hierarchy (Owner/Admin/Manager/Client/Auditor). Cross-tenant leak gated by CI.

The audit-trail isn't a label - it's a Postgres trigger that physically blocks UPDATE and DELETE on the audit_logs table. Even a compromised admin can't rewrite history. Compliance officers verify this in their first demo.
Calibration cert lapses? Pest control report 14 days from expiry? You and the document owner are notified across email and SMS, with the document owner's name on the alert. No chasing in a group chat.
audit_logs raises on UPDATE/DELETE at the database. Application code can't bypass it.
Email ยท SMS ยท WhatsApp (Q3). Owner name + document title + days remaining on every notification.
Sidebar tree by folder. Tag chips with live counts. Filter is one click, response < 100ms.
One streamed download covers every action across every document for the audit window.
Full visibility and control over supplier and production documents. Each capability below is shipping today unless tagged Roadmap.
One repository for every supplier doc - CoAs, certs, SOPs, training records - stored in S3 with per-tenant prefixing and Postgres row-level security. Suppliers upload via a tokenized link without needing an account.
5-tier cadence - 30 / 21 / 14 / 7 / 1 day - fired automatically when any doc with an expiry date lands. Email + SMS (WhatsApp Q3). Re-upload bumps the cycle; cancelled jobs stay in the audit trail.
No row caps on the Supplier, DocumentType, or Lot tables. Plan-tier limits are enforced by the quota app on storage volume - never on profile count.
One click generates an audit-ready PDF (cover page โ summary โ evidence table) or CSV for the spreadsheet trail. SQF / BRCGS / generic templates today; XLSX on request.
Document state machine - pending โ processing โ successful / failed / review_required - exposed on the dashboard. SPA polls every 5s for in-flight docs and 30s for KPI metrics.
Tenant-scoped REST API covers every entity (documents, suppliers, lots, certs, audit log). Outbound webhooks for state-change events and pre-built SAP / NetSuite / TrackWise connectors are on the roadmap - design-partner driven.
Click any stage to see how the underlying tables and triggers enforce control. Versioning is the cornerstone - DocumentVersion rows are immutable.
Drop the SOP / training record / calibration cert. Tag it, place it in a folder, attach to a supplier. Storage delta event emitted on every upload.
POST /documents (multipart)Drop the SOP / training record / calibration cert. Tag it, place it in a folder, attach to a supplier if relevant.
POST /documents (multipart)Each upload after the first creates v2, v3 - the document_versions table is immutable. Old versions remain.
document_versionsOptional sequential or parallel approval workflow. Each step HMAC-signed. Rejections cite the rule.
apps/workflows/services.pyExpiry alerts auto-scheduled. Pest control out of date? Calibration certificate lapsed? Email + SMS to the document owner.
apps/notifications/One CSV export covers every action against every document for the audit window. Append-only by DB trigger.
apps/audit_log/views.pyOld version becomes current with one click. The previous current stays in history; you can see exactly when and why the swap happened.
POST /documents/.../restoreDates are targets, not commitments. Design partners get earlier access.
Start with one folder of training records - see the difference within an audit cycle.