# Pelagia Portal — Design Document

Internal purchase-order management system for a maritime company.  
This document describes every feature, page, workflow, and user story to guide UI/UX design.

---

## 1. Purpose

Pelagia Portal digitises the full purchase-order lifecycle — from a crew member raising a requisition aboard a vessel, through manager approval and payment by accounts, to receipt confirmation on delivery. It replaces paper and email-based processes with a traceable, role-gated workflow.

---

## 2. User Roles

Seven roles exist. Each role represents a real job function in the company.

| Role | Who they are | Core capability |
|------|-------------|-----------------|
| **TECHNICAL** | Ship technical crew | Create, submit, and track their own POs; confirm delivery |
| **MANNING** | Manning crew | Same as TECHNICAL |
| **ACCOUNTS** | Finance / accounts team | Process payments, manage vendor registry |
| **MANAGER** | Department manager | Review and approve POs, edit line items before approval, view analytics |
| **SUPERUSER** | Power user / ops lead | All PO actions across the board |
| **AUDITOR** | Internal auditor | Read-only view of all POs; export reports |
| **ADMIN** | System administrator | Manage users, vendors, vessels, accounts, products, and sites |

### Role Access Matrix

| Feature area | TECH / MANNING | ACCOUNTS | MANAGER | SUPERUSER | AUDITOR | ADMIN |
|---|:---:|:---:|:---:|:---:|:---:|:---:|
| Create / edit own POs | ✓ | | ✓ | ✓ | | |
| Approve / reject POs | | | ✓ | ✓ | | |
| Process payments | | ✓ | | ✓ | | |
| Confirm receipt | ✓ | | | ✓ | | |
| View all POs | | ✓ | ✓ | ✓ | ✓ | ✓ |
| View analytics / export | | | ✓ | ✓ | ✓ | ✓ |
| Vendor registry | | ✓ | ✓ | | | ✓ |
| Item catalogue | | | ✓ | | | ✓ |
| Vessel management | | | ✓ | | | ✓ |
| Site management | | | ✓ | | | ✓ |
| User management | | | | | | ✓ |
| Account management | | | ✓ | | | ✓ |

---

## 3. Navigation Structure

The left sidebar adapts to the signed-in user's role.

```
Dashboard                       ← all users

─── Purchase Orders ──────────────────
New PO                          ← TECH, MANNING, MANAGER, SUPERUSER
My Orders                       ← TECH, MANNING, MANAGER, SUPERUSER
Approvals                       ← MANAGER, SUPERUSER
Import PO                       ← MANAGER, SUPERUSER, ADMIN
Payments                        ← ACCOUNTS
History / Export                ← MANAGER, SUPERUSER, ACCOUNTS, AUDITOR, ADMIN

─── Inventory ───────────────────────
Vendors                         ← MANAGER, ACCOUNTS, ADMIN
Items                           ← MANAGER, ADMIN
Vessels                         ← MANAGER, ADMIN
Sites                           ← MANAGER, ADMIN
Cart                            ← TECH, MANNING, MANAGER, SUPERUSER

─── Administration ──────────────────  (ADMIN only)
Users
Accounts
```

---

## 4. Authentication

### Login Page `/login`

- Email + password form
- Validates credentials against bcrypt hash
- On success: redirects to `/dashboard` (or pre-login destination)
- No self-registration; accounts are created by an ADMIN

---

## 5. Page Catalogue

### 5.1 Dashboard `/dashboard`

Entry point after login. Content varies by role.

**Submitter view (TECHNICAL / MANNING / SUPERUSER)**
- Stat cards: Open orders count, Pending approval count, Completed orders
- Quick "New PO" call-to-action
- Link to full order list

**Manager view**
- Stat cards: Awaiting approval (clickable → approval queue), Approved this month, Total approved spend
- Recent approved POs table: PO number, title, vessel, amount, date
- Spend trend chart (monthly bar chart, last 6–12 months)
- Vessel spend breakdown chart (pie or bar)

