Freelance contract at Noside on Envelope, an AI workflow SaaS for fashion. Team media library, creative review tool, AI media enrichment and Claude Code assisted engineering.
Envelope is an AI workflow SaaS: creative teams in fashion and luxury assemble nodes (images, text, video, generative models) on a collaborative canvas to produce their visuals. The product is built by Noside with a two-developer team. I have been working on it as a freelancer since July 2026.
Stack: Next.js 16, React 19, TypeScript, Supabase (Postgres, Auth, Storage, RLS), Drizzle, CRDT-synced canvas (Yjs, Liveblocks), Vercel AI SDK, Stripe, Vitest.
This page describes the approach and the problems solved, without code or customer data.
The need: teams were exchanging visuals by email and Slack, with no history and no versions. I designed and shipped end to end a team-level shared library, then a review tool inspired by Frame.io.
Every media is described by a vision-language model. I turned those descriptions into search tools: facets (framing, time of day, light mood), 12-colour palette extraction and background colour filter, team-defined custom fields classified by LLM, face clustering into people behind an opt-in.
OAuth connector framework with encrypted tokens (OneDrive, SharePoint, Dropbox) to import and publish media. Authorization guard rolled out to every server action, with a test that fails CI as soon as an action touches the database without going through the guard. Encrypted nightly backup of database and storage to Scaleway.
After a “replace this image everywhere in the canvas”, the old image came back for a colleague opening the project. Cause: a freshly opened browser first paints its local cache, a background job started on that stale view and rewrote the whole content as a new CRDT write, causally later than the replacement. It won. Diagnosed through storage timestamps and a direct read of the Liveblocks room; fixed with a “view reconciled with the server” signal that gates every background writer.
The spec said an anonymous visitor left their email. The field had never existed. The rule “no email, no notification” perfectly hid a “never any email”. Lesson: check that a piece of data is actually collected before writing the rule that consumes it.
A push route to a DAM validated the shape of a storage path, then downloaded the file with a privileged role: a path from another team went through. Found in code review, not by the test suite. Since then, the proxy allow-list is pinned by a test, and every new anonymous surface has to be in it.
The whole contract was done with Claude Code, keeping ownership of every decision.
Result: the test suite grew from 3,800 to 6,700, 20+ PRs merged in three months, and a project memory that captures the pitfalls for the next sessions.