Skip to main content

Organizations & Workspaces

Workspace types

AMS has two concrete workspace types, both extending the base Workspace class using JPA InheritanceType.JOINED:

TypeTableWho owns itCreated when
OrgWorkspaceorg_workspaceAn OrganizationOrg is created (default) or manually added
UserWorkspaceuser_workspaceA UserUser first signs in (auto-created)

Never instantiate the base Workspace class. Always use OrgWorkspace or UserWorkspace. When querying workspace-subclass-specific fields in JPQL, target the subclass directly: SELECT w FROM OrgWorkspace w WHERE w.orgId = :orgId.

Organization workspace lifecycle

When an organization is created:

  1. A default OrgWorkspace is created
  2. A default team is created in that workspace
  3. An OrgPublicProfile is immediately created in synced mode (copy of private profile)
  4. The creator is added as OWNER member of the default team

Public org profile

Every OrgWorkspace has exactly one OrgPublicProfile. This is the client-facing view of the organization.

Sync behaviour

ModeBehaviour
synced = true (default)Public profile mirrors private OrganizationProfile + addresses. Auto-updated whenever private profile is saved.
synced = falseIndependently managed. Private org profile changes do NOT affect the public profile.

GraphQL mutations:

  • syncOrgPublicProfile(workspaceId) — copies private → public, sets synced = true
  • updateOrgPublicProfile(workspaceId, input) — saves custom data, sets synced = false

OrgPublicProfileAddress records are independent copies — editing them does not touch OrganizationAddress.

Invariant

There must never be an OrgWorkspace without an OrgPublicProfile. Always create one via OrgPublicProfileService.sync() immediately when creating an OrgWorkspace.

Clients

Clients are external applicants assigned directly to an organization (client.orgId FK → Organization). They are not scoped to a specific workspace.

  • A Client links a User to an Organization
  • Clients are queried org-wide: clients(orgId: ID), clientInvitations(orgId: ID)
  • When a client participates in an application, they appear as an Applicant record on that application
  • Workspace-level permission checks for clients are resolved via a join: JOIN org_workspace ow ON ow.org_id = c.org_id WHERE ow.id = :workspaceId

Teams & members

Teams are org-scoped and assigned to workspaces via TeamWorkspaceAssignment. Teams organize staff users.

  • Team slug must be unique within the org
  • Member links a User to a Team with a MemberRole
  • Creator of a team is automatically added as OWNER

Default teams

TeamPurpose
Default teamAll regular team members

Personal workspace

Every user has exactly one UserWorkspace, created automatically on first login. It provides:

  • Personal dashboard
  • Personal applications list
  • User settings (profile, account, appearance, notifications, addresses)
  • Organizations list

URL structure

Personal workspace:
/p/$userSlug/applications/
/p/$userSlug/settings/...

Org management (not workspace-specific):
/o/$orgSlug/teams/
/o/$orgSlug/users/
/o/$orgSlug/clients/
/o/$orgSlug/partners/
/o/$orgSlug/settings/...
/o/$orgSlug/workspaces/

Workspace work (workspace-specific):
/o/$orgSlug/w/$workspaceSlug/dashboard/
/o/$orgSlug/w/$workspaceSlug/applications/
/o/$orgSlug/w/$workspaceSlug/applications/$id/
/o/$orgSlug/w/$workspaceSlug/messages/
/o/$orgSlug/w/$workspaceSlug/application-setup/documents/
/o/$orgSlug/w/$workspaceSlug/application-setup/templates/
/o/$orgSlug/w/$workspaceSlug/application-setup/permissions/

Org-management routes (/o/$orgSlug/...) handle resources that belong to the org as a whole — teams, clients, partners, settings. Workspace-specific work routes nest under /o/$orgSlug/w/$workspaceSlug/ and carry both the org and workspace context in the URL.


See also