Move description generation to the server (notification.list) so the
popover renders a pre-built string. Adding a new notification type
now only requires updating describeNotification on the server — the
UI stays generic.
- Remove discriminated union types and WorkspaceInvitePayload import
from notification-popover.tsx
- NotificationItem is now derived from the server return type
- Move getDescription tests → describeNotification tests
- Remove unused __testing__ export from cross-tab-manager.ts
- notification.create returns notification ID
- addMember returns notificationId (fake UUID for non-existent users)
- workspace router exposes notificationId in addMember response
- workspace-dialogs: trash button calls notification.cancel with stored ID
- replace $userEmail atom with $user storing full User object
- add maxProjectsAllowedPerUser to UserPlanFeatures + all plan constructors
- plan-limit check on transfer accept
- global dedup: one pending transfer per project
- notification.cancel endpoint
- cross-owner move restriction in moveProject
- self-transfer check in transfer dialog
- Add transfer dialog with workspace selector and email input
- Support moving projects between workspaces (instant) and
transferring to another user via notification (async)
- Add project transfer notification type with accept/decline flow
- Verify sender ownership and auto-decline stale transfers
- Add audit logging for ownership changes
- Add canTransfer permission for owners and admins
- Use camelCase notification types (workspaceInvite, projectTransfer)
- Use .select("id").single() on all notification status updates
- Debounce email search with stale response rejection
- Use Set-based loading state for concurrent notification actions
- Filter unknown notification types before rendering
- Use theme tokens for all spacing values
When a workspace owner's plan no longer supports workspaces (maxWorkspaces <= 1),
member access is revoked while preserving workspace data and memberships:
- Add getOwnerPlanFeatures callback to AppContext for cross-user plan lookups
- Check workspace owner plan in hasProjectPermit to deny non-owner access
- Mark member workspaces as isDowngraded in findMany based on owner plan
- Gate updateWorkspaceRelation behind maxWorkspaces check
- Block downgraded workspace members in builder route loader
- Show ProBadge "Suspended" and disable selection for downgraded workspaces
- Replace workspaces feature flag with maxWorkspaces-based gating
- Default maxWorkspaces to 0 (controlled via MAX_WORKSPACES env var)
- Skip workspace queries in dashboard loader when maxWorkspaces is 0
- Extract pure functions (resolveCurrentWorkspace, isWorkspaceRelationPermitted, getView) with tests
- Remove workspaces feature flag from all files
- Rename userRelation → workspaceRelation across schema, DB, router, and UI
- Rename MemberRelation type → WorkspaceRelation everywhere
- Create canonical UserPlanFeatures/UserPurchase module in trpc-interface
- Make userPlanFeatures non-optional in AppContext
- Separate purchases from UserPlanFeatures
- Compute workspaceRelation in route loaders instead of consumer sites
- Add $workspaceRelation atom, use real relation in $permissions computed
- Remove permissions prop-drilling from all dashboard components
- Leaf components use useStore($permissions) directly
- Create setSharedStores() for unified store initialization
- Combine workspace + membership into single PostgREST query in builder route
- Replace purchases.length checks with canDownloadAssets/canRestoreBackups
- getUserPlanFeatures() → getUserPlanInfo() returning { userPlanFeatures, purchases }
- Add unified getPermissions() combining role + plan permissions
- Gate project actions (create, delete, publish, share, etc.) by workspace role
- Introduce MemberRelation schema (owners/admins/builders/viewers)
- Compute $permissions from $userPlanFeatures + $authPermit in nano-states
- Set $userPlanFeatures globally in DashboardSetup (matching builder pattern)
- Add workspace dialogs for managing members and invitations
- Enforce permissions across dashboard, builder, and settings UI
- Extract softDeleteProject helper so unique domain invariant lives in one place
- Projects created in a workspace are owned by workspace owner, not creator
- Remove unnecessary useEffect around $data.set
- Remove unused parseTrpcError helper
- Remove unsafe `as TokenAuthPermit` cast
- Add sortWorkspaces tests
- Document idempotent retry safety in workspace remove()
- Backend: accept deleteProjects flag to soft-delete all projects before removing workspace
- Frontend: warning text mentions all projects will be deleted, with 'All projects' in red
- Dashboard: detect stale workspaceId in URL and redirect to default workspace
- Add workspace dialogs: create, rename, manage members, delete
- Rewrite workspace selector as dropdown menu with action items
- Support comma-separated multi-email member invites
- Create placeholder users for non-existing email invites
- Add ScrollAreaNative component with native thin scrollbar
- Show newest members first in member list
- Preserve workspaceId query param in navigation links
- Fix DashboardSetup to use useEffect for data sync
Add/remove/list workspace members by email.
- addMember: owner-only, looks up user by email, inserts as
administrator, rejects duplicates and self-add
- removeMember: owner-only, prevents removing the owner
- listMembers: visible to owner and members, returns user email/username
tRPC procedures: workspace.addMember, workspace.removeMember,
workspace.listMembers.
Projects are created inside a workspace and listed per workspace.
- project.create accepts optional workspaceId, sets it on the new project
- dashboard findMany accepts optional workspaceId filter
- Dashboard route loader loads workspaces list and reads selected
workspace from cookie when the workspaces flag is on
- DashboardData type extended with workspaces and currentWorkspaceId
When the flag is off, all behavior is unchanged.
- Create default "Personal" workspace at user signup in genericCreateAccount
- Add data migration to backfill existing users with default workspaces
- Assign unassigned projects to their owner's default workspace
- Add Workspace type export from @webstudio-is/project
- Regenerate PostgREST types with Workspace/WorkspaceMember tables
- Add workspaceId to storybook/test mock data
- Add @webstudio-is/postgrest dependency to project package
closes https://github.com/webstudio-is/webstudio/issues/5621
to publishedBuilds and findManyByIds en…dpoints
- Add getProjectPermit check to publishedBuilds endpoint to verify user
has access
- Add userId filtering to findManyByIds to only return user's own
projects or approved marketplace templates
- Maintain belt-and-suspenders approach with both authType check and
permit verification
## Description
1. What is this PR about (link the issue and add a short description)
## Steps for reproduction
1. click button
2. expect xyz
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
## Description
1. What is this PR about (link the issue and add a short description)
## Steps for reproduction
1. click button
2. expect xyz
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
## Description
1. What is this PR about (link the issue and add a short description)
## Steps for reproduction
1. click button
2. expect xyz
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
## Description
1. What is this PR about (link the issue and add a short description)
## Steps for reproduction
1. click button
2. expect xyz
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
## Description
### Full track
https://github.com/webstudio-is/webstudio-saas/issues/317#issuecomment-2289241819
So thoughts about session
https://github.com/webstudio-is/webstudio-saas/issues/317#issuecomment-2314515772
Some explanations what is fixed and how
https://github.com/webstudio-is/webstudio-saas/issues/317#issue-2465048823
Next PR:
- [x] - Old share links auto redirect
- [x] - Try make better error message having that current PR will logout
all users.
## Steps for reproduction
1. Login using `google login` or `dev login` try to open projects on
dahsboard, create new, clone delete etc.
2. Try to open projects on dahboard, see each is on it's own domain and
work
3. Try to open project link (without share token) with other user -
should fail.
4. Try publish/clone any links and operations.
5. Share project from `userA`:
- try to open it with other `userB`
- see `userB` is not logged in to that project
- try to get using fetch from console anything about `userB` or `userA`
i.e rest etc endpoints on apps.webstudio.is domain
- try to open incognito, check it works.
6. Open few project, then logout from dashboard, reload project page
- See login page
- Try to login as same uer - see it works
- Or try to login as another user - see auth error
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
## Description
closes#3960
The issue that in prisma we had multi key relation
`project Project @relation(fields: [projectId, domain], references: [id,
domain])`
but in postgrest seems lile this is not working (invetigating)
## Steps for reproduction
1. click button
2. expect xyz
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
Switched to postgrest in "project" package.
Do 3 requests now when load project to get
latest build and latest static build since
they are not inferred as related in postgrest.
## Description
Closes https://github.com/webstudio-is/webstudio/issues/3861
## Steps for reproduction
1. click button
2. expect xyz
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
Migrated prisma with postgrest in project build.
Got two cases
- in many cases it is ok to use a couple of select queries since round
trip is low
- transactions can be avoided with late binding to user
Our project cloning does a lot of roundtrips to database and got
fragmented across 3 packages. The logic is too complicated to represent
with postgrest.
Here written single sql function which is invoked safely with postgrest
rpc.