# ASN Workflow — Product Requirements

**Domain:** logistics  ·  **Type:** web  ·  **Generated:** 2026-05-07T03:32:14+00:00  ·  **Run:** `1778124586772-pdf`  ·  **Spec version:** `0.2.0`

## Goal

This application supports core operations in logistics. It exposes the entities, workflows, and user roles documented below.

## Glossary

_30 domain terms (auto-extracted from CIR; review for accuracy)._

| Term | Kind | Definition | Source |
|------|------|------------|--------|
| `AdvancedShipmentNotice` | entity | An ASN sent by a supplier announcing inbound goods. | ENT-001 |
| `Advanced Shipment Notice` | entity | An ASN sent by a supplier announcing inbound goods. | ENT-001 |
| `AsnLineItem` | entity | Line items within an ASN. | ENT-002 |
| `Asn Line Item` | entity | Line items within an ASN. | ENT-002 |
| `DoorMaster` | entity | Master table for door assignments. | ENT-003 |
| `Door Master` | entity | Master table for door assignments. | ENT-003 |
| `ReceivingConfirmationReport` | entity | Document generated after ASN closure. | ENT-004 |
| `Receiving Confirmation Report` | entity | Document generated after ASN closure. | ENT-004 |
| `Supplier` | entity | Entity representing suppliers providing goods. | ENT-005 |
| `Order` | entity | Represents a purchase order used in ASN creation. | ENT-006 |
| `PurchaseOrder` | entity | Alias for `Order`. Represents a purchase order used in ASN creation. | ENT-006 |
| `warehouse_user` | role | User responsible for managing ASNs and processing shipments. |  |
| `WarehouseOperator` | role | Handles the creation and processing of ASNs. |  |
| `create_asn` | action | User action on `Create ASN (Standard)`: Opens ASN creation modal |  |
| `create_local_asn` | action | User action on `Create Local ASN`: Opens local ASN creation modal |  |
| `reserve_slots` | action | User action on `Unreserved ASN List`: Reserves storage slots for SKUs |  |
| `print_rcr` | action | User action on `Closed ASN View`: Prints Receiving Confirmation Report |  |
| `assign_door` | action | User action on `At Door View`: Assigns a door for unloading |  |
| `mark_asn_completed` | action | User action on `Completion`: Marks ASN as completed and moves to Closed state |  |
| `ASN Expanded (Multiple SKUs)` | screen | UI screen: ASN Expanded (Multiple SK Us). |  |
| `At Door View` | screen | UI screen: At Door View. |  |
| `Closed ASN View` | screen | UI screen: Closed ASN View. |  |
| `Completion` | screen | UI screen: Completion. |  |
| `Create ASN (Standard)` | screen | UI screen: Create ASN (Standard). |  |
| `Create Local ASN` | screen | UI screen: Create Local ASN. |  |
| `RCR Print Preview` | screen | UI screen: RCR Print Preview. |  |
| `Reserved ASN View` | screen | UI screen: Reserved ASN View. |  |
| `Unreserved ASN List` | screen | UI screen: Unreserved ASN List. |  |
| `ASN` | acronym | Acronym `ASN` referenced in domain content. (Definition unresolved — see source CIR.) |  |
| `RCR` | acronym | Acronym `RCR` referenced in domain content. (Definition unresolved — see source CIR.) |  |

## Entities

_6 entities defined._

### `ENT-001` — AdvancedShipmentNotice
_table:_ `advanced_shipment_notice`  ·  conf 0.98

An ASN sent by a supplier announcing inbound goods.

| Field | Type | Required | Unique | PK | Source |
|-------|------|----------|--------|-----|--------|
| `id` | uuid | ✓ | ✓ | ✓ | synthesized |
| `asnId` | string | ✓ | ✓ |  | vision |
| `supplierId` | uuid | ✓ |  |  | vision |
| `status` | enum | ✓ |  |  | vision |
| `createdAt` | timestamptz | ✓ |  |  | vision |
| `poNumber` | string | ✓ |  |  | vision |
| `updatedAt` | timestamptz | ✓ |  |  | synthesized |

**Relationships:**
- many-to-one → `Supplier` (ENT-005) (FK: `supplierId`, cascade: restrict)
- many-to-one → `PurchaseOrder` (FK: `poNumber`, cascade: restrict)

