docs: submitter view-all feature flag (read+export every PO, History)
parent
9bcc43f460
commit
8eaf2ed0a0
4 changed files with 46 additions and 4 deletions
|
|
@ -31,6 +31,7 @@ Server-side env on pms1 lives in `~/pms/App/.env`; locally in `App/.env.local`
|
|||
| `FORGEJO_TOKEN` | optional | optional | Token scope `write:issue` |
|
||||
| `GST_SERVICE_URL` | optional | optional | GstService base (default `http://localhost:3003`) |
|
||||
| `NEXT_PUBLIC_INVENTORY_ENABLED` | optional | optional | Inventory flag — **off only when `"false"`** |
|
||||
| `NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED` | optional | optional | Submitter view-all flag — **on only when `"true"`**. Lets TECHNICAL/MANNING read & export every PO and open History |
|
||||
| `NEXT_PUBLIC_ENV_LABEL` | optional | **unset** | When set, shows the non-prod banner (`EnvBanner`). Leave unset in production |
|
||||
| `PORT` | optional | optional | App port (default 3000; staging 3200; autofix 3100) |
|
||||
|
||||
|
|
@ -44,6 +45,12 @@ Server-side env on pms1 lives in `~/pms/App/.env`; locally in `App/.env.local`
|
|||
[File Storage](File-Storage) and [Notifications](Notifications).
|
||||
- **Inventory flag** — `INVENTORY_ENABLED = NEXT_PUBLIC_INVENTORY_ENABLED !==
|
||||
"false"`, i.e. enabled unless explicitly `"false"`.
|
||||
- **Submitter view-all flag** — `SUBMITTER_VIEW_ALL_ENABLED =
|
||||
NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED === "true"`, i.e. **off unless
|
||||
explicitly `"true"`** (opt-in, since it widens read access). When on, submitter
|
||||
roles (TECHNICAL/MANNING) can read & export **every** PO and reach the History
|
||||
page; it grants no approval/payment/edit rights. See
|
||||
[Roles and Permissions](Roles-and-Permissions#feature-flagged-access).
|
||||
- **Env banner** — `EnvBanner` renders nothing when `NEXT_PUBLIC_ENV_LABEL` is
|
||||
unset, so production is unaffected; staging sets it to the
|
||||
"INTERNAL DEV / STAGING - NOT PRODUCTION" string.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ with the detail, or names the code that implements it.
|
|||
centre and by month (Recharts).
|
||||
- **In-app notification bell** with unread badge, plus email at every transition.
|
||||
- **History & export** — filter by date range, cost centre, and **multiple
|
||||
statuses**; CSV/PDF export (up to ~200 rows).
|
||||
statuses**; CSV/PDF export (up to ~200 rows). Open to `export_reports` holders;
|
||||
**submitters get read+export access under the `NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED`
|
||||
flag** (read-only). See [Roles and Permissions](Roles-and-Permissions#feature-flagged-access).
|
||||
- **Mobile experience** — manager/accounts get mobile cards + bottom nav; other
|
||||
roles see a "Desktop Required" overlay.
|
||||
- **PPMS rebrand** — login, sidebar, and title show "PPMS".
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ My Orders /my-orders ← TECH, MANNING, MANAGER, SUPERUSER
|
|||
Approvals /approvals ← MANAGER, SUPERUSER
|
||||
Import PO /po/import ← MANAGER, SUPERUSER, ADMIN
|
||||
Payments /payments ← ACCOUNTS (+ MANAGER, SUPERUSER)
|
||||
History / Export /history ← MANAGER, SUPERUSER, ACCOUNTS, AUDITOR, ADMIN
|
||||
History / Export /history ← MANAGER, SUPERUSER, AUDITOR, ADMIN
|
||||
(+ TECHNICAL, MANNING when SUBMITTER_VIEW_ALL flag on)
|
||||
Vendors /inventory/vendors ← MANAGER, ACCOUNTS, ADMIN
|
||||
Items /inventory/items ← all (read-only catalogue)
|
||||
Cart /inventory/cart ← TECH, MANNING, MANAGER, SUPERUSER
|
||||
|
|
@ -39,7 +40,7 @@ SuperUser Requests /admin/superuser-requests ← ADMIN
|
|||
| `/dashboard` | Dashboard | Role-specific stat cards + charts |
|
||||
| `/my-orders` | My Purchase Orders | Submitter's open & past POs (Closed list scoped by role) |
|
||||
| `/po/new` | New PO | Multi-section form (header, line items, T&C, documents) |
|
||||
| `/po/[id]` | PO Detail | Read view; contextual action buttons by status/role; export |
|
||||
| `/po/[id]` | PO Detail | Read view; contextual action buttons by status/role; export. Own PO always; any PO for `view_all_pos` holders (and submitters when the `SUBMITTER_VIEW_ALL` flag is on) |
|
||||
| `/po/[id]/edit` | Edit PO | DRAFT or EDITS_REQUESTED, owner/SUPERUSER; "Update & Resubmit" |
|
||||
| `/po/[id]/receipt` | Confirm Receipt | PAID_DELIVERED; upload receipt; full or partial |
|
||||
| `/po/import` | Import PO | Upload Pelagia-format Excel → CLOSED |
|
||||
|
|
@ -47,7 +48,7 @@ SuperUser Requests /admin/superuser-requests ← ADMIN
|
|||
| `/approvals/[id]` | Approval Detail | Approve / Approve+Note / Reject / Request Edits / Request Vendor ID; inline line-item edit |
|
||||
| `/payments` | Payment Queue | MGR_APPROVED & SENT_FOR_PAYMENT cards; send/mark paid; partial |
|
||||
| `/payments/history` | Payment History | Completed payments (ACCOUNTS, MANAGER) |
|
||||
| `/history` | History & Export | All POs; filter by date/cost centre/multiple statuses; CSV/PDF |
|
||||
| `/history` | History & Export | All POs; filter by date/cost centre/multiple statuses; CSV/PDF. `export_reports` holders, plus submitters when the `SUBMITTER_VIEW_ALL` flag is on |
|
||||
| `/inventory/items` | Items (read-only) | Catalogue; expand for per-vendor prices; Cheapest/★Closest tags |
|
||||
| `/inventory/items/[id]` | Item Detail | Price comparison, site-distance sort, stock by site |
|
||||
| `/inventory/vendors` | Vendors | List with verified/active badges |
|
||||
|
|
|
|||
|
|
@ -62,6 +62,38 @@ The exact `ROLE_PERMISSIONS` map in `lib/permissions.ts`. ✓ = granted.
|
|||
(`manage_users` plus the catalogue/`manage_*` permissions) and can view/export.
|
||||
- **AUDITOR is strictly read-only** (`view_*`, `export_reports`).
|
||||
|
||||
## Feature-flagged access
|
||||
|
||||
### Submitter view-all (`NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED`)
|
||||
|
||||
By default submitters (**TECHNICAL**, **MANNING**) only see the POs they raised.
|
||||
When `NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED="true"` they gain **read-only**
|
||||
access to every PO:
|
||||
|
||||
- the **History** page (`/history`) and its CSV/PDF report export;
|
||||
- any other user's **PO detail** page (`/po/[id]`);
|
||||
- the **Export PDF / XLSX** buttons on those POs (approved & cancelled POs only,
|
||||
same status gate as everyone else).
|
||||
|
||||
It is a pure read widening — it grants **no** approval, payment, edit, cancel, or
|
||||
admin rights, and does not change what non-submitter roles can do. The flag is
|
||||
**opt-in** (off unless the value is exactly `"true"`).
|
||||
|
||||
Implementation lives in `lib/permissions.ts`:
|
||||
|
||||
| Helper | Meaning |
|
||||
|---|---|
|
||||
| `isSubmitterRole(role)` | `role ∈ {TECHNICAL, MANNING}` |
|
||||
| `submitterCanViewAll(role)` | flag is on **and** `isSubmitterRole(role)` |
|
||||
| `canViewAllPos(role)` | `hasPermission(role, "view_all_pos") \|\| submitterCanViewAll(role)` |
|
||||
|
||||
`canViewAllPos` gates the PO detail page and the per-PO export route;
|
||||
`submitterCanViewAll` is OR'd into the `export_reports` gate on the History page,
|
||||
the report-export route, and the sidebar's History link. When the flag is off,
|
||||
all of these collapse to the prior behaviour (view_all_pos holders only). The
|
||||
`my-orders` "Closed Purchase Orders" list stays personal for submitters
|
||||
regardless — History is the all-POs surface.
|
||||
|
||||
## Business rules layered on top
|
||||
|
||||
Beyond the permission map, server actions and the state machine enforce:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue