Server Actions

Last updated on 2026-09-02

Every mutation in the kit uses Next.js Server Actions. They run server-side, use the appropriate Supabase client for reads and writes, and call revalidatePath() to refresh page data.

Architecture

Client Component --> Server Action --> Supabase Client --> Database
                                   --> revalidatePath() --> Page Refresh

All Server Actions are in lib/actions/ and marked with "use server" at the top of each file.

Auth Actions (lib/actions/auth.ts)

Action Parameters Description
signIn email, password Sign in with email/password
signUp email, password, fullName Create account; triggers profile creation
signOut - Clear session and redirect to /login
resetPassword email Send password reset email
signInWithOAuth provider Redirect to Google or GitHub OAuth

Contact Actions (lib/actions/contacts.ts)

Action Parameters Description
getContacts filters, search, page, limit Paginated list with full-text search
getContact id Single contact with joins
createContact FormData Insert contact and contact_tags
updateContact id, FormData Update contact and sync tags
deleteContact id Delete contact and associated tags
searchContacts query Full-text search via tsvector
importContacts contacts[] Bulk insert from CSV import

Company Actions (lib/actions/companies.ts)

Action Parameters Description
getCompanies filters, search, page, limit Paginated list with full-text search
getCompany id Single company with joins
createCompany FormData Insert company and company_tags
updateCompany id, FormData Update company and sync tags
deleteCompany id Delete company (admin only)
searchCompanies query Full-text search via tsvector

Deal Actions (lib/actions/deals.ts)

Action Parameters Description
getDeals pipelineId, filters Deals with stage, company, contact joins
getDeal id Single deal with all related data
createDeal FormData Insert deal, deal_products, deal_tags
updateDeal id, FormData Update deal details
updateDealStage dealId, stageId Move deal to new stage (triggers activity log)
deleteDeal id Delete deal (admin only)

Pipeline Actions (lib/actions/pipelines.ts)

Action Parameters Description
getPipelines - All pipelines with stage counts
getPipelineStages pipelineId Ordered stages for a pipeline
createPipeline name, description Create new pipeline (admin only)
updatePipeline id, data Update pipeline details (admin only)
createPipelineStage pipelineId, data Add stage to pipeline (admin only)
updatePipelineStage id, data Update stage name, color, probability (admin only)
reorderPipelineStages stageIds[] Update position ordering (admin only)
deletePipelineStage id Remove stage with deal reassignment (admin only)

Task Actions (lib/actions/tasks.ts)

Action Parameters Description
getTasks filters, search, page Paginated tasks with joins
createTask FormData Insert task
updateTask id, data Update task fields or toggle status
deleteTask id Delete task
bulkUpdateTasks ids[], status Batch status change
bulkDeleteTasks ids[] Batch delete

Activity Actions (lib/actions/activities.ts)

Action Parameters Description
getActivities filters, page Paginated activity log with joins
createActivity type, description, entityIds Log a new activity
getActivitiesForEntity entityType, entityId Activities for a specific contact/deal/company
exportActivities filters Generate CSV export

Tag Actions (lib/actions/tags.ts)

Action Parameters Description
getTags - All tags
createTag name, color Create new tag
deleteTag id Delete tag (admin only)
addTagsToEntity entityType, entityId, tagIds Add tags via junction table
removeTagFromEntity entityType, entityId, tagId Remove tag link

Email Actions (lib/actions/emails.ts)

Action Parameters Description
getEmails folder, search, page Paginated emails by folder
getEmail id Single email with contact join
createEmail data Create email (sent, draft, or inbox)
updateEmail id, data Toggle read, starred, or move folder
deleteEmail id Delete email
bulkUpdateEmails ids[], data Batch read/star updates

Email Template Actions (lib/actions/email-templates.ts)

Action Parameters Description
getEmailTemplates category, search Templates with optional filters
getEmailTemplate id Single template
createEmailTemplate data Create template
updateEmailTemplate id, data Update template; increments usage_count when used
duplicateEmailTemplate id Clone template with "Copy of" prefix
deleteEmailTemplate id Delete template

Email Sequence Actions (lib/actions/email-sequences.ts)

Action Parameters Description
getEmailSequences - All sequences with step counts
getEmailSequence id Sequence with all steps
createEmailSequence data Create sequence
updateEmailSequence id, data Update sequence status or details
deleteEmailSequence id Delete sequence and steps
createSequenceStep sequenceId, data Add step to sequence
updateSequenceStep id, data Update step content or position
deleteSequenceStep id Remove step
reorderSequenceSteps stepIds[] Update step positions

Team Actions (lib/actions/team.ts)

Action Parameters Description
getTeamMembers - All profiles
updateTeamMember id, data Update role, quota, job title (admin only)
removeTeamMember id Deactivate team member (admin only)
inviteTeamMember email, role Send invite via Supabase Auth (admin only)

Notification Actions (lib/actions/notifications.ts)

Action Parameters Description
getNotifications userId Unread notifications for current user
markAsRead id Mark single notification as read
markAllAsRead userId Mark all notifications as read
dismissNotification id Delete notification

Settings Actions (lib/actions/settings.ts)

Action Parameters Description
getSettings - Get CRM settings row
updateSettings data Update settings (admin only)

Report Actions (lib/actions/reports.ts)

Action Parameters Description
getSalesOverview dateRange KPIs, revenue trend, won/lost, by source
getPipelineAnalytics pipelineId Funnel, stage counts, time in stage, velocity
getTeamPerformance dateRange Leaderboard, radar data, activity distribution
getRevenueBreakdown dateRange By product, industry, deal size, LTV table
getForecastData quarter Monthly forecast by category and rep

Error Handling Pattern

All Server Actions follow this pattern:

"use server"

import { createAdminClient } from "@/lib/supabase/admin"
import { revalidatePath } from "next/cache"

export async function updateDealStage(dealId: string, stageId: string) {
  try {
    const supabase = createAdminClient()

    const { error } = await supabase
      .from("deals")
      .update({ stage_id: stageId })
      .eq("id", dealId)

    if (error) throw error

    revalidatePath("/deals")
    revalidatePath(`/deals/${dealId}`)

    return { success: true }
  } catch (err) {
    console.error("Failed to update deal stage:", err)
    return { success: false, error: "Failed to update deal stage" }
  }
}

Using Server Actions in Components

"use client"

import { updateDealStage } from "@/lib/actions/deals"

function StageSelect({ dealId, currentStage }: Props) {
  const [isPending, startTransition] = useTransition()

  function handleStageChange(stageId: string) {
    startTransition(async () => {
      const result = await updateDealStage(dealId, stageId)
      if (result.success) {
        toast.success("Deal stage updated")
      } else {
        toast.error(result.error)
      }
    })
  }

  return (
    <Select onValueChange={handleStageChange} disabled={isPending}>
      {/* ... */}
    </Select>
  )
}

Supabase Client Selection

Context Client RLS
Dashboard reads (all CRM data) Server client Yes (team member session)
Report aggregates Server client Yes (team member session)
Write operations (create, update) Admin client Bypassed (service role)
Delete operations Admin client Bypassed (service role)
Auth operations Server client N/A (Supabase Auth API)
Notifications (own only) Server client Yes (user's session)

The admin client (lib/supabase/admin.ts) uses SUPABASE_SERVICE_ROLE_KEY and should never be exposed to the client.