Back to case studies

AVX-CS-003 · Construction SaaS · Product We Engineered

StructumAI Plans: Drawing & Field Collaboration Platform

A PlanGrid-class construction drawing, markup, and field-collaboration module built from the ground up, 26 tables, real-time multi-user collaboration, and a permission engine with 35 discrete access keys.

ProductStructumAI
Year2026
Engagement3-Month Build
FocusPDF Markup Engine · Real-Time Collaboration · Multi-Tenant SSO
StructumAI Plans: Drawing & Field Collaboration Platform
26

database tables

A production data model spanning plan sets, sheets, annotations, tasks, permissions, notifications, and scheduled reports.

35

permission keys

Across 9 categories with 6 role templates and per-user overrides, enforced centrally at the API layer, not just the UI.

48+

commits, solo build

Architecture, backend, frontend, database, and deployment, delivered end to end in roughly three months.

Executive Summary

What we built, and why it matters.

Plans is StructumAI's construction-drawing workspace, built to stand shoulder-to-shoulder with commercial tools like PlanGrid, Autodesk Build, and Fieldwire: upload blueprint sets, mark them up in the field, track punch-list and RFI-style tasks against exact drawing locations, compare drawing revisions, and roll all of it into reports, inside a secure, multi-tenant product that plugs into a larger platform without ever breaking its shared login.

Avrixo designed and built the module end to end: architecture, backend, frontend, database, and deployment, in roughly three months. The result is a production system with 26 database tables, a full role-based permission engine, real-time multi-user collaboration, scheduled report automation, and a hardened authentication contract now shared across the platform's other independently-deployed modules.

01

The Core Problem

The bottleneck beneath the business goal.

The module had to live inside an existing multi-tenant platform: sharing a single sign-on session issued by a separate API service, with no login screen of its own, and never surfacing a raw server error to a field user mid-shift on a job site. Mixed teams working the same drawing set, from GCs to subcontractors to engineers, each needed different visibility into the same sheets, enforced at the permission level, not just hidden in the UI.

It also had to support real construction workflows, not just 'draw on a PDF': scaled measurements, drawing-revision history, cross-sheet linked call-outs, CSI-coded stamp templates that generate tasks in one click, and a formal publish/archive lifecycle so draft markups don't leak to subcontractors before a foreman approves them, all while running reliably on a modest single server processing large, multi-hundred-page PDF sets without exhausting memory.

02

The Technical Solution

Engineered for accuracy, scale, and trust.

Multi-file PDF upload triggers automatic sheet extraction: every page of a plan set becomes an individually addressable, searchable sheet with a server-rendered thumbnail (pdfjs-dist + sharp / @napi-rs/canvas), full-text searchable via Postgres tsvector/GIN indexes. On top of that sits an 11-tool markup suite: pin, rectangle, circle, cloud, arrow, freehand, highlight, line, X-mark, text, and a custom 'worm' linked pin for cross-sheet call-outs, with per-annotation styling, undo/redo, and stamp placement that instantly generates a linked, pre-configured task.

A per-sheet scale-calibration tool derives a real-world scale factor from a reference line, driving a true-distance measure tool. Tasks are drawing-linked, first-class entities surfaced through a Task Center with rich filtering, saved views, and CSI MasterFormat 2018 stamp templates. Sheets carry full revision history with a side-by-side Compare view, plus a carry-forward workflow: review each open markup from the prior revision and mark it carried, skipped, or flagged with a confidence rating, every decision logged, solving the classic 'did we lose our punch list when the drawing was reissued?' problem.

Every annotation and task carries a publish / unpublish / archive state independent of its workflow status, so field staff can draft privately before a project admin publishes to the wider team. Pusher powers real-time collaboration: live cursors, a presence bar, and instant sync of annotations, tasks, and comments across users on the same sheet, while three report types (Task, Photo, Sheet) export to branded PDF, CSV, and XLSX, backed by a cron-driven Scheduled Reports engine running three production jobs with per-run status tracking.