### `ENT-002` — AsnLineItem
_table:_ `asn_line_item`  ·  conf 0.98

Line items within an ASN.

| Field | Type | Required | Unique | PK | Source |
|-------|------|----------|--------|-----|--------|
| `id` | uuid | ✓ | ✓ | ✓ | synthesized |
| `poNumber` | string | ✓ |  |  | vision |
| `upcNumber` | string | ✓ |  |  | vision |
| `sku` | string | ✓ |  |  | vision |
| `quantity` | integer | ✓ |  |  | vision |
| `createdAt` | timestamptz | ✓ |  |  | synthesized |
| `updatedAt` | timestamptz | ✓ |  |  | synthesized |

**Relationships:**
- many-to-one → `AdvancedShipmentNotice` (ENT-001) (FK: `asnId`, cascade: restrict)

### `ENT-003` — DoorMaster
_table:_ `door_master`  ·  conf 0.98

Master table for door assignments.

| Field | Type | Required | Unique | PK | Source |
|-------|------|----------|--------|-----|--------|
| `id` | uuid | ✓ | ✓ | ✓ | synthesized |
| `doorNumber` | string | ✓ | ✓ |  | vision |

### `ENT-004` — ReceivingConfirmationReport
_table:_ `receiving_confirmation_report`  ·  conf 0.98

Document generated after ASN closure.

| Field | Type | Required | Unique | PK | Source |
|-------|------|----------|--------|-----|--------|
| `id` | uuid | ✓ | ✓ | ✓ | synthesized |
| `rcrId` | string | ✓ | ✓ |  | vision |
| `skuDetails` | json | ✓ |  |  | vision |
| `vendorDetails` | json | ✓ |  |  | vision |
| `asnId` | string | ✓ |  |  | vision |
| `createdAt` | timestamptz | ✓ |  |  | synthesized |
| `updatedAt` | timestamptz | ✓ |  |  | synthesized |

**Relationships:**
- one-to-one → `AdvancedShipmentNotice` (ENT-001) (FK: `asnId`, cascade: restrict)

### `ENT-005` — Supplier
_table:_ `supplier`  ·  conf 0.85

Entity representing suppliers providing goods.

| Field | Type | Required | Unique | PK | Source |
|-------|------|----------|--------|-----|--------|
| `id` | uuid | ✓ | ✓ | ✓ | synthesized |
| `supplierId` | uuid | ✓ | ✓ |  | vision |
| `supplierName` | string | ✓ |  |  | vision |
| `createdAt` | timestamptz | ✓ |  |  | synthesized |
| `updatedAt` | timestamptz | ✓ |  |  | synthesized |

### `ENT-006` — Order
_table:_ `order`  ·  conf 0.98  ·  aliases: PurchaseOrder

Represents a purchase order used in ASN creation.

| Field | Type | Required | Unique | PK | Source |
|-------|------|----------|--------|-----|--------|
| `id` | uuid | ✓ | ✓ | ✓ | synthesized |
| `poNumber` | string | ✓ | ✓ |  | vision |
| `vendorId` | uuid | ✓ |  |  | vision |
| `createdAt` | timestamptz | ✓ |  |  | synthesized |
| `updatedAt` | timestamptz | ✓ |  |  | synthesized |

## Entity-Relationship Diagram

```mermaid
erDiagram
  AdvancedShipmentNotice {
    uuid id PK,UK
    string asnId UK
    uuid supplierId
    enum status
    timestamptz createdAt
    string poNumber
    timestamptz updatedAt
  }
  AsnLineItem {
    uuid id PK,UK
    string poNumber
    string upcNumber
    string sku
    integer quantity
    timestamptz createdAt
    timestamptz updatedAt
  }
  DoorMaster {
    uuid id PK,UK
    string doorNumber UK
  }
  ReceivingConfirmationReport {
    uuid id PK,UK
    string rcrId UK
    json skuDetails
    json vendorDetails
    string asnId
    timestamptz createdAt
    timestamptz updatedAt
  }
  Supplier {
    uuid id PK,UK
    uuid supplierId UK
    string supplierName
    timestamptz createdAt
    timestamptz updatedAt
  }
  Order {
    uuid id PK,UK
    string poNumber UK
    uuid vendorId
    timestamptz createdAt
    timestamptz updatedAt
  }
  AdvancedShipmentNotice }o--|| Supplier : "supplierId"
  AdvancedShipmentNotice }o--|| PurchaseOrder : "poNumber"
  AsnLineItem }o--|| AdvancedShipmentNotice : "asnId"
  ReceivingConfirmationReport ||--|| AdvancedShipmentNotice : "asnId"
```

