Document System
The document system has 5 layers. Understanding the snapshot rule is critical.
Architecture
DocumentDefinition (workspace master)
└── DocumentTemplate (admin-uploaded reference files)
ApplicationTemplate
└── ApplicationTemplateDocument (join: template ↔ definition, with required/optional override)
Application
└── ApplicationDocumentDefinition (SNAPSHOT copied at app creation)
└── ApplicationDocument (actual client file upload)
Layer 1: DocumentDefinition
The workspace-level master list of document types. Managed by admins.
Fields: name, description, category, defaultRequired, allowCustomDocuments, type
- Workspace-scoped — shared across all templates in the workspace
- Changes here do NOT propagate to existing applications
Layer 2: DocumentTemplate
Admin-uploaded reference files attached to a DocumentDefinition.
- Example: a standard income statement form that clients should fill in
- Fields:
fileUrl,fileType,fileName,fileSize - Clients can download these from the document slot view
Layer 3: ApplicationTemplate + ApplicationTemplateDocument
An ApplicationTemplate defines an application type. It links to DocumentDefinition records via ApplicationTemplateDocument join entries.
ApplicationTemplateDocument allows:
- Overriding the default
required/optionalflag for this template - Setting
sortOrder(display order) - Adding
instructionsspecific to this template
Permissions: Creating/updating requires OWNER, ADMIN, or MANAGER role.
Layer 4: ApplicationDocumentDefinition (document slot)
When an application is created from a template, the document definitions are copied as snapshots into ApplicationDocumentDefinition records. They are not live-linked to the source DocumentDefinition.
Changing a DocumentDefinition or ApplicationTemplateDocument does not update existing applications.
- One
ApplicationDocumentDefinitionper expected document on the application - Links back to
documentDefinitionId(nullable for custom/ad-hoc documents) - Has its own editable
name,description,category,required,instructions,sortOrder - Custom documents (if
allowCustomDocuments = true) havedocumentDefinitionId = null
Computed status — derived from the ApplicationDocument records beneath it, not stored directly.
Layer 5: ApplicationDocument (actual upload)
The actual file submitted by a client or staff member.
Status enum:
| Status | Set by | Meaning |
|---|---|---|
| PENDING | System | No uploads yet |
| UPLOADED | System | At least one file uploaded |
| APPROVED | Staff | At least one file approved |
| REJECTED | System | All uploaded files rejected, none approved |
| NOT_APPLICABLE | Staff | Manually marked — the only manually-set status |
Status computation logic:
- PENDING → no uploads
- UPLOADED → at least one file uploaded
- APPROVED → at least one APPROVED upload
- REJECTED → all UPLOADED are rejected, none approved
- NOT_APPLICABLE → staff manually set (overrides everything)
Document review actions
Staff review uploaded documents via reviewApplicationDocument mutation:
- APPROVE → sets status APPROVED, creates action log comment
- REJECT → sets status REJECTED, requires
reviewNote, creates action log comment - RE_REQUEST → prompts client to re-upload, creates action log comment
- NOT_APPLICABLE → marks slot as not needed
These review actions automatically generate system comments (action log) in the DOCUMENTS category.
Permissions
| Action | Required role |
|---|---|
| Create/update DocumentDefinition | OWNER, ADMIN, MANAGER |
| View DocumentDefinition | Any workspace role |
| Submit ApplicationDocument (upload) | Any authenticated user |
| Review ApplicationDocument (approve/reject) | Staff only (not CLIENT) |
| List ApplicationDocuments | Workspace role or client membership |