diff --git a/packages/core/README.md b/packages/core/README.md index a927696..ad4b269 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -162,9 +162,12 @@ below. ## Per-space permissions -A space is `visibility: "workspace"` (the default, and what every existing space -is) or `"private"`. Owners and admins see every space; a member sees the -workspace-visible ones plus the private ones they are in (`space_members`). +A newly created space defaults to `visibility: "private"`; its creator is +added as its first member. Pass `visibility: "workspace"` to make a new space +visible to every member. The `"workspace"` default on the stored `Space` entity +is a compatibility fallback for existing rows that have no visibility value. +Owners and admins see every space; a member sees workspace-visible ones plus +the private ones they are in (`space_members`). Everything under a space — lists, tasks, subtasks, comments, attachments — inherits that decision; there is no per-list override. The rule itself lives in `src/visibility.ts` as `canSeeSpace`, and the three enforcement shapes all call @@ -456,11 +459,12 @@ and nothing else — no spaces, no lists; imports or the UI create those. | Workspace Owner | owner@placeholder.flow | owner | The seed is static SQL with no access to env, so the owner starts with a -placeholder address flagged `needs_email_update`. After deploying, set -`OWNER_EMAIL`, sign in through Access (or `DEV_NO_AUTH=true` locally), and set -the real address with `upsertUser`, which clears the flag once the address is -no longer `@placeholder.flow`. Notifications are skipped for placeholder -emails, so nothing is sent until then. +placeholder address flagged `needs_email_update`. Set `OWNER_EMAIL` before the +owner's first sign-in through Access (or use `DEV_NO_AUTH=true` locally). That +sign-in claims the seeded owner for the configured address; `claimOwner` calls +`upsertUser`, which clears the flag once the address is no longer +`@placeholder.flow`. Notifications are skipped for placeholder emails, so +nothing is sent until then. ## IDs diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8da0ab7..59733dd 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -456,7 +456,8 @@ export class Workspace extends DurableObject implements WorkspaceRpc { /** * WebSocket upgrade at `/ws`. The api Worker authenticates the request and - * forwards it with `?userId=us_…`; the DO does not re-authenticate. + * forwards the user id in `X-Flow-User-Id`; `?userId=us_…` is a fallback for + * direct-to-DO callers. The DO does not re-authenticate. */ fetch(req: Request): Response { const url = new URL(req.url); diff --git a/packages/core/src/visibility.ts b/packages/core/src/visibility.ts index b1cdf43..8c30eba 100644 --- a/packages/core/src/visibility.ts +++ b/packages/core/src/visibility.ts @@ -5,7 +5,8 @@ import type { Actor, Role, SpaceVisibility } from "@flow/shared"; // // The model is deliberately small: // -// - Every space is "workspace" (the default) or "private". +// - New spaces default to "private"; stored legacy rows without a value read +// as "workspace" through the shared Space entity schema. // - Owners and admins see every space, always. // - A member sees workspace-visible spaces, plus private spaces they are a // member of (`space_members`).