Engineering Specification — PavingOS

Version: MVP v1 (Authoritative)

Focus: Field reliability (offline), financial correctness, scalable estimating logic

1. Product & Architectural Goals

Primary Product Goals

Opinionated estimating built for paving (templates → assemblies → estimates).

Zero-reentry workflow: Estimate → Job → Actuals → Invoice.

Continuous feedback loop from job actuals back to estimating insights.

Foreman-first execution experience with minimal friction.

Day-1 Non-Negotiables

Minimum viable offline support for foremen:

View assigned jobs

Start / complete job

Log labor hours

Add notes

Capture photos

Sync later without data loss

Financial correctness

No floating-point currency math

Deterministic, auditable calculations

Multi-tenant, secure-by-default

Row Level Security everywhere

Strong auditability for financial actions

2. System Architecture

High-Level Stack

Frontend & API: Next.js (App Router) deployed on Vercel

Database: Supabase Postgres

Auth: Supabase Auth (magic link initially)

Storage: Supabase Storage (private buckets)

Offline: Service Worker + IndexedDB (event queue + photo staging)

Integrations: QuickBooks Online (OAuth2 + REST APIs)

Runtime Responsibilities

Vercel Edge

Session handling

Lightweight reads

Middleware (auth, rate limiting)

Vercel Serverless

Job/event ingestion

Estimate → Job transactions

Invoice creation

QBO OAuth + API calls

Supabase

Data integrity, RLS enforcement

Storage signing

Optional realtime subscriptions

3. Offline Strategy (Authoritative)

Philosophy

This is not a full local-first replica.

This is minimum viable offline, optimized for reliability and speed.

Client Behavior

Foreman actions are written first to IndexedDB.

Each action generates a job_event with a UUID client_event_id.

Photos are staged locally until upload succeeds.

Sync runs automatically when connectivity is detected.

Server Behavior

Events are appended idempotently.

Duplicate client_event_ids are ignored.

Derived summaries are recomputed server-side.

Why This Approach

Predictable

Auditable

Easy to reason about

Avoids premature sync-engine complexity

4. Authentication & Foreman PIN Security

Supabase Auth

Email magic link for all users.

Sessions managed server-side (@supabase/ssr).

Foreman PIN Gate (Required)

Field devices are shared. We add a local PIN lock.

Behavior

After initial login, foreman sets a 4–6 digit PIN.

App requires PIN to unlock cached jobs and offline UI.

PIN is required after:

App restart

Inactivity timeout

Ops/Owner can remotely reset or lock PINs.

Data Model

profiles

user_id (pk)

pin_hash text

pin_set_at timestamptz

pin_failed_attempts int

pin_locked_until timestamptz

Notes

PIN ≠ Auth token

PIN protects against casual misuse, not device compromise

IndexedDB encryption may be added later

5. Data Model (Postgres, Multi-Tenant)

Core Tenancy

All tables include org_id.

All access enforced via RLS.

orgs

id uuid pk

name text

timezone text

created_at

profiles

user_id uuid pk

full_name

phone

PIN fields (see above)

org_memberships

org_id

user_id

role enum (owner|ops|estimator|foreman)

status

Unique (org_id, user_id)

6. Financial Modeling (Critical)

Money Rules (Hard Requirements)

All currency stored as integer cents (bigint)

All percentages stored as basis points (int)

Quantities stored as numeric

No floats. Ever.

Estimating

estimate_templates

id

org_id

name

default_markup_bps

notes

archived_at

assemblies

id

org_id

template_id

name

kind (labor|equipment|materials|mobilization)

uom

default_qty numeric

default_unit_cost_cents bigint

production_rate numeric null

sort_order

estimates

id

org_id

customer_id

template_id null

status (draft|sent|approved|rejected)

subtotal_cents

markup_bps

total_cents

pricing_snapshot jsonb

job_site jsonb

assumptions text

created_by

estimate_line_items

id

estimate_id

assembly_id null

name

kind

qty numeric

unit_cost_cents

unit_price_cents

line_total_cents

sort_order

7. Jobs & Field Execution

jobs

id

org_id

estimate_id

status (ready|in_progress|completed|invoiced)

scheduled_date date

job_site jsonb

scope_snapshot jsonb

created_at

Event Log (Append-Only)

job_events

id uuid pk

org_id

job_id

client_event_id uuid

type enum

start

complete

note

labor_hours

equipment_usage

photo_add

photo_remove

adjustment

payload jsonb

created_by

device_ts

created_at

Unique (org_id, client_event_id)

Derived Data

job_actuals_summary

job_id pk

labor_hours numeric

equipment_hours numeric

notes_count

photos_count

last_event_at

job_variances

job_id pk

estimate_totals_cents jsonb

actual_totals_cents jsonb

variance_cents jsonb

signal enum (ok|warn|bad)

8. Invoicing & QuickBooks

invoices

id

org_id

job_id

status (draft|sent_to_qbo|paid|void)

line_items_snapshot jsonb

total_cents

qbo_invoice_id text

created_at

qbo_connections

org_id pk

realm_id

access_token encrypted

refresh_token encrypted

token_expires_at

scopes

connected_at

9. API Surface (Primary)

Core

POST /api/estimates

POST /api/estimates/:id/approve

POST /api/jobs/:id/events

POST /api/jobs/:id/events/batch

GET /api/jobs/:id

POST /api/invoices/from-job/:jobId

POST /api/invoices/:id/push-to-qbo

Foreman PIN

POST /api/foreman/pin/set

POST /api/foreman/pin/reset

POST /api/foreman/pin/lock

10. Storage

Bucket: job-photos (private)

Path: org/{org_id}/jobs/{job_id}/{uuid}.jpg

Upload via signed URLs

Read via short-TTL signed URLs only

11. Security & Integrity

RLS on every table

Server-derived org_id only

Idempotency enforced at DB level

Audit log for:

Estimate approval

Job completion

Invoice push

PIN resets

Rate limiting on:

Auth

Event ingestion

QBO endpoints

12. Testing & CI

Required Tests

Unit

Pricing math (decimal correctness)

Markup bps logic

Variance signals

Integration

Supabase migrations + RLS policies

Event idempotency

E2E

Estimate → Job

Offline job execution → sync → invoice

CI

Lint

Typecheck

Unit

Integration

E2E

Vercel Preview Deploys per PR

13. Explicit Non-Goals (MVP)

Full local-first replication

Multi-foreman concurrent editing conflict resolution

Automated template mutation

ERP integrations beyond QBO

14. Design & UX Governance

All user-facing functionality MUST comply with the

"PavingOS Design Contract (MVP)".

The Engineering Spec defines system behavior and constraints.

The Design Contract defines interaction rules, friction limits, and experience principles.

In cases of conflict:

Data integrity > UX polish

Field usability > office convenience

Design Contract > ad-hoc UI decisions