pelagia-portal/Progress/PROGRESS.md

13 KiB

Pelagia Portal — Build Progress

Last updated: 2026-05-05

Legend: Complete · ⚠️ Partial (works but incomplete) · Not started


Infrastructure & Config

Item Status Notes
Next.js 15 App Router project Turbopack dev, strict TS
Tailwind CSS v4 + design tokens Colour palette matches spec
Prisma schema — all models Product, gstRate, piQuotationNo/Date, requisitionNo/Date, placeOfDelivery, tcDelivery/tcDispatch/tcInspection/tcTransitInsurance/tcPaymentTerms/tcOthers, address/gstin/contactMobile on Vendor — all migrated (latest: structured_tc_fields)
Database seed script 5 users, 3 vessels, 3 accounts, 3 vendors, 3 sample POs, 4 products
Dev / production environment split NODE_ENV gates R2 vs local storage, Resend vs console log
.env.example + .env / .env.local docs README covers full setup
README with dev + prod setup guide
CI/CD (GitHub Actions) No workflow files yet

Authentication & Authorisation

Item Status Notes
Login page (credentials) Email + password, bcrypt hash
NextAuth.js v5 session Database sessions, role in JWT
Auth middleware (route protection) Redirects unauthenticated to /login
Role permissions matrix (lib/permissions.ts) All 7 roles; manage_products added for Admin
SSO / Azure AD login Open question — credentials only for v1

PO State Machine (lib/po-state-machine.ts)

Item Status Notes
All 10 statuses defined
All transitions with role guards
canPerformAction, getAvailableActions helpers
requiresNote helper
Unit tests tests/unit/po-state-machine.test.ts

Email Notifications (lib/notifier.ts)

Item Status Notes
Notifier module (Resend in prod, console in dev)
Email templates (all 7 events) React Email components in /emails/
Notify on PO submitted Notifies managers + submitter (confirmation)
Notify on PO approved / rejected / edits requested Per notification matrix
Notify on vendor ID requested / provided
Notify on payment processed Notifies managers + accounts on processing; submitter + managers on confirmed
Notify on receipt confirmed Notifies managers + accounts

File Storage (lib/storage.ts)

Item Status Notes
Dev local storage (/api/files/dev/[...key]) Auth-gated, path-traversal protected
Prod Cloudflare R2 presigned URLs Upload + download URL generation
Sign API (/api/files/sign) Returns { uploadUrl, key }
File upload UI on New PO form FileUploader component + uploadAndLinkFiles utility; PO created first, then files signed+uploaded+linked
File upload UI on Receipt form Same pattern, type "receipt"
Document download links on PO detail PoDetail made async; generateDownloadUrl called server-side; filenames are clickable links

Pages & Server Actions

Login

Item Status
Login page + credentials form

Dashboard

Item Status Notes
Submitter dashboard (stat cards + New PO CTA) Recent orders table; link to My Orders
Manager dashboard (stat cards)
Manager dashboard — approved POs listing Recent approved/in-progress POs table with vessel, status, amount
Manager dashboard — spend by vessel breakdown Recharts bar chart (top 5 vessels)
Manager spend-by-vessel bar chart SpendCharts component using Recharts
Manager spend-by-month bar chart Last 12 months, bar chart
Accounts dashboard (stat cards)
Auditor / Admin / generic dashboard Single total-count card

New PO

Item Status Notes
Form (title, vessel, account, vendor, project code, date)
Line items — UoM dropdown (15 options) Replaces free-text unit field
Line items — Size field Optional free-text
Line items — GST rate per item (0 / 5 / 12 / 18 / 28%) Default 18%; taxable / GST / grand-total breakdown shown live in editor
PI / Quotation No. + Date Separate section on form
Vessel / Office Requisition No. + Date Separate section on form
Place of Delivery Pre-filled with company delivery address; editable
Terms & Conditions — structured fields Fixed line 1 (read-only); separate inputs for Delivery, Dispatch Instructions, Inspection, Transit Insurance, Payment Terms, Others (multiline); all pre-filled with defaults
Currency defaults to INR Changed from USD → INR throughout
Save as draft
Submit for approval (→ MGR_REVIEW)
Document file upload Drag-and-drop + click; signed upload after PO creation

PO Detail (/po/[id])

Item Status Notes
Full detail view (info, vendor, line items, activity trail)
New fields displayed (PI/Quotation, Requisition, Delivery, Approved By)
Line items with GST breakdown (taxable / GST / grand total)
Vendor detail (address, GSTIN, contact name + mobile + email)
Terms & Conditions block (structured display) Fixed line 1 always shown; each labeled field (Delivery, Dispatch, etc.) on its own line
Export PDF button /api/po/[id]/export?format=pdf — auto-triggers print dialog; matches Sample_PO layout
Export XLSX button /api/po/[id]/export?format=xlsx — SheetJS; matches Sample_PO column layout
Confirm Receipt CTA (PAID_DELIVERED state)
Document download links Clickable links with server-generated presigned/dev URLs
Edit PO link (DRAFT / EDITS_REQUESTED)

PO Edit (/po/[id]/edit)

Item Status Notes
Edit page Pre-populated form including all new fields
Update draft action
Resubmit after edits Shows manager note banner + Resubmit button

Vendor ID Flow

Item Status Notes
Request vendor ID action (manager) Sets status to VENDOR_ID_PENDING
Provide vendor ID UI (submitter / manager) Inline form on PO detail for VENDOR_ID_PENDING
Provide vendor ID server action Transitions back to MGR_REVIEW, notifies managers

Approvals

