CON-001
System Overview & Role
The Contractor portal is for subcontractors doing field work on engineering projects. A contractor user is linked to a Subcontractor record via user_id. All financial data (vouchers, ledger) is resolved through that Subcontractor record — not the user directly.
| Capability | Source |
|---|---|
| View workspace | Subcontractor record WHERE user_id = auth()->id() |
| Submit daily logs | DailyLog; subcontractor_id auto-resolved |
| Submit expenses | Expense; subcontractor_id auto-resolved |
| View materials | MaterialStock for the business (read-only) |
| View vouchers | Voucher WHERE subcontractor_id = resolved sub.id |
| View ledger | LedgerEntry WHERE party_type=subcontractor AND party_id=sub.id |
⚠ If no Subcontractor record is linked to the logged-in user, vouchers and ledger return empty arrays rather than errors. Admin must link the user_id to the Subcontractor record during onboarding.
CON-002
Subcontractor Onboarding Flow
1Admin creates
POST /api/admin/subcontractors with company_name, trade_type, contact details2If the subcontractor needs portal access: create a user account separately, note the user_id
3Admin updates the subcontractor record with
user_id of the portal user4Contractor logs in →
GET /api/contractor/workspaces returns their company profile5Contractor can now submit daily logs and expenses, and view vouchers/ledger
CON-003
Daily Log Workflow
Daily logs are the primary accountability record. They show the admin what work was done and how many workers were on site each day.
| Field | Rule |
|---|---|
| log_date | Required; typically today or yesterday |
| work_summary | Required; narrative of work done |
| workers_count | Optional; defaults to 0 |
| project_id | Optional; links to a specific project |
| status | Auto-set to submitted; admin can change to approved/rejected |
| subcontractor_id | Auto-resolved from auth user; cannot be overridden |
CON-004
Expense Claims
Expenses represent costs incurred by the subcontractor on behalf of the project. All expenses start as pending and require admin approval.
| Expense category examples | Typical usage |
|---|---|
| fuel | Diesel for machinery, generator |
| materials | Binding wire, formwork timber, consumables |
| labour | Labour-only costs not covered by weekly voucher |
| transport | Vehicle hire, delivery charges |
| other | Miscellaneous site costs |
// Expense approval flow
contractor submits -> status: pending
admin reviews -> status: approved | rejected
// Approved expenses may generate a ledger debit entry
contractor submits -> status: pending
admin reviews -> status: approved | rejected
// Approved expenses may generate a ledger debit entry
CON-005
Vouchers & Ledger (Read-Only)
Vouchers and ledger entries are read-only for the contractor. Admin creates vouchers for weekly work claims; once approved, a corresponding ledger entry records the payment.
| Voucher status | Contractor visible? | Meaning |
|---|---|---|
| draft | Yes | Admin is preparing the voucher |
| submitted | Yes | Submitted for approval |
| approved | Yes | Approved; payment being processed |
| paid | Yes | Payment made; matches ledger credit entry |
| rejected | Yes | Declined; may require re-submission |
// Running balance visible to contractor
credits = SUM(ledger_entries WHERE party_type=subcontractor AND party_id=sub.id AND entry_type=payment)
deductions = SUM(ledger_entries WHERE ... AND entry_type=deduction)
balance_due = credits - deductions - advance_paid
credits = SUM(ledger_entries WHERE party_type=subcontractor AND party_id=sub.id AND entry_type=payment)
deductions = SUM(ledger_entries WHERE ... AND entry_type=deduction)
balance_due = credits - deductions - advance_paid
CON-006
Error Reference
| Code | Cause |
|---|---|
| 401 | Token missing or expired |
| 403 | user_type is not contractor |
| 422 | Validation failed on daily log or expense submission |