Skip to main content

Core (Backend) — Key Facts

  • Java 21, Spring Boot 4.0.3, GraphQL schema-first, PostgreSQL, Keycloak 26.5.5, MapStruct, Envers
  • Package root: com.axvero.ams.core
  • DB: local Postgres via compose.yaml (user/password, db: core)
  • Profiles: src/main/resources/application-*.yaml
  • Tests: not working properly — ignore for now. Run ./mvnw compile to validate.
  • Do NOT inject CurrentUserContext into services. Resolve currentUserId in the controller and pass it as a method parameter.

Role-Based Data Scoping

When a query returns different results by role (e.g. client vs staff): resolve currentUserId in the controller, pass to service. Service checks ClientService.findClientIdByUserIdAndWorkspaceId(currentUserId, workspaceId) and auto-scopes results. Clients always see only their own data; staff see all.

BaseEntity Refactoring — DO NOT DO

BaseEntity uses InheritanceType.JOINED and is extended by User, Organization, Team, Workspace. A future dedicated task will dissolve it. Do NOT dissolve it as part of other tasks.

OrgPublicProfile Sync Behaviour

  • synced = true: public profile mirrors private OrganizationProfile + OrganizationAddresses. When private org profile is updated (OrganizationService.update()), OrgPublicProfileService.propagateSyncIfEnabled(orgId) is called automatically for all synced profiles of that org.
  • synced = false: owner manages the public profile independently; private org updates do NOT affect it.
  • GraphQL mutations: syncOrgPublicProfile(workspaceId) — copies private → public, sets synced=true. updateOrgPublicProfile(workspaceId, input) — saves custom data, sets synced=false.
  • Public profile returned as nested field publicProfile on the existing workspace(id) query.
  • Rule: There must never be an OrgWorkspace without an OrgPublicProfile. Always create one via OrgPublicProfileService.sync() immediately when creating an OrgWorkspace.