Item Status Notes
Approval queue list
PO detail + decision view
Approve / Approve+Note actions
Reject action
Request edits action
Request vendor ID action
Manager edit line items (amber edit mode) Saves original snapshot to POAction; diff shown with strike-through
Search / filter (PO number, vessel, submitter, date) URL search params; ApprovalsSearch client component

Payments

Item Status Notes
Payment queue list (MGR_APPROVED + SENT_FOR_PAYMENT)
Start payment processing (MGR_APPROVED → SENT_FOR_PAYMENT) Step 1
Confirm payment sent with ref (SENT_FOR_PAYMENT → PAID_DELIVERED) Step 2 — auto-updates Product.lastPrice for linked line items

My Orders (/my-orders)

Item Status Notes
My Orders page — all POs with open/past grouping Links to individual PO detail; shows manager note inline

Receipt Confirmation

Item Status Notes
Notes + file receipt confirmation Closes PO to CLOSED; optional file attachment via FileUploader

History

Item Status Notes
All-POs list (latest 200 by default)
CSV export Respects active filters
PDF export (bulk) Print-optimised HTML page (/api/reports/export?format=pdf); auto-triggers browser print dialog
Date range filter URL search params; HistoryFilters client component
Vessel / status filters Same component

Admin — User Management

Item Status Notes
User list
Add user form + action AdminDialog modal; bcrypt password hash
Edit user form + action Optional password change
Deactivate / reactivate user Cannot deactivate own account

Admin — Vendor Management

Item Status Notes
Vendor list
Add vendor form + action AdminDialog modal; sets isVerified if vendorId provided
Edit vendor form + action Includes address, GSTIN, contact mobile
Deactivate / reactivate vendor

Admin — Vessel Management

Item Status Notes
Vessel list page /admin/vessels
Add vessel form + action Name-only cost centre creation
Edit vessel form + action
Deactivate / reactivate vessel

Admin — Account Management

Item Status Notes
Account list page /admin/accounts
Add account form + action Code uniqueness check
Edit account form + action
Deactivate / reactivate account

Admin — Product Catalogue (/admin/products)

Item Status Notes
Product list (code, name, last price, last vendor) Last price/vendor read-only — auto-populated on payment
Create product action Code must be unique
Toggle active/inactive action
Add product form (UI) AdminDialog modal wired to existing createProduct action

Type Safety

Item Status Notes
Discriminated union narrowing in approval-actions.tsx Typed as { ok: true } | { error: string } | undefined, checked with "error" in result
Union narrowing in receipt-form.tsx
Union narrowing in new-po-form.tsx
Buffer type in api/files/dev/route.ts Cast to Uint8Array
New PO fields in Prisma types ⚠️ Migration applied; Prisma client types stale — resolve by restarting dev server and running pnpm db:generate

Testing

Item Status Notes
Unit: state machine tests/unit/po-state-machine.test.ts — 21 tests
Unit: permissions tests/unit/permissions.test.ts — 11 tests
Unit: utility functions tests/unit/utils.test.ts — 17 tests (formatCurrency INR, formatDate, generatePoNumber, status labels/variants)
Unit: Zod validation schemas tests/unit/validations.test.ts — 24 tests (createPoSchema, lineItemSchema, TC fields, defaults)
Component: PoStatusBadge tests/unit/po-status-badge.test.tsx — 17 tests (all 10 statuses)
Component: LineItemsEditor tests/unit/po-line-items-editor.test.tsx — 20 tests (add/remove rows, GST calc, totals, read-only, diff mode)
Integration: PO creation (S-01, S-02, S-03) tests/integration/create-po.test.ts — 9 tests; uses real DB + mocked auth/notifier
Integration: Approval actions (M-02, M-03, M-04, S-06, S-07) tests/integration/approval-actions.test.ts — 14 tests
Integration: Payment actions (A-01, A-02) tests/integration/payment-actions.test.ts — 8 tests
E2E: authentication flow tests/e2e/auth.spec.ts — 6 tests
E2E: submitter journey (S-01 to S-08) tests/e2e/submitter-journey.spec.ts — 8 tests
E2E: manager approvals (M-01 to M-04) tests/e2e/manager-approvals.spec.ts — 9 tests
E2E: accounts payment (A-01, A-02) tests/e2e/accounts-payment.spec.ts — 6 tests
E2E: PO export (PDF + XLSX) tests/e2e/po-export.spec.ts — 8 tests (buttons, endpoints, content, auth)
Accessibility (axe-core + Playwright) Not yet written

Summary

Category Total items tracked Done ⚠️ Partial Pending
Infrastructure 8 7 0 1
Auth & Permissions 5 4 0 1
State Machine 5 5 0 0
Email Notifications 7 7 0 0
File Storage 6 6 0 0
Pages & Actions 83 83 0 0
Type Safety 5 4 1 0
Testing 15 14 0 1
Total 134 130 (97%) 1 (1%) 3 (2%)

Remaining Items

  1. Prisma client regeneration — restart dev server, then pnpm db:generate (DLL was locked during the last generate; migration is fully applied, no data loss)
  2. CI/CD — GitHub Actions workflow: lint, type-check, test, build on PR; deploy on merge
  3. Accessibility tests — axe-core + Playwright
  4. SSO / Azure AD — credentials-only for v1; open question for v2

Not in Spec (deferred)

  • SSO / Azure AD login
  • Discount field on PO
  • Account Group / Account Code hierarchy (codes currently flat)
  • Cost centre vs vessel distinction (currently same entity)
  • Vendor deactivation cascade — warn if vendor has open POs
  • Approval queue — show VENDOR_ID_PENDING alongside MGR_REVIEW
  • Vendor required before approval can be granted (currently advisory only)