Skip to content
  • about
  • contact

A studio that ships software and shows its work.

hello@caparisonlab.com, Chittagong, Bangladesh

2026 Caparison Lab

  • work
  • capabilities
  • about
  • contact
  • RSS
work
web application

CinematicWorkflow

A self-hosted video review tool for editors and their clients: versioned cuts, timecoded notes, and share links that need no account.

Notes, versions and done state live behind one link. 1.80s cold load measured, and files over 100MB upload in 64MB parts to the user's own bucket.

ScopingArchitectureDatabase designFrontendBackendEdge functionsSecurity reviewDeploymentDocumentationWebEmbedded iframeSelf-hosted
year
2026
status
live
team
1

stack

next.jstypescriptpostgressupabasecloudflarevercelnext.jstypescriptpostgressupabasecloudflarevercelnext.jstypescriptpostgressupabasecloudflarevercelnext.jstypescriptpostgressupabasecloudflarevercel

The brief

Video review already lived inside the Caparison ERP, bolted to that system's role ACL and its shared tables. Two guest-link bugs were live in it. The share links table was readable by anonymous visitors, so anyone could list every active token and open every workflow behind them, and the workflow policy referenced itself, so a guest holding a valid link could read nothing.

The ask was to pull review out into an app that stands alone: its own schema, its own login, no dependency on the ERP. Deployable for one editor with their own Supabase project and their own bucket, and embeddable in the Build & Launch hub without forking the code.

What we built

A workflow holds a stack of video versions. Each version carries comments pinned to a timecode, a range, or a point on the frame, with threaded replies and file attachments. Two versions can play side by side, synced or independent. A workflow owner mints a share link, an unguessable uuid, and a client opens it with no account, works through the notes and ticks them off.

  • Versioned video nodes per workflow, added by upload or by pasting an existing Drive, Dropbox or server URL.

  • Comments anchored to a timecode, a time range, or a drawn rectangle on the frame, with threaded replies and attachments.

  • Compare mode running two versions side by side, with a playhead sync that can be switched off.

  • Done state on every comment, set by the owner or the guest, stored in the database rather than in component state.

  • Share links as one revocable uuid served by a single SECURITY DEFINER function: anonymous visitors have no table access anywhere in the app.

  • Per-user storage, where each account connects its own R2 bucket through a guided wizard. Keys are AES-256-GCM encrypted and no client role can read them back.

  • Direct-to-R2 uploads: a single PUT under 100MB, multipart in 64MB parts above it, three parts in flight, four retries on transient failures.

  • Two run modes from one codebase: standalone Supabase auth, or an RS256 hub token verified with an enforced aud claim.

One engineer, 13 commits between 21 July and 23 August 2026.

key decisions

  1. 01

    One RPC for guests, not anonymous row-level policies

    The ERP's two guest bugs were both the kind that direct anonymous table policies invite. A SECURITY DEFINER function takes an unguessable token and returns one fixed projection, so there are no anonymous-facing policies to get subtly wrong and no share links table to enumerate.

  2. 02

    Each user brings their own R2 bucket

    A shared developer bucket would make the studio custodian of every client's footage and payer of every byte. Per-user keys leave media, cost and liability with whoever uploaded it, with column-level grants that stop even the owner reading their own secret key back.

  3. 03

    Node serverless in Singapore, not Edge, because it was measured

    Functions defaulted to US East while Postgres sits in Singapore, costing 220 to 240ms on every server-side query. Moving the entry pages to the Edge runtime was tried next and reverted when the cold start measured 3.8 to 4.1 seconds against 1.80 on Node.

how it went

  1. 21 July 2026

    Extraction

    Lifted out of the Caparison ERP into its own schema, with the two live guest-security bugs fixed on the way out.

  2. 21 to 22 July 2026

    Embedded mode

    Every read and write moved behind server actions, because a hub token is not a Supabase session and PostgREST rejected the browser client.

  3. 22 July 2026

    Per-user storage

    Bring-your-own R2 with an encrypted credential vault, a connect wizard and an upload gate; 14 of 14 adversarial checks passed.

  4. 23 July 2026

    Load profiling

    Three fixes on the embedded path: co-locating the functions with the database, an Edge-runtime experiment reverted on measurement, and a redirect removed from the doorway.

  5. 23 August 2026

    Field fixes

    Five commits from real use: endpoint normalisation, a missed service-role grant, R2 objects orphaned on delete, and done state made persistent.

results

cold start, embedded entry page

1.80s

the same pages measured 3.8 to 4.1 seconds on the Edge runtime, which is why that change was reverted

23 July 2026, measured by two idle-then-cold samples, taken by hand

220-240ms

round trip removed from every server-side query

the functions ran in Virginia while Postgres sits in Singapore; pinning them to Singapore co-located the two

23 July 2026, measured by request timing

since launch Five fixes shipped on 23 August 2026 off reports from people actually using it, including two orphaned 53MB clips that proved deletes were never reaching R2.

Want something like this?

A tool people open without an account is a security question before it is a feature list. Tell us who gets the link, and what they must not be able to reach with it.

Build something like this

next

Raw Footage, Real Story