## Workflows

### `WF-001` — asn_lifecycle
**States:** Create → Unreserved → Reserved → At Door → Closed → RCR
**Initial state:** `Create`

**Transitions:**
- `Create` → `Unreserved`  —  trigger: ASN creation submitted
- `Unreserved` → `Reserved`  —  trigger: all SKUs reserved  (when: all_skus_reserved)
- `Reserved` → `At Door`  —  trigger: Door assignment from Door Master
- `At Door` → `Closed`  —  trigger: Mark Completed button (warehouse user)  (when: all_skus_processed)
- `Closed` → `RCR`  —  trigger: Print RCR button

```mermaid
stateDiagram-v2
  %% asn_lifecycle
  [*] --> Create
  Create --> Unreserved: ASN creation submitted
  Unreserved --> Reserved: all SKUs reserved [all_skus_reserved]
  Reserved --> At_Door: Door assignment from Door Master
  At_Door --> Closed: Mark Completed button (warehouse user) [all_skus_processed]
  Closed --> RCR: Print RCR button
```

### `WF-002` — advancedshipmentnotice_lifecycle — bound to `AdvancedShipmentNotice` (ENT-001)
**States:** unreserved → reserved → at door → closed
**Initial state:** `unreserved`

> [NEEDS CLARIFICATION] Workflow has no transitions defined.

```mermaid
stateDiagram-v2
  %% advancedshipmentnotice_lifecycle
  [*] --> unreserved
```

## Roles + Permissions

### warehouse_user
User responsible for managing ASNs and processing shipments.

**Visible permissions:**
- create_asn
- reserve_slots
- assign_door
- mark_asn_completed
- print_rcr

### WarehouseOperator
Handles the creation and processing of ASNs.

**Visible permissions:**
- create_asn
- reserve_slots
- assign_door
- mark_asn_completed
- print_rcr

## User Actions

| Action | Trigger | Screen | Expected outcome |
|--------|---------|--------|------------------|
| `create_asn` | Create ASN button | Create ASN (Standard) | Opens ASN creation modal |
| `create_local_asn` | Create Local ASN button | Create Local ASN | Opens local ASN creation modal |
| `reserve_slots` | Reserve Slots button | Unreserved ASN List | Reserves storage slots for SKUs |
| `print_rcr` | Print RCR button | Closed ASN View | Prints Receiving Confirmation Report |
| `assign_door` | Assign Door button | At Door View | Assigns a door for unloading |
| `mark_asn_completed` | Mark Completed button | Completion | Marks ASN as completed and moves to Closed state |

## Business Rules + Validations

_Each rule rendered in EARS notation (Easy Approach to Requirements Syntax)._

| ID | Rule | EARS pattern | Applies to | EARS sentence |
|----|------|--------------|------------|---------------|
| `RULE-001` | `min_one_line_item` | ubiquitous | AsnLineItem | The system shall ensure: An ASN must contain at least one line item before it can be submitted. |
| `RULE-002` | `all_skus_reserved` | ubiquitous | AdvancedShipmentNotice | The system shall ensure: All SKUs must be reserved before ASN can move to Reserved state. |
| `RULE-003` | `all_skus_processed` | ubiquitous | AdvancedShipmentNotice | The system shall ensure: All SKUs must be processed before ASN can be marked as Completed. |
| `RULE-004` | `door_assignment_required` | ubiquitous | AdvancedShipmentNotice | The system shall ensure: A door must be assigned before ASN can move to 'At Door' state. |
| `RULE-005` | `rcr_print_after_closure` | event_driven | ReceivingConfirmationReport | When the relevant event occurs, the system shall RCR can only be printed after ASN is closed. |
| `RULE-006` | `slot_assignment_required` | ubiquitous | ASN | The system shall ensure: A slot must be assigned before ASN can move to Reserved state. |

## Non-Functional Requirements

_Keyed by **ISO/IEC 25010:2023** quality model. Defaults provided for app-type `web`. Refine in Step 5/6 as needed._