**Accounts view**
- Stat cards: Ready for payment count, Total value awaiting payment
- Quick link to payment queue

**Auditor / Admin view**
- Total PO count with link to history

---

### 5.2 My Purchase Orders `/my-orders`

Personal PO list for submitters.

**Open orders table** (DRAFT, SUBMITTED, MGR_REVIEW, VENDOR_ID_PENDING, EDITS_REQUESTED)
- Columns: PO Number, Title, Vessel, Status badge, Amount, Last updated
- Manager note displayed inline if status = EDITS_REQUESTED

**Past orders table** (MGR_APPROVED through CLOSED / REJECTED)
- Same columns

Actions:
- "New PO" button (top right)
- Click any row → PO detail page

---

### 5.3 Approval Queue `/approvals`

All POs awaiting manager decision (status = MGR_REVIEW).

Filter bar:
- Search (PO number, submitter name, title)
- Vessel dropdown
- Date from picker

Table columns: PO Number, Title, Submitter, Vessel, Amount, Submitted date

Actions:
- "Review" link per row → approval detail page
- Pending count shown in heading

---

### 5.4 PO Detail `/po/[id]`

Full read view of a single PO. Accessible to: the submitter (own POs), ACCOUNTS, MANAGER, SUPERUSER, AUDITOR, ADMIN.

**Header band**
- PO number (monospace)
- Status badge (colour-coded)
- Export PDF button

**Body sections**

*Summary panel*
- Title, vessel, account, vendor (if assigned), project code, date required, currency, total amount

*Line items table*
- Columns: Item name, Description, Qty, Unit, Unit price, GST rate, Total (incl. GST)
- Read-only

*Terms & Conditions*
- Delivery, Dispatch, Inspection, Transit insurance, Payment terms, Others

*Documents*
- Uploaded files with download links

*Audit trail*
- Chronological list of every action on the PO
- Each row: actor name, action type, timestamp, optional note

*Timestamps sidebar (or footer)*
- Created, Submitted, Approved, Paid, Closed

**Contextual action buttons** (shown/hidden based on status and role)

| Condition | Button |
|-----------|--------|
| Status = DRAFT or EDITS_REQUESTED + own submitter | Edit |
| Status = DRAFT + own submitter or MANAGER/SUPERUSER | Discard (delete draft) |
| Status = VENDOR_ID_PENDING + can provide vendor | Vendor selection form inline |
| Status = PAID_DELIVERED + own submitter or SUPERUSER | Confirm Receipt |

---

### 5.5 Approval Detail `/approvals/[id]`

Full PO view with approval action panel. MANAGER / SUPERUSER only.

Same content as PO detail, plus:

**Manager action panel**
- Approve button
- Approve with Note button (opens note textarea, then approves)
- Reject button (requires mandatory note)
- Request Edits button (requires mandatory note)
- Request Vendor ID button (sends back to submitter to supply vendor)

**Manager line-item edit form**
- Inline form allowing manager to adjust quantities, unit prices, GST rate, add/remove line items and change vessel, account, vendor before approving

---

### 5.6 New PO `/po/new`

Multi-section form to create a purchase order.

**Section 1 — Header**
- Title (required)
- Description / remarks
- Vessel (required, dropdown)
- Account / Cost Centre (required, dropdown)
- Vendor (optional, dropdown — can be added later)
- Date Required (date picker)
- Project Code

**Section 2 — Line Items**
- Dynamic table; rows can be added and removed
- Per-row fields: Name (searchable against item catalogue), Description, Qty, Unit, Size, Unit Price, GST Rate
- As-you-type name search shows matching products with per-vendor prices as hints
- Running totals shown below table: Taxable, GST, Grand Total

**Section 3 — Terms & Conditions**
- Delivery, Dispatch, Inspection, Transit Insurance, Payment Terms, Others (all text, optional)

**Section 4 — Documents**
- Drag-and-drop or browse file uploader
- Shows list of attached files

**Footer actions**
- Save as Draft
- Submit for Approval

