Actions Directory
Location: src/actions/
Purpose: Server Actions ("use server") that handle mutations. They validate input with Zod schemas (defined alongside their forms in src/components/forms/**), call services / Supabase, and return the standardized FormState shape ({ message, error, data?, zodIssues? }) defined in src/types/form.ts.
Some domain-specific actions live next to their components (
src/components/{rates,regions,transactions,turn-in,teams}/actions/*.ts). Thesrc/actions/tree below holds the cross-cutting actions.
Structure
actions/
├── auth/ # Authentication actions
│ ├── block-action.ts # Block/unblock user accounts
│ ├── profile-update.ts # Update user profile
│ ├── sign-in-action.ts # User sign-in
│ ├── sign-out-action.ts # User sign-out
│ └── sign-up-action.ts # User registration
│
├── campaign/ # Campaign CRUD
│ ├── create-campaign-action.ts
│ └── update-campaign-action.ts
│
├── credentials/ # External-service credentials (Directus etc.)
│ ├── create-credentials-action.ts
│ └── update-credentials-action.ts
│
├── dashboards/ # Configurable per-campaign dashboards
│ ├── create-dashboards-action.ts
│ ├── update-dashboards-action.ts
│ └── refresh-charts-action.ts # Triggers chart regeneration
│
├── permission-sets/ # "Responsibilities" management
│ ├── create-new-permission-sets-action.ts
│ └── update-permission-sets-action.ts
│
├── petition/ # Petition operations
│ ├── create-circulator.ts # Create circulator record (manual add)
│ ├── create-petition-action.ts # Create new petition
│ ├── update-petition-action.ts # Update petition
│ └── updatePetitionFormat.ts # Switch a petition's format
│
├── role-based-access/ # Roles + permission keys
│ ├── add-role-permission-action.ts
│ ├── create-new-role-action.ts
│ ├── create-permissionsKeys-action.ts
│ ├── update-permissionsKeys-action.ts
│ └── update-role-action.ts
│
├── signatures/ # Signature submission
│ └── submitSignatures.ts
│
├── teams/ # Team + sub-team + invite management
│ ├── accept-campaign-invite-action.ts # Accept a sub-team's campaign invite
│ ├── accept-invite-action.ts # Accept a team-membership invite
│ ├── add-sub-team-action.ts
│ ├── assign-team-permission-sets-action.ts
│ ├── create-teams-action.ts
│ ├── search-team-members-action.ts # Wraps fetchTeamMembersWithSearch (typeahead)
│ ├── set-active-team-session.ts # RPC team_session_update
│ ├── update-sub-team-action.ts
│ └── update-team-action.ts
│
├── city-search.ts # Reverse-geocode / city autocomplete
├── credentials-search.ts # Credentials search (admin)
├── place-search.ts # Place / address autocomplete
├── search-address.ts # Address autocomplete
└── team-search.ts # Team autocomplete
Domain-local action folders that ship alongside their components (not duplicated above):
src/components/rates/actions/—create-rate-action.ts,update-rate-action.ts.src/components/regions/actions/—add-region-action.ts,update-regions-action.ts.src/components/transactions/actions/—create-transaction-action.ts,update-transaction-action.ts.src/components/turn-in/actions/—add-turnIn-action.ts,update-turnIn-action.ts,turnIn-records-admin-action.ts.src/components/teams/actions/—check-user-by-mail.ts,member-camapign-update-action.ts,member-role-update-action.ts,new-member-action.ts.
Conventions
- Files use the
"use server"directive. - Validation runs through Zod schemas located next to the form (e.g.
src/components/forms/campaignForm/campaign.schema.ts). - Helpers from
src/lib/server-utils.ts(createSuccessResponse,createErrorResponse) standardize theFormStatepayload. - After mutating data that affects sidebars or guards, actions can trigger
revalidateTag(\permissions-${userId}`)(typically through/api/permissions/revalidate`) so cached snapshots refresh. - Member-management actions enforce
roles.hierarchy_levelviasrc/lib/team-member-hierarchy.tsso a non-super-admin cannot promote/demote a peer or senior.