What changed when teams asked for real workspaces
Author: Dana Okafor at Zitegen
Zitegen started with one owner per site, which is the correct default for a solo founder and the wrong default for anyone with a co-founder, a contractor, or a studio. Retrofitting teams into a system built around single ownership is one of those changes that sounds like "add a table" and is actually a full pass through every access check in the app.
The migration shape
Every existing user got a personal team backfilled — one seat, themselves as primary owner — and every site picked up a team_id. Nothing broke on day one because a personal team of one behaves exactly like the old single-owner model from the outside.
The part that took longest
Flipping authorization was the real work: every row-level security policy that checked sites.owner_id against the current user had to become a team-membership check, and every server-side access function had to call a shared assertion helper instead of comparing owner IDs inline. We shipped it as two migrations on purpose — schema and backfill first, RLS cutover second — so we could verify the data was correct before authorization behavior changed under it.
One deliberate asymmetry
Every team member gets full read/write parity on the team's sites — except deleting one, which stays owner-only. Destructive, irreversible actions got a narrower gate than everything else on purpose; parity is the default, not an absolute rule.
The old owner column still exists in the schema. It's creator metadata now, used for things like per-account site-creation quotas — never for deciding who's allowed to open a site. Old columns don't have to disappear to stop meaning what they used to.