feat: add invoice viewing (C-015) and notifications display (C-016)
Some checks failed
Build and Deploy / build (push) Successful in 5m4s
Build and Deploy / deploy (push) Failing after 3s

- Invoice page with table, search, sort, CSV export, PDF download
- Company-level access control (can_access_invoices + view_invoices permission)
- Notifications page with unread alerts section and mark-as-read
- Fix unread notification count in layout (was counting read markers)
- Fix dashboard notification count to use per-user unread alerts
- Configurable INVOICE_STORAGE_PATH for invoice PDF file serving

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lorentz Hinrichsen 2026-02-17 10:04:01 -05:00
parent 1198aaa373
commit b32553668d
17 changed files with 881 additions and 32 deletions

View file

@ -128,7 +128,7 @@
## Phase 2: Core Features (Est. 80-110 hrs)
**Progress:** 12/16 tasks complete
**Progress:** 14/16 tasks complete
### C-001: Dashboard
- [x] Dashboard page at `/(portal)/dashboard/page.tsx`
@ -282,19 +282,23 @@
- **Deps:** F-005, C-003 | **Est:** 8 hrs
### C-015: Invoice Viewing (Customer)
- [ ] `/(portal)/invoices/page.tsx`
- [ ] Only visible if company `CanAccessInvoices=true`
- [ ] List invoices from `inv_upload_entry` filtered by company
- [ ] PDF download endpoint `/api/invoices/:id/pdf`
- [ ] File serving from storage directory
- **Deps:** F-005, F-009 | **Est:** 4 hrs
- [x] `/(portal)/invoices/page.tsx` — client-side fetch with loading skeleton
- [x] Only visible if company `can_access_invoices=true` (403 response + user-friendly message)
- [x] Service: `getInvoicesForCompany(companyId)` querying `inv_upload_entry` filtered by company
- [x] Invoice table with search, sort, CSV export (invoice#, job#, page, date, sent date, PDF link)
- [x] PDF download endpoint `/api/invoices/{id}/pdf` with company security check
- [x] File serving from configurable `INVOICE_STORAGE_PATH` storage directory
- [x] Permission check: `view_invoices` + `can_access_invoices`
- **Deps:** F-005, F-009 | **Est:** 4 hrs | **Status:** ✅ Complete
### C-016: Notifications Display
- [ ] Notification bell in header with unread count
- [ ] Alert banner on dashboard for IsAlert=true notifications
- [ ] Notification list view
- [ ] Mark as read → create `quest_user_notification_alert_read` record
- **Deps:** F-005, F-009 | **Est:** 3 hrs
- [x] Fixed notification bell unread count (was counting read records, now counts unread alerts)
- [x] Notification service: `getActiveNotifications()`, `getUnreadAlertCount()`, `markNotificationRead()`
- [x] Alert banner on dashboard uses correct unread count for current user
- [x] `/(portal)/notifications/page.tsx` — notification list with unread alerts section
- [x] Mark as read → upsert `quest_user_notification_alert_read` record
- [x] API routes: `/api/notifications` (GET list) + `/api/notifications/{id}/read` (POST mark read)
- **Deps:** F-005, F-009 | **Est:** 3 hrs | **Status:** ✅ Complete
---