### Functional Suitability
- Functional completeness: every CIR entity has CRUD operations available to its bound role(s) (or read-only if that role lacks write permissions).
- Functional correctness: outputs match acceptance criteria specified in PRD.

### Performance Efficiency
- p95 page load < 2.5s on 4G
- p95 API response < 500ms for read endpoints
- Core Web Vitals: LCP < 2.5s, FID < 100ms, CLS < 0.1

### Compatibility
- Last 2 major versions of Chrome, Safari, Firefox, Edge

### Interaction Capability
- WCAG 2.2 Level AA conformance
- Keyboard-only navigation supported on all interactive elements
- Screen-reader landmarks and ARIA labels on all forms
- Mobile-responsive at ≥360px viewport width

### Reliability
- Target availability ≥ 99.5% (43h downtime/year)
- Graceful degradation for read-only mode if write path fails

### Security
- TLS 1.2+ enforced; HSTS preload-eligible
- OWASP Top 10 mitigations: input validation, parameterized queries, CSRF tokens
- Session cookies: HttpOnly + Secure + SameSite=Lax
- Sensitive PII fields encrypted at rest (AES-256) and in transit

### Maintainability
- Test coverage ≥ 70% on business logic modules
- Module boundaries follow CIR entity grouping

### Flexibility
- Schema additions (new fields, new entities) do not break existing routes.
- i18n-ready: user-facing strings extracted into resource files.

### Safety
- Destructive operations require confirmation and produce audit-log entries.

## User Stories

_6 actions × 2 role(s) → 6 stories (after multi-role expansion: +5 candidates, −5 collapsed). Auto-derived; refine in Step 5+ as needed._

- **`US-001`** (Priority: P1) — As a **warehouse_user** (also: WarehouseOperator), I can `create_asn` so that Opens ASN creation modal.
  - screen: `Create ASN (Standard)` · trigger: `Create ASN button`
  - **Why P1:** Entry-point action — without it, downstream workflows cannot proceed.
  - **Independent test:** As `warehouse_user`, perform `create_asn` on `Create ASN (Standard)` → verify: Opens ASN creation modal.
  - **Linked:** workflow: `WF-002` · rules: `RULE-006`
- **`US-002`** (Priority: P1) — As a **warehouse_user**, I can `create_local_asn` so that Opens local ASN creation modal.
  - screen: `Create Local ASN` · trigger: `Create Local ASN button`
  - **Why P1:** Entry-point action — without it, downstream workflows cannot proceed.
  - **Independent test:** As `warehouse_user`, perform `create_local_asn` on `Create Local ASN` → verify: Opens local ASN creation modal.
  - **Linked:** workflow: `WF-002` · rules: `RULE-006`
- **`US-003`** (Priority: P2) — As a **warehouse_user** (also: WarehouseOperator), I can `reserve_slots` so that Reserves storage slots for SKUs.
  - screen: `Unreserved ASN List` · trigger: `Reserve Slots button`
  - **Why P2:** Mid-flow action — required for full workflow but not the entry point.
  - **Independent test:** As `warehouse_user`, perform `reserve_slots` on `Unreserved ASN List` → verify: Reserves storage slots for SKUs.
  - **Linked:** workflow: `WF-002` · rules: `RULE-006`
- **`US-004`** (Priority: P3) — As a **warehouse_user** (also: WarehouseOperator), I can `print_rcr` so that Prints Receiving Confirmation Report.
  - screen: `Closed ASN View` · trigger: `Print RCR button`
  - **Why P3:** Auxiliary action — useful but not required for MVP slice.
  - **Independent test:** As `warehouse_user`, perform `print_rcr` on `Closed ASN View` → verify: Prints Receiving Confirmation Report.
  - **Linked:** workflow: `WF-002` · rules: `RULE-005`, `RULE-006`
- **`US-005`** (Priority: P2) — As a **warehouse_user** (also: WarehouseOperator), I can `assign_door` so that Assigns a door for unloading.
  - screen: `At Door View` · trigger: `Assign Door button`
  - **Why P2:** Mid-flow action — required for full workflow but not the entry point.
  - **Independent test:** As `warehouse_user`, perform `assign_door` on `At Door View` → verify: Assigns a door for unloading.
  - **Linked:** workflow: `WF-002` · rules: `RULE-004`
