BetterAuth session responses contain only identity fields — workspace context (workspaceId, currentWorkspaceId) was never returned, causing "Workspace ID is required" on every guarded endpoint after login. Add GET /api/workspaces endpoint (AuthGuard only, no WorkspaceGuard) that returns user workspace memberships with auto-provisioning for new users. Frontend auth-context now fetches workspaces after session check and persists the default to localStorage. Race condition in auto-provisioning is guarded by re-querying inside the transaction. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
29 lines
1.0 KiB
TypeScript
29 lines
1.0 KiB
TypeScript
import { Controller, Get, UseGuards } from "@nestjs/common";
|
|
import { WorkspacesService } from "./workspaces.service";
|
|
import { AuthGuard } from "../auth/guards/auth.guard";
|
|
import { CurrentUser } from "../auth/decorators/current-user.decorator";
|
|
import type { AuthUser } from "@mosaic/shared";
|
|
import type { WorkspaceResponseDto } from "./dto";
|
|
|
|
/**
|
|
* User-scoped workspace operations.
|
|
*
|
|
* Intentionally does NOT use WorkspaceGuard — these routes operate across all
|
|
* workspaces the user belongs to, not within a single workspace context.
|
|
*/
|
|
@Controller("workspaces")
|
|
@UseGuards(AuthGuard)
|
|
export class WorkspacesController {
|
|
constructor(private readonly workspacesService: WorkspacesService) {}
|
|
|
|
/**
|
|
* GET /api/workspaces
|
|
* Returns workspaces the authenticated user is a member of.
|
|
* Auto-provisions a default workspace if the user has none.
|
|
*/
|
|
@Get()
|
|
async getUserWorkspaces(@CurrentUser() user: AuthUser): Promise<WorkspaceResponseDto[]> {
|
|
return this.workspacesService.getUserWorkspaces(user.id);
|
|
}
|
|
}
|