---

### 5.7 Edit PO `/po/[id]/edit`

Identical form to New PO, pre-filled with existing data.

Available only when status = DRAFT or EDITS_REQUESTED, and the user is the submitter or SUPERUSER.

Footer actions:
- Save as Draft
- Update & Resubmit (only shown when status = EDITS_REQUESTED; transitions back to MGR_REVIEW)

---

### 5.8 Import PO `/po/import`

Upload an Excel file in Pelagia's standard PO template format.

Steps (wizard-style or single page):
1. Drop / upload .xlsx file
2. System parses line items, vendor, quotation details
3. User selects Vessel and Account (not parsed from file)
4. Preview of extracted line items in editable table
5. Save as Draft

---

### 5.9 Confirm Receipt `/po/[id]/receipt`

Receipt confirmation form. Shown only when status = PAID_DELIVERED.

- PO number and title shown as context
- File upload for delivery receipt document
- Optional notes field
- Submit button → transitions PAID_DELIVERED → CLOSED

---

### 5.10 Payment Queue `/payments`

ACCOUNTS role only.

Card list of POs in MGR_APPROVED and SENT_FOR_PAYMENT statuses.

**Per card**
- PO number, title
- Vessel, Submitter, Vendor
- Approved date
- Amount (prominent)
- Status badge: "Ready for Payment" or "Processing — awaiting confirmation"

**Per card actions**
- MGR_APPROVED → "Send for Payment" button
- SENT_FOR_PAYMENT → "Mark as Paid" button
- View PO detail link

---

### 5.11 History & Export `/history`

All POs in all statuses. MANAGER, SUPERUSER, ACCOUNTS, AUDITOR, ADMIN.

**Filter bar**
- Date range (from / to)
- Vessel dropdown
- Status dropdown

**Table columns**: PO Number, Title, Vessel, Submitter, Status badge, Amount, Created date

**Export buttons** (apply current filters to export)
- Export PDF
- Export CSV

---

### 5.12 Vendor Registry `/admin/vendors`

Vendor list. MANAGER, ACCOUNTS, ADMIN.

**Table columns**: Vendor ID (or "Pending"), Name, Contact (name + email), Item count, Verified badge, Status badge

**Actions**
- Add Vendor button → modal form (GSTIN lookup, name, address, pincode auto-filled via GST portal captcha; manual contact fields)
- Edit / Delete per row
- Click vendor name → Vendor Detail page

---

### 5.13 Vendor Detail `/admin/vendors/[id]`

**Header**
- Vendor name, vendor ID, verified / active badges
- Edit button

**Info card**
- GSTIN, address, pincode, contact name, mobile, email

**Items supplied table**
- Product code, name, last quoted price, last updated
- Click product name → Item Detail page

**Recent POs table**
- PO number, status, amount, created date (last 10)

---

### 5.14 GSTIN Lookup (modal / inline within vendor form)

Two-step flow embedded in the Add / Edit Vendor form:

1. User types a 15-character GSTIN and clicks "Look up"
2. System loads GST portal captcha image from the microservice → displays inline
3. User types the 6-digit captcha answer
4. User clicks "Verify" → microservice submits to GST portal → returns taxpayer data
5. Form auto-fills: name, address, pincode (lat/lng geocoded silently from pincode)

Error states: wrong captcha (shows error, resets), session expired (auto-reset), GST portal unavailable.

---

### 5.15 Item Catalogue `/admin/products`

MANAGER, ADMIN.

**Table columns**: Name, Code, Description, Vendor count, Last price, Last vendor, Updated date, Status badge

Footer note: "Items are added automatically when a PO is marked as paid."

**Actions** (ADMIN only)
- Add Product → modal form (code, name, description)
- Toggle Active / Inactive per row
- Delete per row
- Click name → Item Detail page

---

### 5.16 Item Detail `/admin/products/[id]`

**Header**
- Name, code, status badge, description
- Add to Cart button
- Toggle Active button (ADMIN only)

