At a Glance
Persona: Audit / Config (Auditor + System Administrator) · Module: good-receive-note · Scenarios: ~29
Categories: Happy Path · Permission · Validation · Edge Case
E2E coverage: maps to501-grn.spec.tsin../carmen-inventory-frontend-e2e/(audit-log and config surfaces are largely planned manual / API-test coverage)
This page captures the test scenarios that the Audit / Config persona — split into two non-transactional sub-personas, Auditor (strictly read-only across the full GRN dataset; runs activity-log queries, three-way-match outcome reviews, lot-recall traces) and System Administrator (configures the lot-number generation format, RBAC roles and approval thresholds, tax / currency / reason codes, and integration endpoints to purchase-order / inventory / Finance / Vendor modules) — directly drives in the good-receive-note module. Neither sub-persona participates in the draft / saved / committed / voided state machine on enum_good_received_note_status: the Auditor's queries return data without writing any state, and the Sysadmin's edits change rules that apply to future GRNs (in-flight draft / saved GRNs retain a snapshot of the rules in force when they were saved; committed GRNs are immutable). The shared rule IDs that this persona's tests exercise are GRN_AUTH_009 (read-only export rights), GRN_AUTH_010 (Receiver ≠ Purchaser segregation enforced at commit, configured in the RBAC panel), GRN_AUTH_011 (workflow-derived authorization at the current workflow_current_stage), GRN_POST_010 (post-commit-void prohibition that gates the Inventory Manager + Finance co-authorisation reversal workflow), GRN_XMOD_001–GRN_XMOD_010 (the integration wiring the Sysadmin maintains across PO / Inventory / Finance / Vendor), and the snapshot rule that protects in-flight GRNs from Sysadmin config changes (described in Section 3 of 03-user-flow-audit-config.md and not assigned a separate rule ID — it lives in the persistence layer's effective-from timestamp). The single common prefix on test IDs is AUD-. Scenarios are grouped into happy paths (Auditor activity-log query and lot-recall trace, Sysadmin lot-number format change and RBAC adjustment, tax / reason-code maintenance, integration cutover), permission (Auditor read-only allow, Auditor write deny, Sysadmin configure allow, Sysadmin no-transact deny, sensitive-field export approval, elevated post-commit co-authorisation), validation (snapshot preservation on in-flight GRNs, export-approval enforcement, deadlock prevention on RBAC changes, lot-number format backwards-compatibility checks, date-range scan limits, tax-code shape rejection, no-op save), and edge cases around in-flight snapshot boundary, rollback of bad config, audit-log gap during lot-recall, query timeout, mass-RBAC activation, and lot-number format collision. Cross-persona handoffs that pivot off this persona (Auditor → Quality / Recall lead, Sysadmin → cross-module change board) live in 04-test-scenarios.md.
| # | Scenario | Pre-condition | Steps | Expected |
|---|---|---|---|---|
| AUD-HP-01 | Auditor — activity-log query by date / vendor | Auditor audit@blueledgers.com logged in with read-only GRN_AUTH_009 scope; tb_good_received_note contains committed and voided rows across 2026-04-01 to 2026-04-30 for vendor VEND-12; audit module enabled. |
1. Open the audit module / GRN activity log scoped to period 2026-04. 2. Apply filter vendor_id = VEND-12 and date range = 2026-04-01..2026-04-30. 3. Observe the chronological feed of workflow_history entries aggregated from tb_good_received_note.workflow_history joined with line-level edits and three-way-match outcomes. 4. Verify all rows are render-only (no edit affordances). |
Filter result returns the matched activity-log entries; the screen surfaces created / saved / committed / voided events with by and at columns, plus three-way-match outcomes (matched / flagged) where applicable; no edit / save / commit / void buttons render; the page emits no write API calls; doc_status of every listed GRN is unchanged. |
| AUD-HP-02 | Auditor — drill into a specific GRN and its audit trail | Auditor logged in; GRN G-A2 exists at doc_status = committed with full workflow_history (created → saved → committed), one credit note CN-A2 booked against it, three-way match flag matched. |
1. From the activity-log feed, click into G-A2. 2. Open the audit-trail panel: created_by_id, saved_by_id (last_action_by_id at save), committed_by_id (with GRN_AUTH_010 segregation evidence: committed_by_id ≠ tb_purchase_order.buyer_id). 3. Walk the linked records: credit note CN-A2, three-way-match outcome, AP-clearing journal reference. 4. Confirm the period-close sign-off that locked the receipt's period. |
Full audit chain renders in read-only mode; segregation-of-duties evidence on the saved → committed transition is visible (the committing user is not the PO transmitter per GRN_AUTH_010); the linked credit-note row and three-way-match outcome surface inline; period-close sign-off timestamp shown; no edit affordances; activity log emits a { action: 'audit_view', user: auditor, target: G-A2 } read-receipt for the audit-of-the-audit trail. |
| AUD-HP-03 | Auditor — lot-recall trace via inventory transaction | Auditor logged in; recall investigation requires tracing affected lot LOT-RECALL-9; lot was introduced by committed GRN G-A3 on 2026-04-12 and partially issued via two stock-issue transactions and one inventory-adjustment write-off. |
1. Open the lot-recall trace tool. 2. Enter lot_no = LOT-RECALL-9. 3. Run trace. The system walks tb_inventory_transaction_detail.lot_no across all tb_inventory_transaction rows. 4. Backward trace: identifies every committed GRN that introduced the lot via tb_good_received_note_detail_item.inventory_transaction_id. 5. Forward trace: identifies every downstream movement (issues, transfers, adjustments, consumption) drawing from the lot. 6. Export the chain-of-custody report. |
Backward trace returns G-A3 (and any other committed GRN carrying LOT-RECALL-9) with receipt date, vendor, qty, expiry; forward trace returns the two stock issues, the inventory-adjustment write-off, and current on-hand qty by location; chain-of-custody report renders both directions in a single artefact suitable for the recall file / external auditor binder; no writes to any GRN, inventory transaction, or adjustment; the trace itself logs an audit-of-audit entry. |
| AUD-HP-04 | Auditor — sensitive-field export with secondary approval | Auditor needs to export an activity-log slice that includes unit costs and vendor payment terms; tenant policy requires Controller or Data Protection Officer co-approval for sensitive-field exports. | 1. Build the activity-log filter (period, vendor, GRN range). 2. Tick the Include unit costs and Include vendor terms checkboxes. 3. Click Request export. 4. System routes the request to Controller controller@blueledgers.com for approval. 5. Controller approves with justification "Q2 external audit binder". 6. System generates the watermarked CSV. |
Export request raised with requested_by = auditor, requested_at = now(), sensitive-field flag = true; Controller receives the approval prompt; on approval, the CSV is generated and watermarked with requester / approver / timestamp per Section 3 decision branch of 03-user-flow-audit-config.md; the export request and the approval are logged on the audit module's own audit trail; the file is downloadable by the Auditor only; plain (non-sensitive) exports would skip this approval per the same decision branch. |
| AUD-HP-05 | Sysadmin — change lot-number format | Sysadmin sysadmin@blueledgers.com logged in with GRN_AUTH_009-elevated config rights; current lot-number format is LOT-{YYYY}{MM}-{SEQ:5}; regulator requires the format to include vendor prefix going forward: {VENDOR_PREFIX}-LOT-{YYYY}{MM}-{SEQ:5}; no GRN at draft or saved currently references the legacy generator output. |
1. Open the GRN configuration console → lot-number format panel. 2. Edit the format-token string to {VENDOR_PREFIX}-LOT-{YYYY}{MM}-{SEQ:5}. 3. Console runs shape validation (token grammar — recognised tokens are {VENDOR_PREFIX}, {YYYY}, {MM}, {SEQ:N}, plus literal characters). 4. Run impact preview — confirms zero in-flight GRNs reference the legacy generator (no migration block). 5. Click Save. |
Format token grammar validates; impact preview returns zero affected draft / saved GRNs; configuration persists with effective_from = now(); previous version retained in the configuration history; new GRN creation immediately picks up the new format; in-flight GRNs (none here) retain the snapshot of the legacy format; configuration-history activity log entry written for Auditor visibility per Section 2.2 step 6 of 03-user-flow-audit-config.md. |
| AUD-HP-06 | Sysadmin — RBAC change on Receiver / Inventory Manager roles | Sysadmin logged in; tenant has added a new business unit and needs to grant the existing Inventory Manager role commit authority on a new location LOC-NEW; no RBAC deadlock with GRN_AUTH_010 segregation (the affected users do not also hold Purchaser rights on the corresponding PO). |
1. Open RBAC panel → role Inventory Manager. 2. Extend action: commit_grn scope to include location_id = LOC-NEW. 3. Run impact preview — lists the 3 users in the role, no active-session conflict, no GRN_AUTH_010 segregation deadlock (none of the 3 users are PO buyers on POs feeding LOC-NEW). 4. Click Save. 5. Confirm warning "3 users hold the affected role — change takes effect on next action attempt; no session revocation required." |
RBAC change persists; the 3 affected users see the new location in their commit scope on their next action (no retroactive cancellation of already-submitted transactions per Section 3 decision branch); segregation-of-duties evaluation at the next saved → committed transition uses the new scope; GRN_AUTH_011 workflow-derived authorization re-binds at the next workflow-stage advance; configuration-history entry logged. |
| AUD-HP-07 | Sysadmin — configure tax codes and reason codes | Sysadmin logged in; tenant onboards a new tax-code VAT-7-EXEMPT (effective 2026-06-01, rate 0%) and a new cancellation reason RECALLED_BY_VENDOR; no in-flight GRN references the placeholder values being introduced. |
1. Open tax / currency / reason codes panel → Tax codes. 2. Add VAT-7-EXEMPT with rate = 0, effective_from = 2026-06-01, effective_to = null. 3. Confirm uniqueness — code does not collide with existing entries. 4. Open Reason codes → Cancellation. 5. Add RECALLED_BY_VENDOR with description and active flag. 6. Click Save on each panel. |
Both codes persist with effective dates; shape validation passes (tax rate 0 ≤ rate ≤ 100, ISO-style code uniqueness, reason-code uniqueness within tenant); new GRNs created from 2026-06-01 onward can select VAT-7-EXEMPT; in-flight GRNs retain their pre-change tax-code snapshot per the snapshot rule; new GRN voids may select RECALLED_BY_VENDOR as the cancellation reason; configuration-history entry written for each. |
| AUD-HP-08 | Sysadmin — integration endpoint cutover (PO / Inventory / Finance / Vendor) | Sysadmin logged in; tenant is cutting over the Finance ERP endpoint from erp-v1 to erp-v2; the cutover plan uses a dual-write window per Section 3 decision branch of 03-user-flow-audit-config.md. |
1. Open Integration panel → Finance endpoint. 2. Add erp-v2 as the secondary endpoint alongside erp-v1. 3. Enable dual-write mode for the AP-accrual fan-out under GRN_POST_006. 4. Run the cutover for 24 hours; the Auditor monitors the reconciliation report for fan-out mismatches per the decision branch. 5. After zero-mismatch confirmation, switch the primary endpoint to erp-v2 and disable erp-v1. 6. Click Save on each step. |
During the dual-write window, every saved → committed transition writes the AP accrual to both erp-v1 and erp-v2; the reconciliation report enumerates fan-out parity row by row; on hard cutover, only erp-v2 receives the fan-out; no GRN-side doc_status changes during the cutover per the decision branch; configuration-history entries log the dual-write enable, the cutover, and the erp-v1 disable; GRN_XMOD_007 integration wiring is unchanged in semantics, only the endpoint identifier changes. |
| # | Scenario | Expected behaviour (allow/deny + reason) |
|---|---|---|
| AUD-PERM-01 | Auditor reads activity log and three-way-match outcomes | Allow read-only. GRN_AUTH_009 grants the Auditor (folded under the View, export reports right) full read access across all doc_status values (draft / saved / committed / voided) and the workflow_history JSON, line-edit history, comment threads, credit-note linkages, and three-way-match outcomes. The audit-module screens render render-only; no Save / Commit / Void / Edit affordances appear; backing API endpoints reject any write call from an Auditor-roled token with "Auditor role is read-only — write actions are not permitted on tb_good_received_note.". Maps to AUD-HP-01..03. |
| AUD-PERM-02 | Auditor attempts to edit a GRN line or post a journal | Deny — role scope. A direct API call to PATCH /grn/{id} or POST /grn/{id}/commit from an Auditor token is rejected at the RBAC layer with 403 Forbidden and reason "Auditor role is not authorised for write actions on the GRN module."; no doc_status transition; no workflow_history append; the rejection itself is logged on the audit-of-audit trail for SOX-equivalent compliance. Mirror of AUD-PERM-01's read-only boundary on the write side. |
| AUD-PERM-03 | Sysadmin configures lot-number format, RBAC, tax / reason codes, integrations | Allow — config scope only. The Sysadmin role holds the configuration panels (lot-number format, RBAC roles and approval thresholds including the GRN_AUTH_010 segregation enforcement, tax / currency / reason codes, integration endpoints to purchase-order / inventory / Finance / Vendor per GRN_XMOD_001–GRN_XMOD_010). The GRN configuration console renders the four panels for the Sysadmin only; Receiver / Inventory Manager / Finance / Purchaser roles do not see the console. Maps to AUD-HP-05..08. |
| AUD-PERM-04 | Sysadmin attempts to create or commit a GRN | Deny — segregation by design. The Sysadmin role is configuration-only; it is not in the tb_good_received_note.user_action.execute set at any workflow_current_stage. An attempt to POST /grn or POST /grn/{id}/commit from a Sysadmin token is rejected by GRN_AUTH_011 (workflow-derived authorization — Sysadmin is not in the stage's execute set) with "Sysadmin role is not authorised to transact on the GRN module — configuration only."; doc_status is unchanged. This is the deliberate separation that lets the Sysadmin maintain GRN_AUTH_010 without being able to bypass it. |
| AUD-PERM-05 | Auditor exports a sensitive-field report — secondary approval required | Allow with secondary approval. Per the Section 3 decision branch of 03-user-flow-audit-config.md, exports that include unit costs, vendor payment terms, or PII require Controller or DPO co-approval before the file is generated. The Export button is enabled, but on the sensitive-field option, the request enters an approval-pending state; without approval, no file is generated and no data is exfiltrated. Maps to AUD-HP-04. Plain activity-log exports (status transitions, line counts, anonymised user roles) bypass this approval and download immediately. |
| AUD-PERM-06 | Sysadmin elevated post-commit void attempt — forbidden per GRN_POST_010 |
Deny — committed is terminal; reversal requires co-authorisation. A Sysadmin (or Inventory Manager) attempt to void a committed GRN is rejected outright per GRN_POST_010 — voided is pre-commit only. Server returns "Cannot void a committed GRN; post-commit reversal requires Inventory Manager + Finance co-authorisation via tb_credit_note or compensating inventory adjustment."; doc_status stays committed; the Sysadmin's role is to ensure the RBAC layer correctly gates the co-authorisation (Inventory Manager + Finance signatures recorded on the credit-note's workflow_history) — the Sysadmin does not execute the reversal. Maps to the elevated-void decision branch in Section 3 of 03-user-flow-audit-config.md. |
| AUD-PERM-07 | Non-audit / non-sysadmin user accesses the audit workspace | Deny. A Receiver / Purchaser / Finance user navigating to /audit/grn-activity-log or /admin/grn-config receives 403 Forbidden with reason "Audit module access is restricted to Auditor role; Configuration console access is restricted to Sysadmin role."; the page redirects to the user's role-appropriate landing screen. Maps to TC-GRN-010003-style permission denial pattern in the canonical Playwright spec. |
| # | Scenario | Trigger | Expected error |
|---|---|---|---|
| AUD-VAL-01 | Snapshot preservation on in-flight GRN when Sysadmin changes tax code | GRN G-AV1 at doc_status = saved references tax code VAT-7 with rate 7%; Sysadmin attempts to retire VAT-7 (mark inactive) via the configuration console; impact preview at step 4 of Section 2.2 of 03-user-flow-audit-config.md detects 1 in-flight reference. |
Block change at impact preview. Console returns "Cannot retire tax code VAT-7 — 1 in-flight GRN at doc_status saved references it. Resolution: (a) wait for in-flight to commit or void; (b) bulk-recompute by re-opening and re-saving against new config; (c) soft-deprecate (mark inactive, keep readable on existing GRNs)."; VAT-7 retains its active state; G-AV1 continues to read its tax-code snapshot unchanged; the change is escalated per Section 4 of 03-user-flow-audit-config.md. On bulk-recompute (option b), each affected GRN re-reads the new tax-code list at re-save time; on soft-deprecate (option c), VAT-7 is marked inactive but G-AV1's snapshot still points to it readably. |
| AUD-VAL-02 | Export-approval enforcement on sensitive-field export | Auditor builds a filter that includes unit costs and clicks Export without going through the Controller co-approval route; server-side guard rechecks approval state. | Reject the export. Server returns "Sensitive-field export requires secondary approval from Controller or DPO; no approval found for this request."; no file is generated; no bytes flow to the Auditor; the export-attempt event is logged on the audit-of-audit trail with { action: 'export_denied', reason: 'no_secondary_approval', requested_by: auditor }; the Auditor must raise the approval request explicitly per AUD-HP-04 before re-attempting. |
| AUD-VAL-03 | Deadlock prevention on RBAC change | Sysadmin attempts to revoke the commit_grn action from the Inventory Manager role at a moment when there is no other role holding commit_grn; impact preview detects that this would leave the tenant with zero users able to advance saved → committed. |
Block change at impact preview. Console returns "RBAC change would leave 0 users authorised to commit GRNs at the saved → committed transition; this would deadlock the GRN workflow at the saved stage. Add commit_grn to another role first, or grant the action to specific named users, before revoking."; the change is not persisted; the existing RBAC scope remains; the Sysadmin re-plans the change to preserve at least one role with commit_grn per GRN_AUTH_011 workflow integrity. |
| AUD-VAL-04 | Lot-number format change without backwards compatibility for in-flight saved GRNs |
GRN G-AV4 at doc_status = saved carries lot data generated with the legacy format LOT-{YYYY}{MM}-{SEQ:5}; Sysadmin attempts a hard cutover to a non-backwards-compatible format that would invalidate parsing of G-AV4's existing lot strings on any subsequent re-save or activity-log render. |
Soft-warn at impact preview; allow with explicit acknowledgement. Console returns "New lot-number format is not backwards-compatible with 1 in-flight saved GRN's existing lot strings. Acknowledge to proceed — existing lot strings will remain on G-AV4 as literal text (read-only), but the audit-log parser will display them unformatted. New GRNs will use the new format." per the snapshot rule (existing strings are preserved verbatim, the parser handles them as literals). The Sysadmin acknowledges; G-AV4 retains its legacy lot strings unchanged (no migration); new GRNs use the new format. If the Sysadmin instead chose to bulk-recompute (option b in AUD-VAL-01), G-AV4 would re-read the format at the next save — which is rejected here because the format is non-backwards-compatible. |
| AUD-VAL-05 | Date-range scan limit on Auditor activity-log query | Auditor enters a date range spanning 18 months on the activity-log filter; tenant query-cost guard caps single-query scans at 12 months to protect production database performance. | Reject the query. Server returns "Audit-log query date range (548 days) exceeds tenant scan limit (365 days); please narrow the range or run multiple consecutive queries."; no rows returned; no partial result delivered; the Auditor narrows the range and re-queries per the cap. The cap is configurable in the tenant config panel (Sysadmin-owned) per Section 2.2 step 2 of 03-user-flow-audit-config.md. |
| AUD-VAL-06 | Invalid tax code rejected at save | Sysadmin attempts to save a new tax code with rate = 150 (out-of-range) or with a duplicate code already in the active list. |
Reject at save. For out-of-range rate: "Tax rate must be in the inclusive range 0..100; received 150."; for duplicate: "Tax code VAT-7 already exists in the tenant configuration; codes must be unique."; no row persisted; no configuration-history entry; the form holds the entered values for correction. Same pattern applies to currency-code shape (ISO-4217 4-letter limit) and reason-code uniqueness. |
| AUD-VAL-07 | No-op save rejected | Sysadmin opens the configuration console, clicks Save on the lot-number format panel without changing any field. | Reject as no-op. Console returns "No changes detected; save not required."; no effective_from timestamp written; no configuration-history entry created (no-op saves would otherwise pollute the audit trail and create noise in the Auditor's review of configuration changes); the previous configuration is unchanged. Same pattern applies to RBAC, tax / reason codes, and integration panels. |
| AUD-VAL-08 | Sysadmin attempts to retire a reason code that is referenced by voided GRNs |
GRN G-AV8 at doc_status = voided carries void_reason_code = SUPPLIER_ERROR; Sysadmin attempts to delete (not soft-deprecate) SUPPLIER_ERROR. |
Reject hard delete. Console returns "Cannot hard-delete reason code SUPPLIER_ERROR — 1 voided GRN historically references it. Reason codes referenced by any historical GRN (including voided) cannot be hard-deleted; use soft-deprecate to mark inactive while preserving audit-trail integrity."; the reason code remains; soft-deprecate is offered as the path forward; configuration-history entry not written (no change applied). Preserves audit-trail integrity per the Section 3 decision branch — committed and voided GRNs are immutable and their referenced configuration must remain readable. |
| # | Scenario | Condition | Expected |
|---|---|---|---|
| AUD-EDGE-01 | In-flight snapshot boundary — Sysadmin save during a Receiver's open saved GRN |
Receiver has GRN G-AE1 open at doc_status = saved at time T; Sysadmin saves a new tax-code rate at T + 100ms; Receiver clicks Commit at T + 1s. |
In-flight retains snapshot per the snapshot rule. G-AE1's tax-code snapshot captured at save (time T - X) is preserved through commit; the commit reads G-AE1's frozen snapshot, not the new tenant-level rate; doc_status advances saved → committed at the snapshot rate; the new rate applies to GRNs created at T + 100ms or later. Mirrors the snapshot-rule decision branch of Section 3 of 03-user-flow-audit-config.md. |
| AUD-EDGE-02 | Rollback of bad config change after partial in-flight effect | Sysadmin saves a bad integration endpoint config at T that breaks the GRN_POST_006 AP-accrual fan-out for 2 minutes (no in-flight GRNs were saved → committed during the broken window — caught by monitoring at T + 90s); Sysadmin rolls back at T + 2min. |
Restore prior config from configuration history; no in-flight effect to undo. The configuration history retains the prior version per Section 2.2 step 5 of 03-user-flow-audit-config.md; Sysadmin clicks Roll back to previous version; the prior config becomes active with effective_from = T + 2min; new GRNs commit cleanly under the restored endpoint; the configuration-history shows two entries (the bad save at T, the rollback at T + 2min) for Auditor review. Had any GRN committed during the broken window with a fan-out failure, the recovery path would route to AP-investigation queue and the GRN's workflow_history would carry the failure event — but no GRN committed in this case. |
| AUD-EDGE-03 | Lot-recall trace with audit-log gap | Auditor runs a lot-recall trace on LOT-GAP-7; the underlying tb_inventory_transaction_detail rows include one row where the originating GRN's workflow_history is missing the committed entry (data-integrity gap from a historical migration); the inventory transaction itself is present. |
Surface the gap in the trace report. The lot trace returns the chain of custody via tb_inventory_transaction_detail.lot_no → tb_inventory_transaction → tb_good_received_note_detail_item.inventory_transaction_id → tb_good_received_note.id correctly; the audit-log panel on the affected GRN flags "workflow_history missing the committed entry — inventory side is consistent (transaction present), audit-log side has a gap; recommend forensics."; the chain-of-custody export includes the gap flag for the external auditor; no auto-repair, no auto-fill of the missing entry (preserves forensic integrity). |
| AUD-EDGE-04 | Auditor query timeout on huge dataset | Auditor enters a filter that, even within the date-range cap (AUD-VAL-05), returns a candidate-row count beyond the tenant query-cost budget (e.g. 500K GRN events for a 12-month, all-vendor scan). | Server timeout with graceful degradation. Backend cancels the query at the configured timeout (e.g. 30s) and returns "Audit-log query exceeded compute budget; partial result up to T+30s returned. Narrow the filter (add vendor / PO / GRN-range) or request an offline export through Sysadmin."; a partial result up to the timeout is delivered with a truncated = true marker; full-dataset extraction routes to an offline export job (Sysadmin-coordinated, runs on read-replica off-peak) per AUD-EDGE-04 escalation path. |
| AUD-EDGE-05 | Mass-RBAC activation — 200 new users granted Receiver role at once | Tenant onboards a new business unit and Sysadmin bulk-grants the Receiving Clerk role to 200 new users via a CSV import on the RBAC panel. |
Allow with batched effective-from; activity-log entry per user. The import processes the 200 users in a single transaction; impact preview at step 4 confirms no segregation-of-duties conflict (none of the 200 are also Purchasers on any active PO); on save, all 200 users see Receiver scope at their next action attempt per Section 3 decision branch — no retroactive transaction cancellation; configuration-history entry written per user (200 entries) for Auditor visibility; total transaction time under the tenant's bulk-RBAC budget; if any single user fails a conflict check, the entire batch rolls back atomically to preserve the all-or-nothing invariant. |
| AUD-EDGE-06 | Lot-number format collision after Sysadmin change | Sysadmin saves a new lot-number format that, on the next Receiver-issued draft → saved transition, computes to a string that collides with an existing lot string already present on tb_inventory_transaction_detail.lot_no (e.g. sequence collision due to a reset). |
Reject at GRN save with format-collision error. The Receiver's save attempt fails at GRN_VAL_* lot-uniqueness check (lot strings must be unique within (vendor_id, product_id, expiry_date)); server returns "Lot number LOT-2026-04-00123 collides with an existing lot for the same vendor / product / expiry; sequence has reset or format generated a duplicate. Sysadmin must adjust the sequence anchor or the format token."; the Sysadmin reviews the configuration history, identifies the bad sequence anchor, corrects it via the lot-number format panel, and the next Receiver save succeeds; no inventory write occurs from the failed save. |
GRN_AUTH_009 (Procurement Officer / AP Clerk view / export read-only baseline that the Auditor inherits), GRN_AUTH_010 (Receiver ≠ Purchaser segregation enforced at commit, configured by Sysadmin in the RBAC panel), GRN_AUTH_011 (workflow-derived authorization via tb_good_received_note.user_action.execute at workflow_current_stage) — plus Section 6 Cross-Module Rules GRN_XMOD_001–GRN_XMOD_010 (the PO / Inventory / Finance / Vendor integration wiring the Sysadmin maintains), and GRN_POST_010 (the post-commit-void prohibition — committed is terminal; reversal requires Inventory Manager + Finance co-authorisation via tb_credit_note or compensating inventory adjustment, configured by the Sysadmin).draft → saved → committed transitions write the workflow_history entries the Auditor reads, and whose lot-number entry at save follows the format the Sysadmin maintains (AUD-HP-05, AUD-EDGE-06); Receiver test scenarios live at 04-test-scenarios-receiver.md.GRN_AUTH_010 / PO_AUTH_010 segregation rule is configured by the Sysadmin in the RBAC panel (AUD-HP-06). Purchaser test scenarios live at 04-test-scenarios-purchaser.md.matched / flagged), AP-clearing journals (Dr GRN Clearing / Cr AP-Trade on success), credit-note bookings, and period-close sign-offs feed the Auditor's reconciliation and period-close reviews (AUD-HP-02); the GL account map, tax-code list, and match-tolerance configuration the Finance flow depends on are configured by the Sysadmin (AUD-HP-07, AUD-HP-08). Finance test scenarios live at 04-test-scenarios-finance.md.tb_good_received_note.workflow_history (the JSON activity-log array the Auditor reads in AUD-HP-01..02), tb_inventory_transaction_detail.lot_no (the lot-trace linkage in AUD-HP-03 and AUD-EDGE-03), and the configuration tables the Sysadmin maintains (tax code, currency, reason code, RBAC role definitions referenced under tb_good_received_note.user_action.execute).GRN_XMOD_001–GRN_XMOD_003) and the PO_AUTH_010 mirror of the segregation-of-duties rule.committed GRNs through tb_inventory_transaction rows to current on-hand and downstream issues / transfers / adjustments / consumption (AUD-HP-03); GRN_XMOD_004–GRN_XMOD_006 integration endpoints are Sysadmin-maintained.../carmen-inventory-frontend-e2e/tests/501-grn.spec.ts — canonical Playwright spec for the GRN module. Audit / Config-relevant patterns: TC-GRN-010003 (View GRN List with Insufficient Permissions — requestor@blueledgers.com fixture as the deny pattern AUD-PERM-07 inherits), TC-GRN-010001 (List view authentication baseline — read-only inheritance pattern for AUD-PERM-01), and the broader permission-denial pattern (requestor@blueledgers.com vs purchase@blueledgers.com fixtures) that the Sysadmin no-transact deny (AUD-PERM-04) extends. Lot-recall and configuration-console flows are not exercised in 501-grn.spec.ts directly — they live in admin / audit-module e2e suites outside the GRN module spec; the cross-link is for the permission boundary patterns the GRN module e2e exercises.