Construction planning and field management, in one place.
FieldFlow gives superintendents, project managers, and project engineers a single source of truth for the schedule, the field, and the paper trail — a spreadsheet-fast scheduler, an executive dashboard, and complete field records (daily logs, inspections, delays, change orders, RFIs, Submittals, and Punch Lists) with their supporting documents.
▶ Try FieldFlow now — no setup required.
- Click Explore the demo on the landing page (credentials are prefilled), then Create account.
- Choose Load Sample Project — FieldFlow seeds Riverside Medical Center — Phase 2 (a 15-activity schedule, crews, logs, inspections, and change orders) in about ten seconds, with live progress.
- You land on the Project Dashboard: aggregate project summary, Attention Required, Upcoming Schedule, Workflow Analytics, and Recent Updates.
- Dashboard — scan project KPIs, items requiring attention, upcoming tasks, workflow status, and recent updates.
- Schedule — set the independent Data Date, update leaf-task progress, click any cell to edit inline (Enter saves, Escape cancels), select a row, drag to reorder, and indent/outdent to build a hierarchy.
- Capture a named baseline, review textual workday and critical-path changes, then open Look-Ahead Planning to coordinate three weeks of live work by readiness, blocker, commitment, company, and weekly period.
- Open Resource Loading to assign crews and equipment, configure dated capacity, and review demand, utilization, and conflicts without moving task dates.
- Open Schedule Summary to review explainable health reasons, baseline finish variance, progress exceptions, field blockers, resource conflicts, and the bounded executive schedule report.
- Change Orders — create or edit a numbered record, track cost and schedule impact, filter by status, and use the accessible delete flow.
- Shrink the window — the persistent rail and record tables adapt down to phone widths.
Superintendents run the job from the field, but the schedule lives in one tool, daily logs in another, and change orders in email. FieldFlow puts the CPM-style schedule and the field record set behind one login, so the 6:30 AM question — "what needs my attention today?" — has a one-screen answer.
- React 19 + Vite SPA with lazy-loaded routes and a hand-rolled, refresh-safe hash router.
- FastAPI backend with a layered domain/services architecture, SQLAlchemy ORM, and Alembic migrations on PostgreSQL.
- Hardened authentication with memory-only access JWTs, rotating opaque refresh sessions, replay-family revocation, CSRF and exact-Origin checks, database-backed user validation, single-flight refresh, cross-tab logout, and production configuration validation.
- Interactive scheduler: spreadsheet-style inline editing, multiple Finish-to-Start, Start-to-Start, Finish-to-Finish, and Start-to-Finish dependencies with signed lead/lag; milestone tasks; eight standard constraints; workday/holiday-aware date math; independent persistent Schedule Start and Data Dates, status-aware recalculation, actual dates, remaining duration, percent complete, out-of-sequence detection, deterministic summary-predecessor rollups, parent/child hierarchy, validated subtree ordering, and keyboard-accessible drag-and-drop reordering (dnd-kit).
- Immutable schedule baselines and variance: coherent project snapshots, persistent comparison selection, active/archive history, stable task-ID matching, workday start/finish variance, critical and structural change analysis, and a responsive table-first comparison workflow.
- Construction look-ahead planning derived from the live schedule, with Data Date anchored 7-42 day windows, three-week grouping, carryover work, readiness, blockers, commitments, project-company assignment, controlled include/exclude overrides, archived read-only plans, and print output.
- Construction resource planning with project-owned labor crews and equipment, whole-number task allocations, project-company crew association, inclusive dated capacity overrides, live progress-aware workday loading, textual utilization and conflict details, unassigned-task reporting, look-ahead assignment labels, and browser-printable output. Resource conflicts never mutate the canonical schedule.
- Explainable schedule health and executive reporting with explicit stable/attention/critical rules, baseline and Data Date context, bounded factual reasons and attention items, a fifth Scheduler summary mode, one dashboard aggregate request, and an authenticated executive PDF.
- Dynamic Gantt chart rendered from the same task data with progress, milestone diamonds, constraint markers, labeled dependency connectors, and a Data Date marker, plus a progress-aware one-click PDF export.
- Project Dashboard and Analytics backed by one authenticated, project-owned aggregate endpoint: schedule, RFI, Submittal, Punch Item, Change Order, Daily Log, and document summaries; bounded Attention Required, Upcoming Schedule, Workflow Analytics, Recent Updates, and bounded explainable Schedule Health; stale-response protection; and no dashboard collection fan-out.
- Project-scoped RFI workflow with server-assigned sequential numbering, Open/Pending/Closed states, responsible-company assignment, due-date and overdue tracking, and authenticated ownership enforcement.
- Project-scoped Submittals workflow with permanent sequential
SUBnumbering; Draft, Submitted, Under Review, Approved, Revise and Resubmit, and Rejected states; responsible-company and reviewer tracking; required-by, reviewed-date, and overdue tracking; dashboard workflow metrics; and authenticated ownership enforcement. - Project-scoped Punch Lists workflow with permanent sequential
PUNCHnumbering; Open, In Progress, Completed, and Verified states; Low, Medium, High, and Critical priorities; location, trade, responsible-company, and assignee tracking; due-date, completion-date, and overdue tracking; dashboard workflow metrics; and authenticated ownership enforcement. - Enhanced project-scoped Change Orders workflow with backend-assigned,
permanent
COnumbering; eight lifecycle statuses; proposed and approved fixed-precision amounts; schedule impact, lifecycle dates, title, description, reason, company, and responsible-party tracking; full create/edit/delete and filtering flows; legacy-record compatibility; dashboard workflow and cost metrics; recent updates; and authenticated ownership enforcement. - Reusable Document Management across Projects, Daily Logs, RFIs, Submittals, Punch Items, and Change Orders, with multiple-file upload, authenticated streaming, secure validation, local or private S3-compatible storage, accessible previews and deletion, and durable object cleanup.
- Document storage foundation with a provider-neutral interface, opaque sharded object keys, safe metadata-only APIs, SHA-256 checksums, hierarchical project folders, soft deletion, and fields reserved for future document version history.
- Project Document Explorer with nested folder browsing, breadcrumbs, metadata search, allowlisted filtering and sorting, bounded pagination, recent documents, batch and drag-and-drop uploads, metadata inspection, authenticated downloads, and soft deletion.
- Construction Drawing Management with project-owned drawing sets, allowlisted disciplines, a searchable drawing register, set-scoped sheet identities, atomic PDF revision upload and superseding, retained revision history, formal draft/issued/void issues, authenticated downloads, and a secure in-browser PDF viewer for current and historical revisions.
- Project document content search with durable extraction jobs, native page-level PDF text extraction, PostgreSQL full-text indexing, bounded snippets, exact drawing-revision navigation, and an explicit OCR provider boundary. Production OCR remains disabled until a deployable provider is approved.
- Construction record relationships with explicit project-scoped links across Documents, drawing records, RFIs, Submittals, Punch Items, Change Orders, and Daily Logs; controlled direction and reverse labels, bounded candidate search, retained unavailable-record context, and lazy per-record panels without table-row or dashboard request fan-out.
- Provider-neutral AI preconstruction foundation with project-owned review sets, controlled document roles, checksum- and extraction-pinned immutable manifests, deterministic readiness, durable leased analysis attempts, and a lazy review workspace. Immutable content preparation adds durable runs, checksum-bound snapshots, one-based pages, bounded citeable segments, lineage/stale detection, and a plain-text source inspector. A controlled construction scope taxonomy then produces evidence-backed scope assertions with immutable assertion sets, deterministic content hashes and deduplication, server-derived evidence excerpts, append-only human review, and human-authored assertions. Production defaults to disabled OCR and AI providers. Deterministic cross-document comparison then produces evidence-backed findings for potential coverage gaps, conflicts, exclusions, and revision impacts, with named comparison plans, immutable finding sets, append-only human review, and an intentional-exclusion decision. A reviewer who accepts a finding can then raise a human-initiated follow-up that keeps the evidence trail and links the RFI, Change Order, or Submittal they created in that record's own workflow. M18.1-M18.5 perform no autonomous acceptance, no automatic RFI, Change Order, procurement, or relationship creation, and no live AI call.
- Accessible design system: tokens, reusable UI primitives (Button, Card,
Sidebar, PageHeader, Icon, ConfirmDialog, Skeleton), skip links, focus
management,
aria-currentnavigation, and screen-reader-labeled loading states. - Responsive UI from desktop rail navigation down to stacked mobile record cards.
- Client-side onboarding: first-run detection seeds a realistic demo project through the public API with visible progress — the app is never empty.
- Automated testing: 1,220 tests — 656 frontend across 94 files (Vitest + React Testing Library, behavior- and accessibility-focused) and 564 backend tests plus 420 separately reported subtests (pytest, covering the scheduling engine, critical path, services, migrations, CORS, and TestClient API integration).
┌────────────────────┐ HTTPS / JSON ┌─────────────────────┐
│ React 19 SPA │ ───── REST + JWT ─────▶ │ FastAPI (Python) │
│ Vite · dnd-kit │ ◀──── JSON responses ── │ api → services → │
│ Accessible UI │ │ domain → models │
│ (Vercel) │ │ (Render) │
└────────────────────┘ └──────────┬──────────┘
│ │ SQLAlchemy
│ memory: access JWT; storage: onboarding flag │ + Alembic
▼ ▼
hash-based routes ┌─────────────────────┐
(refresh-safe, no │ PostgreSQL │
rewrite rules) └─────────────────────┘
How data flows: the SPA authenticates against /auth, keeps its
short-lived access JWT only in memory, and restores or rotates an opaque
HttpOnly refresh session through CSRF-protected cookie requests. Every
protected request carries the access token through a fetch wrapper that
centralizes one-retry 401 handling and cross-tab session events. Page
containers call REST endpoints (/projects/{id}/tasks,
/daily-logs, /inspections, /notes-delays, /change-orders, /rfis,
/submittals, /punch-items, …); the
FastAPI service layer applies the scheduling rules against each project's
persistent Schedule Start Date (dependencies, lag, summary rollups, and
workday/holiday calendars) and persists through SQLAlchemy models managed by
Alembic migrations. Responses return the full recalculated task set, so the
grid and Gantt always render from one consistent source. The project dashboard
uses one authenticated aggregate endpoint instead of loading each resource
collection. Backend queries calculate bounded summary metrics, attention
items, upcoming tasks, and recent updates; the frontend handles formatting,
navigation, loading, retry, cancellation, and stale-response protection.
The same aggregate includes bounded schedule health from the focused backend
service without loading schedule, baseline, look-ahead, or resource
collections. The lazy Schedule route loads the full executive summary on
demand and supports a separate authenticated executive PDF.
Document uploads also queue checksum-bound extraction work in their existing
transaction. A finite externally scheduled command opens the same private
object through the storage provider, persists bounded page text, and updates
PostgreSQL full-text vectors; project search remains a separate lazy route and
does not widen dashboard loading.
The complete dashboard hierarchy, API contract, request lifecycle, test
coverage, bundle history, and deferred work are documented in
docs/PROJECT_DASHBOARD.md.
The deterministic scheduling anchor, dependency and hierarchy contracts,
transaction boundaries, migration behavior, scale budgets, and known limits
are documented in docs/SCHEDULING.md.
The complete M17 capability, architecture, route/model inventory, health
policy, reporting boundary, and release limits are documented in
docs/ADVANCED_SCHEDULING.md, with focused
recovery and verification guides in
docs/SCHEDULE_OPERATIONS.md and
docs/SCHEDULE_QA.md.
The immutable snapshot lifecycle, comparison policy, variance formulas,
frontend workflow, and measured scale behavior are documented in
docs/SCHEDULE_BASELINES.md.
The Data Date, progress-state normalization, status-aware scheduling,
out-of-sequence policy, and progress UI contract are documented in
docs/SCHEDULE_PROGRESS.md.
Crew and equipment identity, task allocation, availability overrides,
progress-aware loading, over-allocation, APIs, security, and explicit
baseline, template, Daily Log, dashboard, and export boundaries are documented
in docs/RESOURCE_PLANNING.md.
The final authentication architecture, threat model, deployment checklist,
operational runbooks, manual QA guide, release notes, and deferred security
roadmap are documented in docs/SECURITY.md.
The complete M16 architecture, API and data-model inventory, migration chain,
production gate, and final bundle record are documented in
docs/DOCUMENT_MANAGEMENT.md. Focused provider,
transaction, explorer, and retention details remain in
docs/DOCUMENT_STORAGE.md.
Drawing terminology, models, normalization, revision transactions, issue
lifecycle, APIs, secure viewer behavior, and deferred drawing work are documented in
docs/DRAWING_MANAGEMENT.md.
Relationship terminology, the allowlisted entity and relationship matrix,
resolver and API design, lifecycle behavior, frontend integrations, and
deferred work are documented in
docs/DOCUMENT_RELATIONSHIPS.md.
Document extraction lifecycle, OCR capability boundaries, durable processing,
PostgreSQL indexing, ranking, APIs, frontend search, and operations are
documented in docs/DOCUMENT_SEARCH.md.
Deployment recovery procedures and the checkable live release matrix are in
docs/DOCUMENT_OPERATIONS.md and
docs/DOCUMENT_QA.md.
Change Orders use a focused service layer for validation and project-scoped
CO-### allocation. A persistent per-project sequence table prevents deleted
numbers from being reused, while a database constraint enforces number
uniqueness within each project. The enhancement migration preserves existing
rows and unique nonstandard numbers, repairs only missing or duplicate
numbers, backfills safely parseable legacy amounts into fixed-precision
NUMERIC(14,2) fields, and retains the original amount field for
compatibility.
FieldFlow keeps supporting documents attached to the records where teams use them: project documents, Daily Log attachments, RFI exhibits, Submittal packages, Punch Item evidence, and Change Order backup. Users can upload multiple files, retain duplicate display filenames, preview supported PDFs and images, download securely, and delete attachments. Deleting an RFI, Submittal, Punch Item, or Change Order also schedules durable cleanup of its stored objects.
flowchart LR
UI[AttachmentPanel] --> API[Authenticated Attachment API]
API --> VALIDATE[Ownership and File Validation]
VALIDATE --> STORAGE[Storage Adapter]
STORAGE --> LOCAL[Local Storage]
STORAGE --> S3[Private S3-Compatible Storage]
VALIDATE --> DB[(PostgreSQL Metadata)]
DB --> LIST[List Attachment Metadata]
API --> DOWNLOAD[Authenticated Streaming Download]
DOWNLOAD --> STORAGE
DB --> OUTBOX[(Cleanup Jobs)]
OUTBOX --> COMMAND[Cleanup Command]
COMMAND --> STORAGE
Upload lifecycle
- The user selects one or more files; frontend size and extension checks provide immediate advisory feedback.
- Each file is sent sequentially through an authenticated multipart API request, allowing partial success when one file fails.
- The backend verifies project ownership and parent identity, then validates size, MIME type, extension, filename, and file signature or container.
- The storage adapter streams the file to local or private S3-compatible storage while calculating SHA-256.
- PostgreSQL metadata is committed only after storage succeeds. Public API responses never expose credentials or object keys.
Download and preview lifecycle
- The browser requests an attachment through the authenticated API.
- The backend verifies project ownership and streams content from storage.
- PDF, JPEG, PNG, and WebP files may open inline; other supported formats download as attachments.
- The frontend uses temporary Blob URLs for previews and downloads and revokes them after use.
Deletion lifecycle
- Standalone deletion records a durable cleanup job and removes attachment metadata transactionally. After commit, object deletion is attempted; provider failures remain queued for retry.
- Parent deletion first preserves every storage key in cleanup jobs, then removes attachment metadata and the parent in one database transaction. Remote cleanup runs after commit, so a provider outage does not block the successful deletion of the parent record.
- Missing objects are handled idempotently as completed cleanup work.
The shared authenticated API is intentionally resource-neutral:
GET /projects/{project_id}/attachmentslists one parent's metadata.POST /projects/{project_id}/attachmentsuploads multipart file content.GET /projects/{project_id}/attachments/{attachment_id}/downloadstreams authenticated preview or download content.DELETE /projects/{project_id}/attachments/{attachment_id}removes one attachment and records durable cleanup work.
PostgreSQL stores metadata, checksums, provider names, and opaque storage keys; it does not store file contents. Local storage is intended for development, lives outside the frontend source tree, uses create-only bounded writes, and removes partial files after failures. Local files on an ephemeral production instance may be lost during redeployment.
The s3 adapter stores private objects in AWS S3 or an S3-compatible service.
Region, endpoint, addressing style, key prefix, transport, timeouts, and
retries are configurable. Reads and writes are streamed, no public-read ACL
is applied, and browsers never receive direct object access or storage keys.
Client construction is lazy, so importing or starting the application does
not contact S3. Persistent private object storage is recommended for
production.
The authoritative backend limit is 25 MiB per file. Supported formats are PDF, JPEG, PNG, WebP, HEIC/HEIF, TXT, CSV, DOC, DOCX, XLS, and XLSX. Validation includes extension and MIME consistency, strong signatures for PDF and supported images, OLE or ZIP container signatures for Office files, UTF-8 and NUL-byte checks for text files, zero-byte rejection, filename normalization, path-traversal protection, bounded streaming, and SHA-256 calculation. Browser checks are advisory; backend validation is authoritative. FieldFlow does not currently perform antivirus scanning.
| Resource | Parent type | Upload | Preview | Download | Attachment delete | Parent-delete cleanup |
|---|---|---|---|---|---|---|
| Project | project |
Yes | Yes | Yes | Yes | Not applicable until project deletion exists |
| Daily Log | daily_log |
Yes | Yes | Yes | Yes | Not applicable until Daily Log deletion exists |
| RFI | rfi |
Yes | Yes | Yes | Yes | Yes |
| Submittal | submittal |
Yes | Yes | Yes | Yes | Yes |
| Punch Item | punch_item |
Yes | Yes | Yes | Yes | Yes |
| Change Order | change_order |
Yes | Yes | Yes | Yes | Yes |
Preview availability depends on the file type and browser; FieldFlow exposes preview controls for PDFs and browser-renderable JPEG, PNG, and WebP images.
Shared attachment API functions support list, multipart upload, authenticated
Blob download, and delete. useAttachments owns request state, sequential
multiple-file uploads, partial-success reporting, stale-response protection,
Strict Mode request deduplication, AbortSignal cancellation, Blob URL
cleanup, and identity resets. AttachmentPanel supplies the reusable upload,
list, preview, download, error, empty, loading, and confirmation UI.
Each resource lazily mounts at most one active panel, so attachments are not
preloaded for every visible record or by the dashboard. Attachment state
stays out of useProjectResource and useRecordForms; changing projects or
active parents clears stale state.
Accessibility support includes associated file-input labels,
keyboard-accessible upload and expansion controls, semantic file lists,
filename-specific action labels, aria-expanded, aria-controls, live upload
and error announcements, accessible confirmation dialogs with focus
restoration, non-color-only drag feedback, and responsive wrapping for long
filenames and actions. These practices are tested, but are not presented as a
formal WCAG certification.
Cleanup jobs transactionally preserve storage work across the PostgreSQL and
object-storage boundary. Processing records attempts, applies bounded
exponential backoff, recovers interrupted Processing jobs after a lease,
treats missing objects idempotently, retains completed jobs for a configurable
period, and supports reconciliation and pruning. Jobs use the exact statuses
Pending, Processing, Completed, and Failed.
python -m app.commands.process_attachment_cleanup
python -m app.commands.process_attachment_cleanup --batch-size 50 --max-jobs 200
python -m app.commands.process_attachment_cleanup --prune-completedSupported options are --batch-size, --max-jobs, and --prune-completed.
Production must invoke this command through an external recurring scheduled
job. FieldFlow does not include a built-in worker or scheduler, and
render.yaml does not currently declare a scheduled cleanup job.
Scheduling
- Spreadsheet-style schedule editing with full keyboard support
- Independent persistent Schedule Start Date and Data Date with deterministic, status-aware recalculation
- Not Started, In Progress, and Completed leaf-task progress with percent complete, remaining duration, actual dates, and server-recorded update data
- Progress-derived project summary and visible out-of-sequence context without a second task request
- Multiple Finish-to-Start, Start-to-Start, Finish-to-Finish, and Start-to-Finish dependencies with signed lead/lag
- Zero-duration milestones and ASAP, ALAP, start/finish no-earlier/no-later, mandatory-start, and mandatory-finish constraints
- Leaf dependencies on nested summary tasks with deterministic date rollups
- Workday scheduling that skips weekends and federal holidays
- Parent/child task hierarchy with indent/outdent, collapse, and validated parent-before-descendant contiguous ordering
- Hierarchy-safe drag-and-drop ordering (pointer and keyboard)
- Immutable named schedule baselines with active and archived history
- Workday start/finish variance, duration and float comparison, critical-path changes, and explicit task-structure change indicators
- Searchable, filterable, paginated Baseline Comparison view with textual summary metrics and stacked mobile records
- Named live Look-Ahead Plans with a Data Date default, 7-42 day windows, weekly groups, carryover, readiness, blockers, commitments, company/trade filters, manual overrides, archival, and print-friendly output
- Project-owned crews and equipment, task allocations, dated availability, progress-aware Resource Loading, explicit over-allocation/unavailability, unassigned-work reporting, bounded conflicts, and print-friendly output
- Explainable stable/attention/critical Schedule Health with visible thresholds, baseline and Data Date context, executive metrics, bounded top attention items, and an authenticated executive schedule PDF
- Progress-aware Gantt visualization with milestone, constraint, and labeled dependency indicators, plus current-schedule PDF export
- Reusable schedule templates
Project Dashboard and Analytics
- Aggregate project summary for schedule, RFIs, Submittals, Punch Items, Change Orders, Daily Logs, and documents
- Bounded Schedule Health with factual reasons, finish variance, blockers, and resource conflicts from the same aggregate request
- Bounded Attention Required and Upcoming Schedule lists with direct project-workflow navigation
- Workflow Analytics for RFI, Submittal, Punch Item, and Change Order status counts, including exact backend-aggregated Change Order values
- Recent Updates across RFIs, Submittals, Punch Items, Change Orders, and attachments
- One project-owned aggregate request with loading, retry, cancellation, Strict Mode deduplication, and stale-response protection
- Accessible headings, semantic lists and timestamps, contextual link names, keyboard focus, reduced motion, and responsive mobile-to-ultrawide layouts
Field records
- Daily logs, inspections, and notes & delays
- Project-scoped Change Order creation, editing, and deletion with
backend-generated permanent
COnumbering and authenticated ownership enforcement - Draft, Pending, Submitted, Under Review, Approved, Rejected, Executed, and Void workflow with title, description, reason, company, and responsible-party tracking
- Fixed-precision proposed and approved amounts, whole-day schedule impact, and requested, submitted, approved, and executed lifecycle dates
- Legacy Change Order compatibility, status filtering, validation, recent Change Order display, and merged activity-feed support
- Project-scoped RFI creation, editing, and deletion with responsible-company assignment and Open, Pending, or Closed workflow
- Sequential per-project RFI numbering with due-date and overdue tracking
- Project-scoped Submittal creation, editing, and deletion with responsible-company and reviewer tracking
- Sequential per-project
SUBnumbering; Draft, Submitted, Under Review, Approved, Revise and Resubmit, and Rejected workflow - Required-by and reviewed-date tracking with overdue Submittal detection
- Project-scoped Punch Item creation, editing, and deletion with location, trade, responsible-company, and assignee tracking
- Sequential per-project
PUNCHnumbering; Open, In Progress, Completed, and Verified workflow; Low, Medium, High, and Critical priorities - Due-date and completion-date tracking with overdue Punch Item detection
- Authenticated ownership enforcement across project Change Order, RFI, Submittal, and Punch Item operations
- Search, filtering, status badges, and responsive record cards
- Project-company management
Document management
- Project documents and attachments for Daily Logs, RFIs, Submittals, Punch Items, and Change Orders
- Provider-neutral document storage with local and S3-compatible adapters
- Hierarchical project folders and safe document metadata APIs
- Opaque sharded storage keys, streamed SHA-256 checksums, and version-ready metadata
- Project Document Explorer with folder tree, breadcrumbs, recent documents, metadata details, search, filtering, sorting, and pagination
- Single, multiple, and drag-and-drop uploads with per-file results, partial success, and retry
- Authenticated downloads and confirmed soft deletion without provider-path exposure
- Multiple-file upload with independent results and duplicate display filename support
- Authenticated PDF and image previews, streamed downloads, and attachment deletion
- Secure backend file validation and project ownership enforcement
- Local development storage and private S3-compatible production storage
- Durable standalone and parent-deletion object cleanup
- Drawing sets, allowlisted disciplines, set-scoped normalized sheet numbers, current and superseded PDF revisions, formal drawing issues, and a project-scoped drawing register
- Drawing-linked documents remain visible in the explorer, while ordinary explorer deletion is blocked to protect revision history
- Lazy, authenticated PDF viewer with current/historical revision routes, page and sheet navigation, bounded thumbnails, zoom modes, selectable text, existing-text search, metadata, and one-session download reuse
- Explicit relationships across ten construction entity types with controlled direction, reverse labels, bounded candidate search, safe unavailable-record history, and one lazily mounted panel per active record context
Product quality
- Branded landing/login, first-run onboarding with demo seeding
- Icon system, confirmation dialogs, toast notifications, loading skeletons
- WCAG-minded semantics: skip links, focus traps,
aria-liveannouncements
(Capture checklist: docs/screenshots/README.md)
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite 8, dnd-kit, Inter (self-hosted) |
| Backend | FastAPI, SQLAlchemy, Alembic, Pydantic |
| Database | PostgreSQL |
| Auth | Memory-only access JWT + rotating opaque refresh sessions |
| Testing | Vitest + React Testing Library (656), pytest (564) |
| Hosting | Vercel (frontend) · Render (API + migrations + finite extraction and preparation crons) |
1,220 primary automated tests passed. Backend subtests are reported separately rather than added to that total.
- Frontend (656 across 94 files) — Vitest + React Testing Library. Tests target behavior and accessibility: roles and names, keyboard flows (Enter/Escape editing, grid cursor navigation, focus traps), aggregate dashboard rendering, demo-seeding orchestration, App-level integration wiring, the HTTP transport layer, and loading/empty/error states. Attachment coverage includes API clients, advisory validation, sequential multiple-file uploads, partial success, stale-response protection, previews, downloads, Blob URL cleanup, confirmation and accessibility behavior, all six resource integrations, and request-count behavior. Document Explorer coverage includes routing, folder navigation, breadcrumbs, query controls, pagination, batch uploads, partial failures, stale-response protection, details and delete dialogs, focus restoration, status-specific failures, and responsive folder access. Drawing coverage includes routing, register queries, project switching, stale requests, set and sheet workflows, revision upload/history/download/viewing, issue membership, viewer routing, request cancellation, PDF security settings, page/zoom/search controls, Blob cleanup, confirmations, focus restoration, and advisory PDF validation. Relationship coverage includes API requests, hook deduplication and stale response handling, bounded keyboard candidate selection, direction-aware rendering, deletion, navigation, and all supported page integrations. Document-search coverage includes safe API encoding, explicit-submit and stale-request hooks, extraction state and reprocessing, plain-text snippet highlighting, filters, pagination, exact result navigation, and lazy route integration. Scheduling-foundation coverage includes the persistent project anchor, confirmation and retry behavior, mutation deduplication, project-switch cancellation, and stale response and rollback rejection. Baseline coverage adds capture validation, selection and archive lifecycle, focus-managed dialogs, textual variance summaries, task classifications, filtering, sorting, pagination, local retries, and responsive table labels. Progress coverage adds independent Data Date controls, conditional progress entry, loading and correction flows, actual and forecast dates, textual summaries, visible out-of-sequence context, project-switch clearing, and one canonical task request. Advanced planning coverage adds milestones, constraints, multiple dependency editing, signed lead/lag, all four relationship types, accessible dialog behavior, and Gantt indicators. Look-ahead coverage adds API encoding, default selection, mutation deduplication, stale project/plan rejection, weekly grouping, carryover, metadata editing, manual overrides, print behavior, and archived read-only presentation. Resource-planning coverage adds crew and equipment CRUD, availability overrides, assignment flows, bounded loading filters, utilization and conflict text, stale-response rejection, and scheduler and look-ahead integration. Preconstruction coverage adds API encoding, lazy routing, review/source/run lifecycle controls, deterministic readiness, preparation actions, stale project/review/content rejection, bounded plain-text inspection, keyboard source selection, focus restoration, and explicit no-binary/no-dashboard request assertions.
- Backend (564, plus 944 separately reported subtests) — pytest. Covers the deterministic workday scheduling engine (persistent anchors, all four dependency types, multiple predecessors, signed lead/lag, milestones, constraints, summary predecessors, hierarchy ordering, federal holidays), critical path and total float, immutable baseline capture, rollback and ownership, stable-ID variance matching, workday variance, critical and structural changes, bounded queries, scale probes, and migration lifecycle, Data Date persistence, progress lifecycle and correction rules, status-aware forecasting, out-of-sequence detection, progress summaries, transactional rollback, and progress-aware baseline variance and export, task services, relationship migrations, CORS configuration, and TestClient API integration (auth, ownership enforcement, task lifecycle, Change Orders, RFIs, Submittals, Punch Lists, and field records over HTTP). Attachment coverage includes authentication, ownership and parent resolution, streaming upload/download, file validation, local and S3 adapters, S3 error classification, deletion cleanup, retries, leases, reconciliation, migration safety, and parent-deletion cleanup. Document foundation coverage includes provider contracts, folder integrity, authorization, secure upload/download, checksums, rollback, soft deletion, response exposure, migration cycles, explorer counts and breadcrumbs, escaped metadata search, filtering, stable sorting, pagination, recent documents, and project isolation. Drawing coverage includes ownership, normalized uniqueness, PDF validation, revision sequencing and rollback, one-current constraints, issue lifecycle, safe register responses, explorer retention, and migration reversibility. Relationship coverage includes migration constraints, all ten resolvers, directional and symmetric creation, duplicate prevention, filtering, pagination, authorization, unavailable targets, transaction rollback, and bounded candidate search. Security coverage includes strict JWT claims, rotating refresh sessions, replay revocation, CSRF, exact CORS origins, rate and body limits, route-wide ownership, transaction rollback, safe errors, production configuration, logging redaction, and health behavior. Extraction and search coverage includes PDF/raster boundaries, deterministic OCR-provider tests, checksums, limits, durable claims and retries, migration lifecycle, status and reprocess authorization, project isolation, ranking, bounded snippets, and drawing-revision enrichment. Look-ahead coverage includes ownership, strict schemas, live inclusion, weekly grouping, readiness and blocker metadata, company validation, manual overrides, archive behavior, migration lifecycle, bounded queries, and 100/500/2,000 task scale cases. Preconstruction coverage adds the two-user ownership matrix, source/extraction snapshots, immutable manifests, provider contract validation, leased retries and recovery, migration lifecycle, safe response fields, immutable page/segment preparation, lineage staleness, atomic rollback, bounded retrieval, and 10/100/250-source probes.
# frontend
cd frontend && npm test && npm run lint && npm run build
# backend
cd backend && pytestpython -m venv venv
venv\Scripts\activate # Windows
pip install -r requirements.txtCreate backend/.env:
DATABASE_URL=postgresql://postgres:YOUR_PASSWORD@localhost:5432/scheduler_db
APP_ENV=development
APP_DEBUG=false
SECRET_KEY=replace-with-a-long-random-secret
REFRESH_TOKEN_SECRET=
ALLOWED_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
COOKIE_SECURE=false
COOKIE_SAMESITE=lax
ATTACHMENT_STORAGE_PROVIDER=localRun migrations and start the API (docs at http://127.0.0.1:8000/docs):
alembic upgrade head
uvicorn app.main:app --reloadnpm install
npm run dev # http://localhost:5173Set VITE_API_URL when pointing at a deployed API. Authentication requests
default to a 10-second timeout; use VITE_AUTH_REQUEST_TIMEOUT_MS only when a
different bounded deployment value is required.
Local development should use ATTACHMENT_STORAGE_PROVIDER=local unless an
S3 integration is intentionally being tested. The following variables match
backend/.env.example. The established
ATTACHMENT_* prefix is retained for deployment compatibility and configures
the shared provider used by both attachments and Documents.
| Group | Variable | Purpose |
|---|---|---|
| Provider | ATTACHMENT_STORAGE_PROVIDER |
local or s3 |
| Local | ATTACHMENT_LOCAL_STORAGE_ROOT |
Optional absolute or expanded local root; blank uses backend/.attachment_storage |
| File limits | ATTACHMENT_MAX_UPLOAD_SIZE |
Maximum bytes per file; default 26214400 |
| File limits | ATTACHMENT_UPLOAD_CHUNK_SIZE |
Backend streaming chunk size; default 65536 |
| File limits | ATTACHMENT_PERMITTED_MIME_TYPES |
Optional comma-separated MIME override; defaults cover the shipped PDF, image, text, Word, and Excel formats |
| S3 | ATTACHMENT_S3_BUCKET |
Private bucket name; required in s3 mode |
| S3 | ATTACHMENT_S3_REGION |
Bucket region; required in s3 mode |
| S3 | ATTACHMENT_S3_ENDPOINT_URL |
Optional HTTPS endpoint for compatible providers |
| S3 | ATTACHMENT_S3_ACCESS_KEY_ID |
Secret access-key identifier; required in s3 mode |
| S3 | ATTACHMENT_S3_SECRET_ACCESS_KEY |
Secret access key; required in s3 mode |
| S3 | ATTACHMENT_S3_SESSION_TOKEN |
Optional temporary session token |
| S3 | ATTACHMENT_S3_ADDRESSING_STYLE |
auto, path, or virtual |
| S3 | ATTACHMENT_S3_SECURE_TRANSPORT |
Require secure transport; default true |
| S3 | ATTACHMENT_S3_KEY_PREFIX |
Optional normalized object-key prefix |
| Timeouts/retries | ATTACHMENT_S3_CONNECT_TIMEOUT |
Connection timeout in seconds |
| Timeouts/retries | ATTACHMENT_S3_READ_TIMEOUT |
Read timeout in seconds |
| Timeouts/retries | ATTACHMENT_S3_MAX_RETRIES |
Provider retry limit |
| Cleanup | ATTACHMENT_CLEANUP_BATCH_SIZE |
Jobs claimed per cleanup batch |
| Cleanup | ATTACHMENT_CLEANUP_MAX_ATTEMPTS |
Maximum attempts before Failed |
| Cleanup | ATTACHMENT_CLEANUP_RETRY_BASE_SECONDS |
Initial exponential-backoff delay |
| Cleanup | ATTACHMENT_CLEANUP_RETRY_MAX_SECONDS |
Backoff ceiling |
| Cleanup | ATTACHMENT_CLEANUP_LEASE_SECONDS |
Recovery age for interrupted jobs |
| Cleanup | ATTACHMENT_CLEANUP_RETENTION_DAYS |
Completed-job retention before pruning |
Use placeholder values in local .env files and configure production
credentials as secret environment values. Render requires the S3 provider,
bucket, region, access-key ID, and secret access key shown in
render.yaml; configure an endpoint when the provider is not AWS. Never
commit production credentials.
- Frontend — Vercel. Hash-based routes keep every module refresh-safe with zero rewrite configuration. Live at construction-scheduler-eight.vercel.app.
- Backend — Render.
backend/render.yamldefines the web service, runs Alembic migrations on deploy, sets the health check, selects production mode and secure cross-site cookies, pins the exact CORS origin, selects private S3-compatible storage, runs the finite document extraction command every ten minutes, and runs the finite preconstruction content-preparation command on an offset quarter-hour schedule. The preparation cron carries no object-storage credential because it reads committed page text only. The preconstruction analysis worker is deliberately not scheduled while the AI provider is disabled — seedocs/AI_PRECONSTRUCTION_OPERATIONS.md. - Security release gate. Follow
docs/SECURITY.mdfor secret preparation, migration and restart order, rollback, post-deployment cookie/CORS/header checks, and incident runbooks. Dynamic Vercel preview origins are not trusted by wildcard. - Attachment storage. Production should use persistent object storage; Render's ephemeral local filesystem may be lost during deploys. Keep the bucket private, store credentials as secrets, and grant the application identity only the minimum operations needed to upload, read, delete, and check object existence.
- Cleanup scheduling. Run
python -m app.commands.process_attachment_cleanupas a recurring external scheduled job. The current Render blueprint declares the API, the extraction cron, and the preconstruction preparation cron, but not attachment cleanup, so cleanup scheduling remains an explicit deployment operation. Seedocs/DOCUMENT_OPERATIONS.md. - AI Preconstruction release review.
docs/AI_PRECONSTRUCTION_RELEASE.mdis the single document to read before deploying, operating, or extending the preconstruction platform: data, request, and worker flows; ownership, provider, and immutability boundaries; the 49-route API inventory; the 20-table data model; the six-migration chain; production configuration and deployment requirements; operational and maintenance procedures; and the known limitations at release. The manual test plan and screenshot checklist are indocs/AI_PRECONSTRUCTION_QA.md.
Shipped
- ✅ Design system, tokens, and reusable UI component layer
- ✅ Persistent project navigation shell with active-page state
- ✅ M14 Project Dashboard and Analytics with one project-owned aggregate endpoint, summary metrics, Attention Required, Upcoming Schedule, Workflow Analytics, Recent Updates, stale-response protection, accessibility, responsive hardening, and bounded request/bundle budgets
- ✅ M15 Authentication and Security Hardening with normalized identities, database-backed JWT validation, rotating refresh sessions, replay-family revocation, memory-only access tokens, CSRF and exact-Origin controls, route-wide ownership and validation hardening, request/rate limits, production configuration checks, and security operations documentation
- ✅ Project-scoped RFI workflow with sequential numbering, due-date tracking, ownership enforcement, and dashboard workflow metrics
- ✅ Project-scoped Submittals workflow with sequential numbering, complete review states, date validation, ownership enforcement, and dashboard workflow metrics
- ✅ Project-scoped Punch Lists workflow with sequential numbering, complete priority and status handling, date validation, ownership enforcement, and dashboard workflow metrics
- ✅ Enhanced project-scoped Change Orders workflow with persistent numbering, data-preserving legacy compatibility, fixed-precision financial fields, lifecycle and schedule-impact tracking, complete frontend CRUD and filtering, and dashboard workflow and cost metrics
- ✅ M13 Document Management across Projects, Daily Logs, RFIs, Submittals,
Punch Items, and Change Orders:
- M13.0 Architecture Audit
- M13.1 Backend Foundation
- M13.2 Production Storage and Durable Cleanup
- M13.3 Reusable Frontend Attachment System
- M13.4 Project and Daily Log Pilot
- M13.5 Remaining Resource Rollout
- M13.6 Documentation and Closeout
- ✅ M16.1 Document Storage Foundation with generic local and S3-compatible providers, opaque sharded keys, project-owned document metadata, hierarchical folders, checksums, soft deletion, secure streaming, and version-ready fields
- ✅ M16.2 Project Document Explorer with nested navigation, breadcrumbs, bounded metadata search, filtering, sorting and pagination, recent documents, batch uploads with retry, details, authenticated downloads, soft deletion, accessibility, and responsive layouts
- ✅ M16.3 Construction Drawing Management with drawing sets, allowlisted disciplines, normalized sheet registration, atomic PDF revisions, automatic superseding, retained history, formal drawing issues, searchable project register, explorer integration, accessibility, and responsive layouts
- ✅ M16.4 Secure Drawing Viewer with authenticated current/historical PDF rendering, project-scoped deep links, page/sheet/revision navigation, bounded thumbnails, zoom, selectable text, existing-text search, metadata, secure download reuse, accessibility, and responsive layouts
- ✅ M16.5 Construction Document Relationships with one project-scoped relationship model, an explicit ten-entity resolver and allowed-link matrix, directional and symmetric links, bounded candidate search, safe historical context, and lazy relationship workflows across documents, drawings, RFIs, Submittals, Punch Items, Change Orders, and Daily Logs
- ✅ M16.6 Document Text Extraction and Search with native page-level PDF
extraction, a production-disabled OCR provider boundary, durable leased
jobs, PostgreSQL
simplefull-text indexing, bounded safe snippets, project-scoped search, reprocessing, and exact drawing-revision navigation - ✅ M16.7 Document Management release readiness with final architecture, API/model and migration inventories, production configuration review, operational runbooks, manual QA, dependency/security gates, and reconciled test and bundle evidence
- ✅ M17.1 deterministic scheduling foundation with persistent project anchors, summary-predecessor rollups, atomic recalculation, hierarchy-safe reordering, database safeguards, and stale-mutation protection
- ✅ M17.2 immutable schedule baselines and variance analysis with coherent capture transactions, persistent comparison selection, archive history, workday and critical-path comparison, and a responsive table-first workflow
- ✅ M17.3 schedule progress and Data Date semantics with server-normalized leaf-task states, actual dates, remaining-duration forecasting, out-of-sequence context, progress-aware Gantt, variance, and PDF export, and one canonical task collection
- ✅ M17.4 milestones, eight standard constraints, multiple normalized predecessors, FS/SS/FF/SF relationships, signed lead/lag, advanced CPM and variance behavior, and accessible Gantt planning indicators
- ✅ M17.5 live schedule-derived Look-Ahead Plans with Data Date anchored three-week planning, weekly and carryover groups, readiness, blockers, commitments, company/trade ownership, manual overrides, archival, and print-friendly field coordination
- ✅ M17.6 project-owned crews and equipment, whole-number task allocations, dated availability, progress-aware loading, textual over-allocation, look-ahead labels, and browser-printable reporting without resource leveling
- ✅ M17.7 bounded, explainable schedule health, executive summary and PDF, single-request dashboard integration, fifth Scheduler summary mode, large-response hardening, operations/QA guides, and M17 release closeout
- ✅ M18.1 provider-neutral AI preconstruction foundation with project-owned review sets, controlled source roles, deterministic readiness, immutable checksum/extraction manifests, durable leased attempts, disabled/fake provider contracts, and a lazy review workspace with no live AI calls
- ✅ M18.2 immutable, extraction-lineage-pinned source snapshots with bounded page segments, durable preparation leases/retries, content-aware manifests, source preparation/readiness states, and safe plain-text inspection without production OCR, scope assertions, findings, or live AI calls
- ✅ M18.3 controlled construction scope taxonomy and evidence-backed, human-reviewed scope assertions with immutable assertion sets, deterministic content hashes and deduplication, server-derived evidence excerpts, append-only review history, human-authored assertions, and a bounded assertion review workspace without omission findings, cross-document comparison, or live AI calls
- ✅ M18.4 deterministic cross-document scope comparison and evidence-backed findings with twelve controlled comparison types, fourteen finding types with documented default severities, named match classes with explicit reason codes, named comparison plans locked by their first run, immutable finding sets, append-only review with a first-class intentional-exclusion decision, human-authored findings, and a bounded comparison workspace without automatic record creation or live AI calls
- ✅ M18.5 human-initiated follow-up actions from accepted findings with six controlled action types, a deterministic evidence-citing draft, a pinned acceptance review, linking to records created in their own workflows through the existing entity resolver, terminal completion or cancellation, and a bounded follow-up panel that creates no RFI, Change Order, Submittal, relationship, or notification
- ✅ M18.6 preconstruction performance, evaluation, and cost accounting with memoized tokenization, single-resolution comparison requests, one-scan summary aggregates, chunked persistence, an exact pair budget that refuses rather than truncates, opt-in manifest reuse, worker runtime budgets, a bounded read-only execution-metrics surface with absent-not-zero cost, and an offline deterministic evaluation suite and release command
- ✅ M18.7 AI Preconstruction release closeout with a full production-readiness and security review, documented data/request/worker flows, ownership, provider and immutability boundaries, final 49-route API and 20-table data model inventories, the six-migration chain, deployment and operational runbooks, a manual QA plan and screenshot checklist, and automated release guards for vocabulary totality, route ownership, and configuration drift
- ✅ Branded landing page and first-run demo seeding
- ✅ Icon system, confirmation dialogs, notifications, loading skeletons
- ✅ Scheduler showcase: WBS numbering, inline validation, critical path + float, federal-holiday calendar, today marker, keyboard grid navigation
- ✅ Engineering hardening: dashboard bundle optimization (chart library removed for CSS bars), error boundaries, App decomposition into feature hooks + router, targeted memoization and shared date utilities, backend DRY cleanup with TestClient API integration coverage
Next
- Weather-delay integration
- Timeline zoom
Future possibilities (not committed scope)
- Distributed rate limiting, password reset, email verification, MFA, OAuth, organizations, roles, audit logs, a same-site API domain, and expanded browser/security scanning
- General document and attachment version history, bulk download, thumbnails, and image galleries
- Drawing annotations, comparison, a deployable production OCR provider, antivirus integration, and document approvals
- Direct multipart browser uploads and bucket-wide orphan scanning
- A built-in background worker and cleanup-job administration interface
- Project and Daily Log parent-deletion workflows
- Automatic RFI, Change Order, procurement, and relationship creation, contract and purchase-order approval, autonomous acceptance, assignees and due dates on follow-ups, subcontractor notification, and live provider integrations, all of which require later separately reviewed milestones
Built by WarscherProgramming — construction-scheduler.