**Stat cards**
- Vendor count, Lowest price, Highest price, Sites with stock

**Price comparison bar chart**
- One bar per vendor, Y-axis = unit price

**Site distance filter**
- Dropdown: "Sort by distance from site" — re-sorts vendor table by proximity
- Uses geocoded pincode of vendor vs site lat/lng for distance

**Vendor pricing table**
- Columns: Vendor (link to vendor detail), Verified badge, Unit price, Distance (if site selected), Last updated, Add to Cart
- Closest vendor gets a ★ marker when a site is selected

**Stock by site**
- Chip list: site name + quantity on hand (link to site detail)

---

### 5.17 Vessel Management `/admin/vessels`

MANAGER, ADMIN.

**Table columns**: Name, Status badge

**Actions**
- Add / Edit / Delete per row (all modal)

---

### 5.18 Account / Cost Centre Management `/admin/accounts`

MANAGER, ADMIN.

**Table columns**: Code, Name, Description, Status badge

**Actions**
- Add / Edit / Delete per row (all modal)

---

### 5.19 Sites `/admin/sites`

MANAGER, ADMIN (ADMIN-only for add/edit/delete).

Ports, depots, and offices that hold inventory.

**Table columns**: Name, Code, Address, Vessels, Items tracked, Location (lat/lon from pincode), Status badge

**Actions**
- Add Site → modal form (name, code, address, pincode for auto-geocoding)
- Edit / Delete per row
- Click name → Site Detail page

---

### 5.20 Site Detail `/admin/sites/[id]`

**Header**
- Name, code, address, geocoded location
- Edit button (ADMIN only)

**Stat cards**
- Vessels at site, Items tracked, Total inventory value (if calculable)

**Inventory bar chart**
- X-axis = product name, Y-axis = quantity on hand

**Consumption line chart**
- Last 30 days of daily consumption, one line per product

**Inventory table**
- Product name, quantity on hand, last updated; link to item detail

**Log consumption form**
- Fields: Product (dropdown), Date (date picker), Quantity, Note
- Submits immediately; chart and table refresh

**Assigned vessels**
- Chip list linking to vessel detail

**Recent POs for this site**
- Last 8 POs with status, vendor, amount

---

### 5.21 User Management `/admin/users`

ADMIN only.

**Table columns**: Employee ID, Name, Email, Role badge, Status badge, Created date

**Actions**
- Add User → modal form (employee ID, name, email, role, initial password)
- Edit → modal form (same fields, password optional)
- Delete per row

---

### 5.22 Cart `/inventory/cart`

Persistent cart collecting items selected from product detail pages. Stored in localStorage.

**Cart view**
- Item list: product name, description, vendor (if selected), unit price, quantity (editable inline)
- Summary: subtotal, GST, grand total
- Site selector (to indicate delivery site)

**Actions**
- Remove item
- Clear cart
- Create PO → opens New PO form pre-filled with cart line items and selected site/vendor

---

## 6. PO Lifecycle State Machine

```
                     ┌──────────────────────────┐
                     ▼                          │
[DRAFT] ──submit──► [SUBMITTED] ──auto──► [MGR_REVIEW]
                                              │  │  │  │
                              approve ◄───────┘  │  │  └──── reject ──► [REJECTED]
                              │                  │  │
                              │    request_edits─┘  └── request_vendor_id ──► [VENDOR_ID_PENDING]
                              │                                                       │
                              │         ◄──── provide_vendor_id ──────────────────────┘
                              │
                     [MGR_APPROVED]
                              │
                    process_payment
                              │
                     [SENT_FOR_PAYMENT]
                              │
                         mark_paid
                              │
                     [PAID_DELIVERED]
                              │
                    confirm_receipt
                              │
                          [CLOSED]
```

States that allow re-entry into the flow:
- **EDITS_REQUESTED** → submitter edits PO → re-submits → MGR_REVIEW
- **VENDOR_ID_PENDING** → submitter selects vendor → MGR_REVIEW

