Intranet · Files management
A shared document library with folders, where each file or folder is published to a role audience (all / commerce / management) or to specific stores, and can be downloaded by the audiences allowed to see it.
| Area | Intranet |
| Routes | intranet.files · intranet.files.index · intranet.files.new · intranet.files.edit · intranet.files.show |
| Centre modules | intranet |
| Staff levels | root · admin · manager · scmanager · storeManager · commerce |
| Models | commerce · intranet-file |
| UI label | title.header.files / menu.navbar.intranet.file.index |
| Coverage | 5 use cases · 2 happy · 7 failure |
Known issues (1)
How it works
Visibility is the core concept: enums/intranet-file-roles defines three audiences and, for each, which staff levels may assign it — only admin/manager/scmanager can publish to all or management, while commerce is additionally assignable by commerce-level users. canSelectRole reflects this. The model validates conditionally through helper predicates: fileUrl is required only when the entry is not a directory (isNotDirectory), and commerces only when the file targets specific stores (isToCommerces); roles has both a presence rule and an inclusion rule over ['management','commerce','owner','all'] — note owner is accepted here but is not one of the three enum options offered in the UI. Navigation state lives in the explore-files service (changeFolder), and folder creation reports folder.success-created.
Use cases
Why someone opens this (5)
- Publishing the centre’s operating manual to all stores.
- Sharing a confidential document with management only.
- Sending a specific contract to one store.
- Organising documents into folders by year or topic.
- A store downloading the forms it needs.
Path map
flowchart LR F(["Files management"]):::feat F --> H1["Document published to all stores"]:::ok F --> H2["Store-specific document"]:::ok F -.-> X1["Name missing"]:::bad F -.-> X2["No file attached"]:::bad F -.-> X3["No role selected"]:::bad F -.-> X4["Store-targeted file with no stores"]:::bad F -.-> X5["Upload rejected"]:::bad F -.-> X6["Role not assignable by this user"]:::bad F -.-> X7["Download not permitted"]:::bad classDef feat fill:#26688f,stroke:#26688f,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
Document published to all stores
- Manager creates a folder (
folder.success-created) and opens it.- Uploads a file, names it and selects the
allrole.- Validation passes (name and file URL present, role valid).
- Stores see the file in their library and download it.
Store-specific document
- Manager sets the audience to specific stores and selects them.
commercespresence rule is satisfied and the file saves.- Only the selected stores see it.
Failure paths
Name missing
Cause — Blank name.
What happens —
error.file.name.required.
No file attached
Cause — Non-directory entry without a file URL.
What happens —
error.file.url.required(‘File is required’).
No role selected
Cause —
rolesblank or outside the allowed list.What happens —
error.file.roles.required(‘Select a role’).
Store-targeted file with no stores
Cause —
isToCommerceswith an emptycommerces.What happens —
error.file.commerces.required(‘Select at least one shop’).
Upload rejected
Cause — Disallowed type or oversized file.
What happens —
error.file.type.not_allowed,error.file.oversize,error.file.not_allowed.
Role not assignable by this user
Cause — A commerce-level user tries to publish to
allormanagement.What happens —
canSelectRolerestricts the options rather than erroring.
Download not permitted
Cause —
canDownloadfalse for the user’s role on that file.What happens — The download action is hidden.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ Document published to all stores
- ✅ Store-specific document
- ⛔ Name missing
- ⛔ No file attached
- ⛔ No role selected
- ⛔ Store-targeted file with no stores
- ⛔ Upload rejected
- ⛔ Role not assignable by this user
- ⛔ Download not permitted
Implementation
app/controllers/intranet/files/index.jsapp/controllers/intranet/files/new.jsapp/routes/intranet/files/*.jsapp/models/intranet-file.jsapp/abilities/intranet-file.jsapp/enums/intranet-file-roles.jsapp/services/explore-files.jsapp/services/api-files.jsapp/components/add-folder-modal.jsapp/components/nf-file-manager.jsapp/components/file-gallery.js
Translation keys (21)
Key English title.header.filesFiles management menu.navbar.intranet.file.indexFiles file.newNew file file.nameName file.sizeSize file.typeType file.visibilityVisibility file.creator_idCreator file.updated_atDate file.roles.allAll file.roles.commerceStore file.roles.managementManagement folder.success-createdSuccess created new_folderNew folder error.file.name.requiredName can’t be blank error.file.url.requiredFile is required error.file.roles.requiredSelect a role error.file.commerces.requiredSelect at least one shop error.file.type.not_allowedFile type not allowed error.file.oversizeFile exceeds the maximum file size error.file.not_allowedFile not allowed
Related
- Same area — Store sales declaration & month closing · Sales status overview & Yardi export · Sales & audit-log CSV download · Annual sales statement · Intranet communications (threads, confirmations, authorisations) · Communication subtypes · Footfall (flows) & Yardi upload · SAFT-E - IntelliSales import · Utility consumptions
- Shares data with — Customer receipts tab & ticket-stamp generation · Customer loyalty — coupon exchanges · Receipt verification queue · Store list, filters & exports · Store create & edit · Store CSV import · Activity editor (loyalty mechanics, rules & targeting) · Proposal editor (content, coupon, push, AI images)
Generated from doc/feature-inventory.json · id intranet-files · commit 276788ca6