Tasks/projects page: reverted back to one row per task (work status only,
no billing state on that page). Per-version R## tracking lives in invoicing
only (invoice_items, sub invoice form).
DB fix: 7 Public Storage tasks had pending revision versions (R01/R02)
with no delivery but were stuck as 'paid' from old invoice lifecycle sync.
Reset to 'not_started' so they appear in the Revisions tab for work:
68664, 68666, 68721 (R02), 68808, 68809 (R02), 68810 (R02), 68811 (R02)
Removed unused invoiceItems state/fetch from Tasks + ProjectDetail.
invoiceVersionRules helpers retained for invoicing use.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each revision (R00, R01, R02) is now an independent trackable unit:
invoiceVersionRules: add deriveVersionStatus, buildInvoiceStatusByKey,
parseVersionFromItemDescription for per-version status derivation
Tasks.jsx + ProjectDetail.jsx:
- Fetch invoice_items joined with invoice.status (team only)
- allRows/rows now flatMap per version (one row per R##)
- Status derived from: invoice_items > past version > task.status
- R00 paid shows as paid; R01 in_progress shows separately
- tr keys use rowKey (taskId:version) to avoid duplicate key warnings
Invoice lifecycle (TeamInvoiceDetail, TeamInvoices, TeamCreateInvoice):
- Remove task.status sync on invoice paid/sent/created
- Keep invoiced:true flag for double-billing prevention
- Task work status (not_started → client_approved) stays work-flow only
ProjectDetail completion bar uses task.status === client_approved only
(no longer polluted by invoiced/paid status from invoice sync)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevent overwriting task status when task has moved to a new revision
cycle after being invoiced. Now uses .eq('status', guardStatus) to only
update tasks still at the expected prior state:
- invoice creation: only update tasks at client_approved → invoiced
- mark sent: only client_approved → invoiced
- mark paid: only invoiced → paid
- reopen: only paid → client_approved
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rgba(255,255,255,0.06) with backdrop blur renders lighter in Chrome.
rgba(0,0,0,0.35) gives consistent dark panel across all browsers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 'PURCHASE ORDER' → 'SUBCONTRACTOR INVOICE'
- Items loop now calls addPage() when hitting safeBottom (792-80pt)
- Continuation pages get header with invoice number + '(continued)'
- Summary/Notes sections also page-break if needed
- Footer text updated to match invoice context
- Footer line position dynamic (tracks y), not hardcoded at 704
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Company dropdown and Email To input only editable on draft invoices.
Sent and paid invoices show read-only text values instead.
Applied to both popup (embedded) and standalone page views.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace SubcontractorInvoiceDetailView (card-based) with flat layout
matching the original sub-invoice popup: meta strip + raw table + notes.
- InvoiceDetailPopup: add metaContent/metaActions/metaCols props + export POPUP_FIELD_LABEL
- New InvoicePopupTable: flat sortable 5-col table, no card wrapper
- All 4 popups (client, team invoice, team sub-invoice, external): use
flat meta strip (4-col grid, borderBottom) and InvoicePopupTable
- Sub-invoice + external: Submitted | Paid/Created | Items | Total
- Client invoice: Date | Due | Status | Total
- Team invoice: Date | Due | Company | Email | Total (+ stripe if paid)
with Edit Dates button in metaActions slot
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Team performance: count each delivery record individually (sent_by + version_number), not per task — R00/R01/R02 by different people all count separately
- Performance uses deliveries table directly, EST timezone bucketing, month-gated tabs
- TaskDetail Submissions tab: reads from deliveries table, shows R## version, sent_by, sent_at
- Submit for Review: writes to deliveries + delivery_files (deliveries bucket), stores version_number
- Revision request popup: uses FileAttachment drag-drop component
- Task table: only Name and Project columns highlight on hover
- deliveries.version_number column added and backfilled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Expense detail popup: 80vw×80vh, inline editing, save gated on dirty state, Download Receipt in footer
- Add expense form: same layout with FileAttachment drag-drop on right
- New invoice popup: 80vw×80vh inline form replacing navigate-away page
- Tasks table: suppress row hover background, only Name/Project table-links highlight
- TaskDetail Submissions tab: reads from deliveries table, shows R## version, sent_by, message
- Submit for Review: writes to deliveries + delivery_files (deliveries bucket)
- deliveries.version_number column added and backfilled from revision history
- Port 4173 for dev server
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- FileSharing: rootPath for clients strips /Clients/ prefix — API resolveClientPath expects /{company} not /Clients/{company}
- Tasks: default to To Do tab (not_started) instead of All Tasks
- Projects: default to Active tab instead of All Projects
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Overview tab: 3 donut pie charts (expenses by category, sub payments, invoiced) each with independent month navigation arrows
- Expenses tab: big red total in category sidebar, left-aligned category column, white text
- Subcontractors tab: big gold total in sidebar, pending/paid breakdown with gold highlight
- Invoices tab: big green total in companies sidebar, dashboard-inline-link for invoice# and company, StatusBadge with Invoiced/Paid labels, column widths tuned
- StatusBadge: add optional label prop for custom display text
- Layout/style polish across tabs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- filebrowserFolders.js: createTaskFolder now creates Old Books
- fbq-backfill: creates Old Books; migrateOldBook() merges/renames
existing Old Book folders into Old Books on each backfill run
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Unified Tasks page: 3 role render blocks → 1, normalized row shape, single renderRow/sort/tabs
- Fixed role scoping: external = all tasks in member projects, client = all tasks in company projects
- Fixed client bug: was scoped by submitted_by, now company→project→tasks
- Aligned dashboard client scope to match tasks page
- Hot tasks dashboard: now filters to active statuses only (not completed/invoiced/paid)
- Removed Projects.jsx (dead), fixed /project/ → /projects/ links
- Renamed all page files to match folder path (Team*, External*, Client* prefixes)
- Renamed: RequestsPage→Tasks, Settings→Profile, CompaniesPage→Companies, ProjectDetailPage→ProjectDetail
- Dropped dead fetches from Tasks page (invoices, invoice_items, subcontractor_invoice_items)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>