Project documents& migration uploads

Keep drawings, specs, WinQS exports, and DimX takeoffs with the project — controlled by the same practice permissions as your BoE and BoQ data.

Everything you need
for project documents

Store drawings, specs, and WinQS migration uploads with the same practice permissions as your bills and valuations.

Tied to the project

Documents sit alongside Auth and Postgres project data — one permission model for the practice.

Fast uploads & fetches

Thin API layer for migration packs and tender documents — ready when the team needs them.

Folders that match QS work

Organize drawings, imports, and specs the way your practice already thinks about project files.

QSNAPP keeps drawings, WinQS exports, and bills together. We don't need a separate drive for migration packs and another tool for the BoQ.

QS
Senior quantity surveyorMulti-office practice

Document spaces
for every project stage

Project documents

  • Store drawings, PDFs, and specs
  • Attach files to projects and bills
  • Fine-grained practice access controls
  • Keep tender packs with the estimate

Migration uploads

  • WinQS and DimX export packages
  • Track import jobs next to source files
  • Retain originals for audit trails
  • Move cleanly into BoE or BoQ

Practice archives

  • Issued certificates and VO packs
  • Client deliverables by project
  • Role-based download permissions
  • Searchable project history

Simple and convenient
document APIs

Upload migration packs and project files with the same auth context as the rest of QSNAPP.

// Upload a WinQS export to project documents
const file = event.target.files[0]
const { data, error } = await qsnapp.documents
  .from('imports')
  .upload(`${projectId}/winqs-export.zip`, file)
Documentation

Integrates natively
with practice auth

Document authorization uses the same Postgres policies as project membership — SQL you can audit with the rest of QSNAPP.

create policy "Project members can read documents"
on storage.objects for select
using (
  bucket_id = 'documents'
  and (storage.foldername(name))[1] in (
    select project_id::text from project_members
    where user_id = auth.uid()
  )
);
Documentation

Estimate this week, scale the practice