Terminal states: **REJECTED**, **CLOSED**

---

## 7. Workflows

### 7.1 Submit a Purchase Order (TECHNICAL / MANNING)

1. Click **New PO** in sidebar
2. Select vessel and account
3. Add line items (type name to search item catalogue; previous vendor prices appear as hints)
4. Optionally attach documents and fill in T&C fields
5. Click **Submit for Approval**
6. Manager receives email notification
7. Status shows as "Under Review" on My Orders page
8. If manager requests edits: submitter sees EDITS_REQUESTED status with manager note; edits form; resubmits
9. If manager requests vendor ID: submitter selects a vendor and submits; returns to manager queue
10. On approval: submitter notified by email; accounts team can see PO in payment queue

### 7.2 Approve a Purchase Order (MANAGER)

1. Click **Approvals** in sidebar; see count of pending POs
2. Click **Review** on a PO
3. Read full detail: line items, vendor, documents, submitter notes
4. Optionally: click **Edit** to adjust line items, change vendor, vessel, or account
5. Choose action:
   - **Approve** → immediately moves to accounts payment queue
   - **Approve with Note** → same, with a note visible to submitter
   - **Request Edits** → write note explaining required changes; PO returned to submitter
   - **Request Vendor ID** → PO returned to submitter to select vendor; then returns to manager queue
   - **Reject** → write reason; PO is closed permanently

### 7.3 Process a Payment (ACCOUNTS)

1. Click **Payments** in sidebar
2. See cards for all MGR_APPROVED POs
3. Click **Send for Payment** → initiates payment; notifies submitter and manager
4. When payment is confirmed by bank/finance: click **Mark as Paid** → notifies all parties
5. Submitter can now upload delivery receipt

### 7.4 Confirm Receipt (TECHNICAL / MANNING)

1. Goods are delivered on site / to vessel
2. Navigate to PO detail page (status = PAID_DELIVERED)
3. Click **Confirm Receipt**
4. Upload delivery receipt document and optionally add notes
5. Submit → PO is CLOSED; accounts and manager notified

### 7.5 Look Up a Vendor by GSTIN (MANAGER / ADMIN)

1. Open Add/Edit Vendor modal
2. Type the 15-digit GSTIN
3. Click **Look up** → captcha image loads from GST portal (via microservice)
4. Type the 6-digit captcha shown in the image
5. Click **Verify** → form auto-fills with legal name, trade name, registered address, pincode
6. Review and save; location is geocoded silently from pincode for distance calculations

### 7.6 Source Items by Proximity (MANAGER)

1. Navigate to **Items** → click an item name
2. See all vendors that supply the item with their last quoted price
3. Select a **site** from the "Sort by distance from" dropdown
4. Table re-sorts: vendors nearest to the site appear first; distance shown per row; closest vendor marked ★
5. Click **Add to Cart** on the desired vendor row → item added to cart

### 7.7 Create a PO from the Cart (MANAGER / TECHNICAL)

1. Browse Item catalogue and add items to cart (Add to Cart button per vendor row)
2. Click **Cart** in sidebar
3. Review cart: adjust quantities inline; remove items; select delivery site
4. Click **Create PO** → opens New PO form pre-filled with all cart items and vendor
5. Fill in title, vessel, account; submit normally

### 7.8 Track Inventory at a Site (MANAGER / ADMIN)

1. Navigate to **Sites** → click a site
2. View bar chart of current stock (quantity per product)
3. View consumption line chart (last 30 days)
4. Use **Log Consumption** form to record daily drawdown: select product, pick date, enter quantity

### 7.9 Auto-sync Catalogue on Payment Confirmation (ACCOUNTS → SYSTEM)

When accounts clicks **Mark as Paid**:
- System checks each PO line item that has a product link
- For unlinked items: attempts fuzzy-match on name; creates new product record if no match
- Upserts `ProductVendorPrice` — if this vendor/product combination is new or the price changed, updates the catalogue
- Sets `Product.lastPrice` and `Product.lastVendorId`
- Future POs using that product name will see this vendor's latest price as a hint

