Skip to main content

Services Directory

Location: src/services/

Purpose: Server-side data access layer that wraps Supabase queries and access control. Returns the standardized QueryResponse shape ({ message, error, data }) defined in src/types/common.ts.

Structure

services/
├── accessCheck/ # Route + permission gating
│ ├── accessCheck.ts # Returns QueryResponse with current permissionKeys for a (team, campaign?) scope
│ ├── getRoutePermissions.ts # Cached snapshot loader (unstable_cache, tagged permissions-${userId})
│ └── requireAccess.ts # Server-side guard; redirect()s to /no-access on failure

├── campaign/ # Campaign data services
│ ├── checkIfAlreadyActiveRate.ts
│ ├── checkInviteToken.ts
│ ├── fetchRateRecordEdit.ts
│ ├── fetch_campaign_circulator_view.ts
│ ├── fetch_campaign_format_view.ts
│ ├── fetch_rate_campaigns.ts
│ ├── fetch_transaction_campaigns.ts
│ ├── fetch_turn_in_campaigns.ts
│ ├── getAllCampaigns.ts
│ ├── getCampaignBySlug.ts
│ ├── getCampaigns.ts
│ ├── getCampaignsForUser.ts
│ ├── getCampaignSlugSuperAdmin.ts
│ └── getUniqueColumns.ts

├── credentials/
│ └── fetchCredentialsRecordEdit.ts

├── dashboards/ # Configurable per-campaign dashboards
│ ├── fetchDashboardList.ts
│ └── fetchDashboardRecord.ts

├── permission-sets/ # "Responsibilities" (permission-set bundles)
│ ├── fetchCampaignPermissionSets.ts
│ ├── fetchPermissionAllSets.ts
│ ├── fetchPermissionSetEdit.ts
│ └── fetchTeamPermissionSets.ts

├── permissions/ # Permission keys + roles
│ ├── fetchPermissionKeyEdit.ts
│ ├── fetchPermissionKeysList.ts
│ ├── fetchRoleEdit.ts
│ ├── fetchRoles.ts
│ ├── fetchRolesForTeam.ts
│ └── regionsForTeam.ts

├── petitions/ # Petition + signature workflow data
│ ├── createNewPetition.ts
│ ├── getDefaultCountyByUser.ts
│ ├── getLastestValueByUserInPetitions.ts
│ ├── getPetitionById.ts
│ ├── getPetitionFormatById.ts
│ ├── getPetitionFormatForEdit.ts
│ ├── getPetitionsFormatForCampaign.ts
│ ├── getPetitionsForUser.ts
│ ├── getPreviousBlockListOfPetition.ts
│ ├── getPreviousSelectedFormat.ts
│ ├── getRecentCirculators.ts
│ └── getSessionBasedTurnInDate.ts

├── regions/
│ └── fetchRegionRecordEdit.ts

├── roles/
│ └── getUserRoleHierarchyLevelForTeam.ts # Cached lookup of roles.hierarchy_level for the current user in a team

├── teams/ # Team / sub-team / member services
│ ├── checkMemberToken.ts
│ ├── fetchSubTeams.ts
│ ├── fetchTeamMatrixAssignments.ts
│ ├── fetchTeamMembersWithSearch.ts # Excludes the calling user; supports name/email search
│ ├── getMemberToken.ts
│ ├── getSubTeamById.ts
│ ├── getSubTeamForEdit.ts
│ ├── getTeamBasicsForAdminInvite.ts
│ ├── getTeamById.ts
│ ├── getTeamForEdit.ts
│ ├── getTeamMemberForEdit.ts
│ └── getUserTeams.ts

├── transactions/
│ ├── fetchCirculatorUsers.ts
│ └── fetchTransactionRecordEdit.ts

├── turnInRecord/
│ └── fetchTurnInRecordEdit.ts

└── user/
├── getAuthUser.ts
├── getUserByEmailClient.ts
└── getUserList.ts

Service Characteristics

  • Server-only: services are imported by Server Components, Route Handlers, and Server Actions. They use the SSR Supabase client from src/lib/supabase/server.ts.
  • QueryResponse return shape: { message: string; error: boolean; data: any }.
  • Caching where it matters:
    • accessCheck/getRoutePermissions.ts and roles/getUserRoleHierarchyLevelForTeam.ts use unstable_cache with revalidate: 3600 and per-user tags so a single revalidateTag call invalidates everything.
  • Access-control bedrock: accessCheck/ is the canonical place to ask "does this user have access to this team/campaign and these permission keys?". See complex-logic/access-control for usage.