Skip to main content

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). The src/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 the FormState payload.
  • 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_level via src/lib/team-member-hierarchy.ts so a non-super-admin cannot promote/demote a peer or senior.