### 7.10 Import a PO from Excel (MANAGER)

1. Navigate to **Import PO**
2. Upload an Excel file in Pelagia's standard template format
3. System extracts: line items (name, description, qty, unit, price, GST), vendor details, quotation number/date
4. User selects vessel and account from dropdowns
5. Review and optionally edit extracted line items
6. Save as Draft → PO created; submitter can then edit and submit

### 7.11 Export PO History (AUDITOR / MANAGER)

1. Navigate to **History**
2. Apply filters: date range, vessel, status
3. Click **Export PDF** or **Export CSV**
4. File downloaded with all matching POs; up to 200 results per export

---

## 8. Data Entities

### Purchase Order
Fields: PO number (auto-generated), title, status, total amount, currency, date required, project code, manager note, payment reference, quotation number/date, requisition number/date, place of delivery, all T&C text fields, timestamps.

### PO Line Item
Fields: name, description, quantity, unit, size, unit price, GST rate (default 18%), total price (computed), sort order, optional product link.

### Vendor
Fields: name, vendor ID (optional, unique), address, pincode, GSTIN, contact name/mobile/email, latitude/longitude (geocoded silently from pincode), verified flag, active flag.

### Product (Item)
Fields: code (auto-generated or manual), name, description, last price, last vendor, active flag. Prices tracked per vendor via `ProductVendorPrice` (one record per product–vendor pair).

### Vessel
Fields: name, active flag, assigned site (optional).

### Site
Fields: name, code, address, pincode, latitude/longitude, active flag.

### Account (Cost Centre)
Fields: code, name, description, active flag.

### User
Fields: employee ID, email, name, role, active flag, password hash.

### Inventory & Consumption
- `ItemInventory`: quantity of a product at a site (one row per product–site pair)
- `ItemConsumption`: daily draw-down record (one row per product–site–date)

---

## 9. Key UI Patterns

### Status Badges
Each PO status has a distinct colour:
- DRAFT — neutral grey
- SUBMITTED / MGR_REVIEW — blue (in-progress)
- VENDOR_ID_PENDING — orange/warning
- EDITS_REQUESTED — yellow/warning
- MGR_APPROVED — teal/success-adjacent
- SENT_FOR_PAYMENT — purple
- PAID_DELIVERED — blue-green
- CLOSED — green/success
- REJECTED — red/danger

### Confirmation before Destructive Actions
Delete buttons use a two-step inline confirm: "Delete [name]? Confirm / Cancel". No modal dialog — the confirm state replaces the button in-place.

### Inline Editing in Tables
Manager line-item editing in the approval flow happens in an inline form on the same page, not in a modal, so the manager can reference the rest of the PO while editing.

### GST Calculation (always visible in PO forms)
Below the line-items table, a live summary shows:
- Taxable amount (sum of qty × unit price)
- GST amount (sum of qty × unit price × GST rate)
- Grand Total (taxable + GST)

### Product Autocomplete
In the PO line-item name field, typing triggers a fuzzy search of the item catalogue. Dropdown shows:
- Product name and code
- Price hints per vendor: "Vendor A: ₹1,200 · Vendor B: ₹1,050"

### Cart Persistence
Cart is stored in browser `localStorage` under a fixed key. It survives navigation but is local to the device and user. A `cart-updated` custom event allows components to react to changes in real time.

### Notifications / Emails
Every PO status transition triggers an email to relevant parties:
- Submit → manager
- Approve → submitter + accounts
- Reject → submitter
- Request Edits → submitter
- Request Vendor ID → submitter
- Payment sent → submitter + manager
- Mark paid → submitter + manager
- Receipt confirmed → manager + accounts

---

## 10. Non-Goals (Out of Scope)

- Mobile app (web-only, desktop-first)
- Public-facing pages (entirely internal)
- Self-registration / OAuth login
- Vendor portal (vendors do not log in)
- Automated bank/payment-gateway integration (payment is marked manually)