Platform integration is the hardest constraint solved: the platform sets a shared JWT cookie on its root domain after login, and the module, deployed as a /plans sub-path of the same host specifically to avoid cross-origin cookie issues, verifies that same token server-side with the same secret, trusting { userId, tenantId, email } and scoping every query by tenant. No second login, no separate user table, no cross-origin dance. Avrixo authored the internal Module ↔ Platform Integration Guide used to onboard the platform's other modules onto this same pattern.

03

What's Inside

Every capability, grouped by workflow.

Drawing & Plan Management

  • Multi-file PDF upload with automatic sheet extraction and server-rendered thumbnails
  • Plan sets organized into tabs with processing / ready / error status tracking
  • Bulk sheet curation: multi-select, batch delete, rename, append-to-set
  • Full-text search across sheets and tasks (Postgres tsvector / GIN)

Markup & Annotation

  • 11 tool types, including a custom cross-sheet "worm" linked pin
  • Per-annotation styling, undo/redo history, floating toolbar, style panel
  • Stamp placement that instantly generates a pre-configured, linked task
  • Threaded comments with @mentions driving in-app and email notifications

Measurement & Field Tools

  • Per-sheet scale calibration (ft / in / m / cm / mm / yd)
  • True-distance measure tool driven by that calibration

Task Management

  • Drawing-linked tasks: status, priority, assignee, checklist, full change history
  • Task Center with rich filtering, saved/shareable views, and bulk actions
  • CSI MasterFormat 2018 stamp templates with default checklist and assignee
  • Document attachments via presigned S3, plus a generic Linked Objects layer to RFIs, submittals, and issues

Revisions & Lifecycle

  • Full revision history with a side-by-side Compare view
  • Carry-forward workflow: carried / skipped / flagged with confidence rating, fully audited
  • Publish / unpublish / archive state machine gated by permissions

Real-Time & Reporting

  • Pusher-based live cursors, presence bar, and connection-state indicator
  • 3 report types (Task, Photo, Sheet) exporting to branded PDF, CSV, and XLSX
  • Scheduled Reports: recurring cron delivery with per-run status and retry tracking

Permissions & Notifications

  • 35 permission keys across 9 categories, with 6 role templates
  • Per-user permission overrides and company / trade-group scoping
  • Full permission and membership audit log
  • 15+ typed notification events with per-user, per-type delivery preferences
04

Architecture Notes

System decisions that made the product viable.

Auth failing silently as a 500 instead of a clean 401: centralized every route's error handling through one apiErrorResponse() helper so an expired or missing token returns a proper 401, never a raw crash.

pdfjs-dist worker version mismatch: a hardcoded CDN worker URL silently broke PDF rendering once the installed package moved to a newer version, traced to the version pin and fixed at the source in both the viewer and compare view.

Out-of-memory crashes on large plan-set uploads: switched to sequential page rendering, explicit buffer freeing, lower render DPI, and a capped DB connection pool to keep multi-hundred-page uploads stable on a modest single server.

Schema drift between the handover spec and actual migrations: a production audit found 5 items referenced in code but missing from migrations, reconciled them, and confirmed one phantom table didn't exist anywhere before dropping it from the spec.

Tenant-context leak from a module-scoped dev shortcut: an early auth shortcut cached a dev identity at module load time, leaking one tenant's context into another's request under real traffic, replaced with a per-request getUserContext(req) call.

basePath-aware API client: every client-side call routes through a shared apiFetch wrapper that prepends the module's base path and always sends credentials, since a raw fetch/axios call would silently 404 or drop the auth cookie once deployed under /plans.

05

Tech Stack Matrix

Infrastructure behind the outcome.

Discuss a similar build

Experience Layer

Next.js 16 (App Router) · React 19 · Tailwind CSS 4 · Zustand

PDF & Media Pipeline

pdfjs-dist / react-pdf · pdf-lib · sharp / @napi-rs/canvas · jsPDF + autotable

Data & Real-Time

PostgreSQL (26 tables) · Pusher · AWS S3 (presigned URLs) · Zod Validation

Quality & Ops

Playwright E2E · JWT (HS256) Shared SSO · PM2 + Nginx · Ubuntu / AWS EC2

Start a Conversation

Need a system built like this?

Fixed scope, clear milestones, and a team that ships production systems end to end.