ModulesPrestartsFeaturesPrestart CRUD

Prestart CRUD

Create, view, edit, publish, and delete prestart checklists. Prestarts start as drafts and can be published to lock core fields.

Create Prestart

  1. User navigates to /admin/prestarts/new or /dashboard/prestarts/new
  2. RSC page reads org_id and project_id from cookies, fetches currentUserId via getCurrentUser()
  3. <PrestartForm mode="create"> renders with:
    • Supervisor dropdown — project members with role supervisor, senior_supervisor, master_admin, or organisational_manager. Auto-selects current user if they’re a supervisor.
    • Date & Time — datetime-local input, defaults to now
    • Toolbox Talk Duration — select: 0/15/30/60 minutes
    • Shift Type — select: Day/Afternoon/Night
    • Site Location — free-text input
  4. On “Create Draft”, the server action validates via Zod, calls POST /v1/orgs/{orgId}/projects/{projectId}/prestarts
  5. Go handler validates membership + supervisor role, inserts into prestarts table
  6. On success, user is redirected to the detail page (/admin/prestarts/{id})

List Prestarts

The prestart list page (/admin/prestarts or /dashboard/prestarts) is a React Server Component that fetches data server-side:

  1. RSC calls listPrestarts(orgId, projectId, { status, page, page_size }) via server action
  2. Go handler executes ListProjectPrestarts query with filters and pagination
  3. <PrestartTableV2> renders with columns: Status (badge), Date, Shift (badge), Supervisor, Location, Duration, Activities count, Sign-Ons count
  4. URL-based filtering via status dropdown (All/Draft/Published)
  5. Pagination controls at the bottom
  6. Row click navigates to detail page

List Query

SELECT p.id, u.name AS supervisor_name, p.prestart_datetime, p.duration,
       p.shift_type, p.site_location, p.status,
       (SELECT COUNT(*) FROM activities a WHERE a.prestart_id = p.id AND a.deleted_at IS NULL) AS activity_count,
       (SELECT COUNT(*) FROM prestart_sign_ons s WHERE s.prestart_id = p.id) AS sign_on_count,
       p.created_at
FROM prestarts p
JOIN users u ON u.id = p.supervisor_id
WHERE p.org_id = $1 AND p.project_id = $2 AND p.deleted_at IS NULL
ORDER BY p.prestart_datetime DESC
LIMIT $3 OFFSET $4

View Prestart Detail

The detail page (/admin/prestarts/[prestartId]) renders <PrestartDetail>, a client component that fetches the full prestart via useQuery:

  • Details tab — Draft: inline edit form; Published: read-only field grid
  • Activities tab — Activity cards with description, resource chips, add/edit/delete
  • Sign-Ons tab — List of signed-on users with role badges, add/remove
  • Comments tab — <PrestartComments> component with input + history

The detail query returns the prestart with all nested data (activities with resources, sign-ons with user info, comments, files) assembled in the Go service from multiple queries.

Beside Back to Prestarts, the previous and next day buttons step to the same supervisor’s prestart on the nearest earlier or later day, on the same shift — see Previous & Next Day.

Update Prestart (Draft Only)

Draft prestarts can be edited inline on the Details tab:

  1. User modifies fields in the <DraftDetailsEditor> section
  2. On “Save Changes”, calls updatePrestart server action
  3. Go handler checks status = 'draft', uses COALESCE pattern for partial updates:
UPDATE prestarts SET
  supervisor_id = COALESCE(sqlc.narg('supervisor_id'), supervisor_id),
  prestart_datetime = COALESCE(sqlc.narg('prestart_datetime'), prestart_datetime),
  ...
WHERE id = $1 AND org_id = $2 AND status = 'draft' AND deleted_at IS NULL

Publish Prestart

  1. User clicks “Publish” button (visible only on draft prestarts)
  2. Confirmation dialog: “Core fields will be locked”
  3. Server action calls POST /prestarts/{id}/publish
  4. Go handler sets status = 'published' and published_at = NOW()
  5. TanStack Query invalidation refreshes the detail view with locked fields

Delete Prestart

  1. User clicks “Delete” button
  2. Confirmation dialog
  3. Server action calls DELETE /prestarts/{id}
  4. Go handler sets deleted_at = NOW() (soft delete)
  5. User redirected back to the prestart list

Security

  • Create: Only supervisors, senior supervisors, and admins can create prestarts
  • Edit/Publish/Delete: Only the prestart creator or an admin
  • View: Any project member can view any prestart in their project
  • All queries include AND org_id = $org_id for tenant isolation

Key Files

FilePurpose
backend/db/queries/prestarts.sqlSQL queries for CRUD + publish
backend/api/internal/prestart/service.goBusiness logic, assembly
backend/api/internal/prestart/handler.goHTTP handlers
apps/web/src/actions/prestarts.tsServer actions with Zod validation
apps/web/src/app/_components/prestart-form.tsxCreate/edit form
apps/web/src/app/_components/prestart-detail.tsxDetail view with tabs
apps/web/src/app/admin/prestarts/_components/prestart-table-v2.tsxList table