- **`US-006`** (Priority: P2) — As a **warehouse_user** (also: WarehouseOperator), I can `mark_asn_completed` so that Marks ASN as completed and moves to Closed state.
  - screen: `Completion` · trigger: `Mark Completed button`
  - **Why P2:** Mid-flow action — required for full workflow but not the entry point.
  - **Independent test:** As `warehouse_user`, perform `mark_asn_completed` on `Completion` → verify: Marks ASN as completed and moves to Closed state.
  - **Linked:** workflow: `WF-002`

## Out of Scope / Flagged for Review

### Open Questions [NEEDS CLARIFICATION]

| ID | Severity | Category | Affected | Description |
|----|----------|----------|----------|-------------|
| `OQ-001` | info | action_no_role | `create_asn` | Action `create_asn` has no `_implied_role` despite 2 roles available. Assigning to first role. |
| `OQ-002` | info | action_no_role | `create_local_asn` | Action `create_local_asn` has no `_implied_role` despite 2 roles available. Assigning to first role. |
| `OQ-003` | info | action_no_role | `reserve_slots` | Action `reserve_slots` has no `_implied_role` despite 2 roles available. Assigning to first role. |
| `OQ-004` | info | action_no_role | `print_rcr` | Action `print_rcr` has no `_implied_role` despite 2 roles available. Assigning to first role. |
| `OQ-005` | info | action_no_role | `assign_door` | Action `assign_door` has no `_implied_role` despite 2 roles available. Assigning to first role. |
| `OQ-006` | info | action_no_role | `mark_asn_completed` | Action `mark_asn_completed` has no `_implied_role` despite 2 roles available. Assigning to first role. |
| `OQ-007` | info | workflow_unbound | `WF-001` | Workflow `asn_lifecycle` has no `bound_entity`. Step 5 cannot generate state column. |
| `OQ-008` | warn | workflow_empty | `WF-002` | Workflow `advancedshipmentnotice_lifecycle` has no transitions. State machine codegen impossible. |

## Acceptance Criteria

_Executable Gherkin scenarios are emitted to `acceptance.feature` alongside this PRD. The list below is the human-readable index._

**From business rules (EARS notation):**
- `AC-RULE-001-1` (ubiquitous): The system shall ensure: An ASN must contain at least one line item before it can be submitted.
- `AC-RULE-002-1` (ubiquitous): The system shall ensure: All SKUs must be reserved before ASN can move to Reserved state.
- `AC-RULE-003-1` (ubiquitous): The system shall ensure: All SKUs must be processed before ASN can be marked as Completed.
- `AC-RULE-004-1` (ubiquitous): The system shall ensure: A door must be assigned before ASN can move to 'At Door' state.
- `AC-RULE-005-1` (event_driven): When the relevant event occurs, the system shall RCR can only be printed after ASN is closed.
- `AC-RULE-006-1` (ubiquitous): The system shall ensure: A slot must be assigned before ASN can move to Reserved state.

**From workflow transitions (EARS event-driven):**
- `AC-WF-001-1`: When `ASN creation submitted` occurs while `asn_lifecycle` is in state `Create`, the system shall transition `asn_lifecycle` to state `Unreserved`.
- `AC-WF-001-2`: When `all SKUs reserved` occurs while `asn_lifecycle` is in state `Unreserved` and all_skus_reserved, the system shall transition `asn_lifecycle` to state `Reserved`.
- `AC-WF-001-3`: When `Door assignment from Door Master` occurs while `asn_lifecycle` is in state `Reserved`, the system shall transition `asn_lifecycle` to state `At Door`.
- `AC-WF-001-4`: When `Mark Completed button (warehouse user)` occurs while `asn_lifecycle` is in state `At Door` and all_skus_processed, the system shall transition `asn_lifecycle` to state `Closed`.
- `AC-WF-001-5`: When `Print RCR button` occurs while `asn_lifecycle` is in state `Closed`, the system shall transition `asn_lifecycle` to state `RCR`.

---

_Generated by Step 4 (CIR → PRD) from `enriched_cir.json`. Source: /home/ubuntu/dpg/pipeline/step-02-prd-generation/mantara/runs/1778124586772-pdf/cir/vision_extract.json_
