Records
A record in CompStack is evidence that a process ran. It's the filled-out leave request, the signed audit attendance sheet, the supplier evaluation result, the photo of the completed safety check. Records are the half of ISO compliance that auditors actually check at audit time.
CompStack treats records two ways, and you'll meet both:
- Uploaded records - drag a file (PDF, image, Excel, etc.) onto a process, tag it, add a title and date. Done. This is the 80% case.
- Structured records - fill in a configurable form like "leave request" or "system access request." The form is defined by an admin as a record type.
Both kinds live in the same /records list, both go through the same
optional approval flow, and both are immutable evidence after submission.
The two paths
Path A - upload from a process (the wedge)
This is the path most people use most of the time.
- Open
/processesand click into the process you ran. - Click the Records tab.
- Click + Add record.
- Drop or pick one or more files. Type a title. Set the date the work happened. Add tags.
- Click Upload.
The record is created with status Approved immediately (no review queue -
this is evidence of work that already happened, not a request for permission).
It's now visible on the process's Records tab forever, on /records, and to
anyone in your org with access to the process.
Limits today: 100 MB per file, allowed types are PDF, PNG, JPEG, WebP, Word, Excel, CSV, plain text, JSON.
Path B - file a structured record
For high-frequency forms (leave, access requests, supplier evaluations), an admin pre-defines a record type with a JSON schema. Users then file records against that type.
- Open
/recordsand click + New record. - Pick the record type (e.g. Leave Request).
- Fill the form. Save draft, or submit for approval.
- The record routes through whichever approval chain the type is bound to.
Use this when you want consistent fields across many records of the same kind.
Admins manage these types at /records/types.
What's on the record detail page
Every record at /records/{id} shows:
- Status - Draft, In Review, Approved, Rejected, Cancelled, Closed, Superseded, or Voided.
- Approval mode -
system_default(auto-approved on upload),manual(an admin approved without a chain), orchain(went through an approval chain). Auditors care about the difference. - Files - every file uploaded against this record, with download buttons.
- Linked to - the process (and later in v2, also CAPAs, findings, audits, documents) this record evidences.
- Tags - free-form, normalized to lowercase.
- Form data - only shown for structured records (Path B above).
- Approvals - the chain materialization, if any.
- Notes - internal commentary.
Records are immutable after submission
Once a record is submitted (status leaves draft), the evidence fields lock:
title, form data, record date, submitter, organization, type, files, links -
none of those can change. The Postgres triggers reject any attempt.
What you can do post-submission:
- Edit description and tags (those are searchability metadata, not evidence).
- Transition status through the allowed graph: approved โ closed | voided | superseded.
- Void the record (admin) - mark it retracted with a reason. The record stays in the DB for audit truth.
- Supersede the record (PR-2) - file a new corrected record that points
back at the original via
supersedes_id. The original transitions tosuperseded; the new one becomes the active version.
If you need to "fix" a record, you don't edit it - you supersede or void it. This matches how ISO 9001 audit trails actually work.
Where records live
/records- global list, filterable by status, type, tags, date range./records/types- admin-only, manage structured record templates./processes/{id}โ Records tab - every record linked to that process./records/{id}- detail page with files, links, approvals, history.
Records are visible to:
- The submitter (always sees their own).
- Anyone listed as an approver on the record.
- Other org members for non-draft, non-voided records.
- The user who voided a record (so they can see what they retracted).
Cross-org isolation is enforced at the Postgres RLS layer - there's no path in the app that lets one org read another org's records.
Tags
Tags are free-form strings. They're normalized to lowercase + trimmed at insert. Common patterns auditors will use:
- The fiscal period (
2026-q2,april-2026) - The artifact type (
attendance,signed-pdf,photo,result) - Subject keywords (
supplier,customer,vendor)
There's no autocomplete in the upload modal yet (deferred to v2.1) - type your own tag values, separated by commas or Enter.
Approval modes
Three modes, all stored explicitly so an auditor can tell them apart:
- system_default - Set automatically when records are uploaded from a process. No human reviewed; the system trusted the submitter. Use when the evidence is a finished artifact (signed PDF, attendance sheet).
- manual - An admin marked it approved without routing through a chain. Used for "yes I checked this in person, approving directly."
- chain - Went through one or more approval steps via an approval chain
bound to a record_type. Each step is materialized in
approvals.
If your audit program requires every record to have human approval, use Path B
(structured records bound to a chain) so approval_mode='chain' everywhere.
Test it
- On any process detail page, the Records tab is visible.
- Click + Add record, pick a file, fill title and date, click Upload. The modal closes; a row appears on the tab.
- Click into the new record. Files section shows the upload; click the filename and the file downloads.
- On
/records, the new record is visible. - Open the record in another browser tab - without refreshing, edits made in the first tab appear (realtime).
- Try to file a record on a process in a different org via direct URL - you should see "process not found" or the modal should refuse.
- Submit an approved record from
/records/types(Path B), have the approver approve it, see the status flip in the inbox.
Known gaps
These are explicitly deferred. Track them in Known gaps and backlog:
- Drag-and-drop file picker (today the modal opens an OS file dialog).
- Tag autocomplete and canonicalization.
- Saved filter views on the records list.
- AI auto-classification (suggest tags + type from filename and file content).
- OCR + full-text search across uploaded PDFs.
- Bulk import (drag a folder of 50 records).
- Server-side SHA-256 verification of uploaded files.
- Virus scanning at upload time.
- Per-org storage quota.
- Storage orphan reconciler (today: monitored, not auto-cleaned).
- The 4-tab department detail page (Manuals, Policies & Procedures, Process Flows, Forms) that surfaces records by document type - coming in PR-2.
- Linking records to CAPAs, findings, audits, and documents directly (today: process-only) - coming in PR-3.