Estúdio Dupla Face
Website and client portal for an architecture studio

Context
Estúdio Dupla Face works across homes, interiors and scenography, and defines its own craft by two faces: the one you see — light, material, landscape — and the one that holds it up: precise drawings and documentation the building site can follow.
The challenge
An architecture project becomes a pile of scattered files: plans, technical drawings, references, site photos and decisions agreed over WhatsApp. The client does not know where to look, and the studio repeats the same information for months. The problem was not storing files — it was giving them a place where they make sense together.
The architecture
The floor plan became the interface. The architect drops a pin on each room and accumulates as many drawings, images and notes inside it as needed — the plan stops being a picture and becomes the project's index. Around it, a portal where the client talks to the studio and downloads documents, and a panel where the studio publishes what it wants shown on the site.
Architecture flow
Studio panel
- Pins dropped on the floor plan
- Publishing to the site
Supabase
- PostgreSQL with Row Level Security
- Private document bucket
- Realtime
Client portal
- Access only after approval
- Realtime messaging
- Downloads through a 60-second URL
Engineering decisions
Pins that hold at any size
Each pin's coordinates are stored as a percentage of the image, not in pixels. The marker stays exactly over the right room at any screen width and any zoom level — a small detail that decides whether the feature is usable on a phone at the building site.
Protection lives in the database
Every table has Row Level Security, and the policies rest on three functions: is_admin(), is_approved() and row ownership. An approved client sees only their own projects, conversations and documents — even if the interface gets it wrong.
Private documents, expiring links
Documents live in a private bucket with the client id as the first path segment, and downloads go through a route that re-checks ownership before signing a 60-second URL. A leaked link stops being a problem a minute later.
A database blip does not take the site down
Database calls are time-capped. If it does not answer, public-site reads degrade to an empty state and the error goes to the log — the page stays up. Writes, by contrast, fail loudly, because there the user needs to know.
Access by approval
Every sign-up starts pending and only becomes access after an administrator approves it — a client portal never opens on its own.