Per-entity cloud pages: app.talkak.daeseon.ai/e/<entity>, visibility-first
Gave each entity its own bookmarkable cloud address (/e/<entity-slug>) on the single login-gated dashboard — the standard SaaS workspace-URL pattern (like Notion/Linear). The slug resolves ONLY against the signed-in user's RLS-scoped workspaces, so a URL never reveals or grants a peek at an entity the user can't access.
The founder's model: "딸깍 클라우드 접속하는 전용 페이지가 따로 있고, 거기서 사람들이 자기네 클라우드에
접속한다" — one product door, each entity with its own address. That's exactly Notion
(x.notion.site) / Linear (linear.app/x). And: "가시성 꼭 신경써."
What it is
app.talkak.daeseon.ai/e/<entity-slug>selects that entity's workspace. The URL syncs as you navigate (history.replaceState), so every entity is bookmarkable/shareable.- Slugs allow unicode (한글 entity names work, URL-encoded), derived from the entity name.
Visibility was the design constraint, not an afterthought
The slug is resolved only among the user's own workspaces — listWorkspaces returns just the
services the signed-in user is a member of (RLS). We never look up an entity by slug across the
table, so:
- A slug you don't have access to matches nothing → one generic "접근 권한이 없거나 존재하지 않습니다" screen. Unknown vs forbidden look identical — no existence oracle.
- The data itself is RLS-gated regardless of the URL, so a guessed address still shows nothing.
Plus apps/web/vercel.json adds the SPA fallback so a direct hit / refresh on /e/<entity> serves
the shell instead of a 404. tsc + vite build green.
Still the owner's to do
Point app.talkak.daeseon.ai at the dashboard's Vercel project (a domain add) and redeploy. The
code is ready; the domain is an account action.