Skip to content

[v5.x] feat: scaffold workspaces#9247

Draft
peaklabs-dev wants to merge 16 commits intov5.x-feat/scaffold-authfrom
v5.x-feat/scaffold-workspace
Draft

[v5.x] feat: scaffold workspaces#9247
peaklabs-dev wants to merge 16 commits intov5.x-feat/scaffold-authfrom
v5.x-feat/scaffold-workspace

Conversation

@peaklabs-dev
Copy link
Copy Markdown
Member

@peaklabs-dev peaklabs-dev commented Mar 29, 2026

Scaffold the full workspaces system (replacing v4 teams) including a workspace global scope and middleware that reduce ~2,800 lines of manual team checks across ~400 files down to ~114 lines across 2 files (and models).

Changes

  • Scaffold workspace model and migration
  • Scaffold workspace member model and migration
  • Scaffold InvitationMethod enum
  • Scaffold workspace invitation model and migration
  • Scaffold Permission enum
  • Scaffold UserRole enum
  • Scaffold custom role model and migration
  • Add global WorkspaceScope that automatically applies WHERE workspace_id = ULID to every scoped model query
  • Add SetWorkspace middleware which resolves workspaces via URL parameter > cookie > session > auto-select (single workspace) and validates membership
  • Add Inertia HTTP interceptor that auto-appends the workspace ID as a query parameter to every request
    • The middleware would do that too but that would result in 1 additional 304 redirect on each request, creating unnecessary overhead
  • Share workspace id and name via Inertia shared props
  • Apply workspace scope to models via #[ScopedBy]

v4 Comparison

  • Workspaces
    • Added workspaces replacing v4 teams (clearer name, fully self-contained and isolated from each other)
    • Added option to require 2FA workspace-wide
    • Added concurrent builds limit and default deployment timeout to workspace settings (incorrectly scoped per-server on v4)
    • Added workspace global scope and middleware (~114 lines) replacing ~1,970 manual team checks, written in 12 different ways (~2,800 lines) across ~400 files
    • Added support for multiple workspaces open simultaneously in different browser tabs (via query parameter, avoiding a long and ugly path segment)
    • Added automatic workspace selection via URL parameter > cookie > session > auto-select (single workspace)
  • Permission System
    • Added UserRole enum defining all predefined roles in one place, replacing scattered role-check methods (isAdmin(), isMember(), etc.) with a single enum-based approach supporting granular permissions and adding new permissions to existing roles without a database migration
    • Added Permission enum with granular permissions per feature (e.g. WorkspaceRead, WorkspaceCreate, WorkspaceUpdate, WorkspaceDestroy), defined as string-backed enums so changes are code-only, not database migrations
    • Added custom roles with configurable permissions assignable to workspace members

Workspace scope

v4.x v5.x
Scoping patterns 12: ownedByCurrentTeam(), currentTeam()->id, teams->contains(), whereTeamId() 1: #[ScopedBy]
Consistency Very inconsistent - 12 different ways to scope across the codebase Consistent - 1 unified pattern everywhere
Security risk High - every unscoped query leaks data (see #9230) Near zero - automatic scoping
Per-model effort ~10 lines + manual scope call on each query 1 line, scoping is automatic
Total checks ~1,970 ~36 (in all needed models)
Total affected files ~400 (36 models, 122 Livewire, 17 controllers, 14 jobs, 9 actions, …) ~36 (~36 models + 1 scope + 1 middleware)
Total lines ~2,800 (1,970 call sites + scope definitions + middleware) ~114 (~36 attributes + ~10 scope + ~68 middleware)
Multiple workspaces open at once Not supported Supported
Propagation to queued jobs Manual Automatic via context()

TODO

  • Investigate if any additional permissions are needed for all scaffolded models in this PR

This is part 2 of 3 in a stack made with GitButler:

@peaklabs-dev peaklabs-dev force-pushed the v5.x-feat/scaffold-auth branch from d8d7049 to c4f38ac Compare March 30, 2026 21:57
@peaklabs-dev peaklabs-dev force-pushed the v5.x-feat/scaffold-workspace branch from 89798ab to 7b5b139 Compare March 30, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant