- Create src/lib/redis.ts (singleton client) and src/lib/cache.ts
(cachedQuery with graceful degradation on Redis failure)
- Wrap all 12 API routes and 7 RSC pages with cachedQuery (TTLs:
120s-900s by data type — dashboard 3min, inventory/orders/shipments
5min, BOL/order-ack/traveler 10min, ship-to 15min, avail-coils 2min)
- Fix redundant connection pools in dashboard.ts and shipments.ts
(were creating their own sql.connect instead of using shared pool)
- Add pool tuning to epicor.ts (max:15, min:2, 60s idle, 30s acquire)
- Parallelize session checks (getQuestSession + getActiveCompany +
isSubUser) with Promise.all across all inventory and orders pages
- Add loading.tsx skeletons for dashboard, inventory detail, orders,
and shipments pages for instant shell rendering via Next.js streaming
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass cartEnabled prop through inventory summary and detail tables
to show the CartBar component for users with shipment request
permissions. Fix embedded detail table missing cart/category props.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the wizard-style 4-step shipment cart with an inventory-page-
integrated flow matching the legacy portal UX. Users now add items
directly from inventory detail rows via "+" buttons, with a persistent
cart bar showing status. The "Complete Release" page is a flat form
instead of a multi-step wizard.
Key changes:
- Add ShipmentCartProvider context for cross-page cart state
- Add CartBar component (start/cancel release, view status)
- Integrate cart column into inventory detail table with per-row
add buttons, plant mismatch indicators, and "Add All" support
- Rewrite /shipment-requests/new as flat Complete Release page
- Add check_only param to cart API (avoid auto-creating on mount)
- Add server-side plant constraint validation on cart items
- Add batch add API endpoint for "Add All" functionality
- Delete deprecated wizard cart and inventory browser dialog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements C-010 (Coil-by-Coil), C-011 (Job Status by Plant), and
C-012 (Job Traveler + PDF) completing 12/16 Phase 2 core features.
C-010: Job number search → detailed coil-level breakdown showing
materials used and produced with independent search/sort/CSV export.
Embeds full 782-line CoilByCoil.sql query in service layer.
C-011: Auto-loading job status view grouped by plant using
OpenOrdersQueryV3 stored procedure. Includes web table with
search/sort/CSV export and landscape PDF download.
C-012: Multi-section job traveler with header info, shipping schedule,
raw materials, operations, and Part_UD paint specifications. Includes
job number search page, detail page, and PDF export with Vorteq
branding. Deduplicates flat SQL results into structured data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
C-005: Order Acknowledgement Detail + PDF
- Order detail page with full line items, releases, addresses, paint codes
- PDF export via Puppeteer matching legacy format
- Clickable order # links and PDF icons in orders table
C-007: BOL Detail + PDF
- BOL detail page with ship-from/to, line items, weights
- PDF export matching legacy BOL format
- PDF icon column in shipments table
C-008: Coil Activity - Usage Report
- Date range picker (max 31 days, default last 10 days)
- Reusable UI: Popover, Calendar (react-day-picker v9), DateRangePicker
- SQL from legacy portal_CoilActivityUsage.sql with OnHandQty dedup
- 11-column sortable table with search and CSV export
C-009: Coil Activity - Receipts Report
- VGL customer exception (special SQL vs portal view)
- 10-column sortable table with search and CSV export
- Shared date range picker component
Also: dashboard API route, shipments API route, HDC→HDM mapping,
Puppeteer PDF infrastructure, improved error handling.
Progress: 9/16 Phase 2 tasks complete.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add reusable SortableTableHead component and useSortableTable hook
with tri-state sorting (asc/desc/none). Apply colored headers and
zebra striping to orders, inventory summary, and inventory detail
tables. Widen detail modal to 95vw.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route dev domain through Traefik to host:3001 instead of Docker
container, enabling instant hot reload. Expose PostgreSQL and Redis
ports to localhost for local dev server connectivity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add cmdk-based combobox to portal header for inline company switching
with search by name or Epicor ID. Also update select-company page to
use the same pattern. Fix admin company switching by allowing admins
to switch to any active company without requiring a quest_user_company
link.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inventory summary table now shows Plant, Cust Part#, Vorteq Part#,
Vorteq Desc, Warehouse, Qty LB, Rows with a blue View button for
drill-down. Admins see all active companies in the company selector.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inventory service now maps PascalCase SP columns (VorteqPartNum,
OnHandQty, etc.) to snake_case types. Fixed non-V6 SP parameter
from Customer to CUSTID. Orders service now uses the portal_Orders
view instead of raw table queries with nonexistent columns.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update inventory service to use actual PascalCase SP names
(e.g. PortalWorkInProgressInventorySummaryV6) and correct parameter
names (Customer, SUBUSER) matching the Epicor database.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add DEV_MODE env var check to return mock admin session when auth is
unavailable, hostname-based middleware bypass for dev domain, and
window.location.href for login redirect to ensure cookies are sent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
next build bakes NODE_ENV=production into the bundle, so a custom
DEV_MODE env var is used instead. Middleware bypasses auth by hostname
for the dev domain, and getQuestSession returns a mock admin session
when DEV_MODE=true. Login page now uses window.location.href for
full-page navigation to ensure the session cookie is sent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change session cookie name from better-auth.session_token to session_token
- Increase rate limit to 100 req/min in development (10 in production)
- Fix DATABASE_URL to use URL-encoded password for special characters
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace client-side useSession hook with server-side prop passing.
Portal layout fetches user email server-side and passes to header.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add custom login API route with bcrypt password verification
- Update auth client to use custom endpoints
- Simplify login page to use new auth client
- Remove Better Auth dependencies that were causing issues
- Add orders service with getTop100Orders and getOrderDetails
- Add special HDC/HDM customer exception handling
- Add OrdersTable component with search, filter, CSV export
- Add orders list page at /orders
- Create public folder for Next.js static assets
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add inventory detail service functions for all 6 categories
- Update stored procedure names to match Epicor database
- Add InventoryDetailTable component with search and CSV export
- Add dynamic detail page at /inventory/[category]/detail
- Update summary table links to point to detail pages
- Fix InventoryDetailRow type to support flexible field names
- Add Dockerfile prisma generate step before build
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements complete dashboard with metrics, recent activity, and quick navigation.
Begins inventory system with service layer and category selector.
Dashboard (C-001) - Complete:
- Server component with parallel data fetching
- Summary cards: WIP, Finished Goods, Total Weight, Recent Orders
- Recent activity tables: top 5 orders and shipments
- Alert banner for important notifications
- Quick navigation cards to all major features
- Loading skeletons with Suspense boundaries
- Reusable components: SummaryCard, QuickNavCard, tables
- Dashboard service with typed Epicor queries
Inventory (C-002) - Core Complete:
- Complete service layer for all 6 inventory categories
- Category selector page with permission-based visibility
- Reusable inventory summary table with search and CSV export
- WIP inventory page as template for other categories
- Sub-user permission enforcement at service layer
- Type-safe stored procedure calls with proper error handling
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements authentication middleware with rate limiting, comprehensive permission
system, full portal navigation with sidebar and header, company selection flow,
and data migration tooling from SQL Server to PostgreSQL.
Key additions:
- Middleware: auth guards, rate limiting, session management
- Permissions: role-based access control with hierarchical permission rules
- Navigation: responsive sidebar with expandable sections, header with notifications
- Company selector: multi-company user support with session-based active company
- Data migration: comprehensive script for migrating auth and quest domain tables
- Schema: added auth_user_type_permission_group junction table
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Initialize Next.js 15 with App Router and TypeScript strict mode
- Configure Tailwind CSS with shadcn/ui theme system
- Install shadcn/ui components (button, card, input, table, etc.)
- Set up ESLint and Prettier with automatic formatting
- Configure path aliases (@/*) in tsconfig.json
- Create full project structure per CLAUDE.md
- Add health check endpoint at /api/health
- Configure next.config.ts with output: 'standalone' for Docker
- Set up Prisma with placeholder schema
- Configure Vitest (unit) and Playwright (E2E) testing
- Add VS Code settings for consistent development experience
Build verification: TypeScript compilation, ESLint, and production build all pass.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>