M16 File Vault — unified document management
Two-pane Windows-Explorer-style file browser surfacing every file in the system — job attachments, client docs, employee docs, generated reports, vault uploads. Folders + tags + per-doc retention + watermarking + share links + audit log. The "where are the files?" answer.
What's in the Vault
The Explorer aggregates files from 6 source tables — read-only, presented as one tree:
| Source | What lives there |
|---|---|
| job_attachments | Loose files uploaded to a job (TB, signed engagement letter) |
| job_documents | Generated reports (audit report PDF, FS pack) |
| client_documents | CR, trade license, MOA, etc. with expiry tracking |
| company_documents | Firm's own docs (CR, VAT cert, etc.) |
| employee_documents | Civil ID, passport, visa, contract |
| documents (M16 vault) | First-class M16 uploads — versioned, foldered, tagged |
The Explorer (default landing)
URL: /documents/explorer. Two-pane GUI:
- Left pane (240-340px): tree showing 5 branches — Clients · Engagements · Firm Compliance · Employees & HR · Vault Uploads
- Right pane: working area with breadcrumb · search · folder cards · file rows
- File row actions: Preview · Download · Open in source module
- Source badge per file: "Vault" · "Job file" · "Generated" · "Client doc" · "Compliance" · "HR"
Virtual paths
| Path | Resolves to |
|---|---|
| /clients/{id}/_docs | Client compliance documents |
| /clients/{id}/jobs/{id}/_attachments | Loose job uploads |
| /clients/{id}/jobs/{id}/_documents | Generated reports |
| /clients/{id}/jobs/{id}/folders/{id} | Phase folders (planning/fieldwork/etc.) |
| /employees/{id}/_docs | Employee documents |
| /firm/_docs | Company documents |
M16 Vault uploads (first-class)
Beyond aggregating other modules' files, M16 also has its own upload pipeline at /documents/uploads:
- Auto-numbered
DOC{YYYY}/{NNNN} - Folder hierarchy with cascade rename
- Tags with hex-coloured chips
- Versioning — every upload preserves prior versions
- SHA-256 integrity check on every download
- Confidentiality tier: public · internal · confidential · restricted · expiring_link_only
Confidentiality tiers
| Tier | Who can download |
|---|---|
| public | Any authenticated user |
| internal | Firm employees only |
| confidential | Per-doc allow-list (employees + roles) |
| restricted | Document creator + super_admin/partner only |
| expiring_link_only | No direct download · only via time-limited share link |
Share links
Generate time-limited, optionally password-protected, view-count-capped links to send a doc externally:
- Token: 48-char URL-safe base64 of 36 random bytes (~256 bits entropy)
- TTL: configurable, clamped to
m16.share_link_max_ttl_hours(default 72) - Password: optional bcrypt-protected gate before viewer access
- Max-views: optional cap; auto-revokes when reached
- Soft-revoke at any time
- Public viewer at
/share/{token}bypasses auth (token IS the auth)
Watermarking
For confidential downloads, M16 can stamp a per-user watermark. WatermarkService::render():
- PDFs — FPDI page-by-page text overlay with rotation
- Images — GD tiled text overlay
- Token:
{firm_name} • {username} • {timestamp} • {doc_code} - Cached at
storage/documents/{id}/wm/{user_id}-v{n}.{ext} - Cache busts on every new version
Retention auto-purge
cron-m16-retention.php runs nightly:
- Soft-purge documents past
retention_untilwithlegal_hold=0 - Hard-purge documents past
m16.purge_grace_daysafter soft-purge - Trim audit-log rows past
m16.audit_log_retention_days - NEVER purges legal_hold=1 rows
Audit log + admin notifications
vault_download_log captures every file download — who, when, what, IP, MIME, size, success/blocked, severity. Admin notification fires on confidential / alert downloads. Admin viewer at /settings/vault-audit-log with 6 filters + CSV/PDF export.
Bulk download (ZIP)
Two buttons in the Explorer toolbar:
- Download folder — any sub-folder, gated on
m16.download - Backup all — root only, gated on
m16.bypass_confidentiality(super_admin/partner only)
ZIP filenames use real folder names + timestamp. Auto-included _manifest.csv + _README.txt. Permission-blocked files silently skipped (count surfaced).
Open File Vault → Explorer. Drill into Clients → any active client → that client's audit job → that job's workpapers folder → see every PDF + CSV + image generated during fieldwork. One unified view of all the firm's files, regardless of which module created them.
Don't share confidential documents via email attachment — use share links instead. Email attachments leave copies on every mail server in the chain. Share links are revocable + audited; emails aren't.
If an engagement is under regulatory inquiry, mark the docs legal_hold=1. They never auto-purge — even after retention expires. Hold released only by super_admin with documented reason. Use this when OAAA, OTA, or CMA opens a case.