Phase 2 Grill Session — Decisions & Clarifications

Grill session between Wayne and Claude resolving eight open design questions for Fieldforce Phase 2 across Go backend, Astro mobile, and SolidStart panel. Decisions lock in atomic attachment linking, immutable ticked checklist items, upload-on-select for both platforms, and role-only approval access control.

  • Predecessor Fieldforce Phase 2 spec
  • Status Approved

View source markdown ↗ generated by claude · diagrams mermaid

Eight open design questions from the Fieldforce Phase 2 spec were resolved in this session, covering Go backend transaction semantics, checklist immutability, attachment upload timing, approval access control, and CSV export scope. The most significant change reverses the original spec: activity creation now rolls back atomically if any attachment link fails.

  • Scope Go backend · Astro mobile · SolidStart panel
  • Participants Wayne, Claude
  • Decisions 8 locked in
  • Spec Gaps Found 5 requiring updates
  • Phase Fieldforce Phase 2

Decisions Made

1. Activity + Attachment Linking — Atomic Transaction

Wrap activity creation and attachment linking in a single transaction. Roll back entirely on any invalid or already-used attachment ID; return 422.

Eliminates partial-failure gap in the original spec. An orphaned activity with missing attachments is worse than a clean failure — the caller can retry with correct IDs.

Rejected: original spec approach of creating activity even if attachment link fails (leaves orphaned activities).

2. Immutable Ticked Checklist Items

Once done: true, a checklist item is read-only. Go returns 422 if the client attempts to modify done, ticked_at, or ticked_by. Frontend disables editing for ticked items.

Prevents tick state corruption when a manager reorders or edits items. Immutability at the API layer is simpler than conflict resolution.

Rejected: server-side matching on reorder (complex), client-only enforcement (bypassable).

3. Checklist Item Semantics — Client Sends Full Objects

Client sends full checklist item objects including existing ticked_at/ticked_by on PATCH. Go stores as-is; no server-side matching.

Simplifies backend — no diffing, no item-level merge logic. Frontend is responsible for reading the current task and preserving tick state when editing text.

Rejected: server-side tick preservation by item ID (extra complexity for same result).

4. Pending Attachment Safeguard

The upload island tracks which attachments are in-flight. The sheet queries island state on dismiss. If pending uploads exist, a warning modal shows attachment details; dismiss is blocked until acknowledged.

Island is the authority on upload state; sheet should not duplicate that tracking. Both components cooperate: island owns state, sheet owns navigation control.

Rejected: island-only warning (sheet can't gate dismiss), sheet-only warning (doesn't know which files are at risk).

5. Attachment Upload Timing

Upload on file select for both mobile (Astro) and panel (SolidStart). Form submit sends only attachment_ids.

Consistent UX across surfaces. Pending attachment cleanup on abandoned uploads is acceptable. No extra user wait at submit time.

Rejected: upload on form submit (slower perceived UX, especially on mobile).

6. Approval Access Control — Role-Only

Any Manager, Supervisor, or Admin can approve any completed task. Self-approval is allowed in Phase 2. No exclusion logic.

Keeps the state machine simple. Self-approval edge cases can be revisited in a later phase if business rules require it.

Rejected: excluding the task creator from approving (adds conditional complexity without clear business need now).

7. Module Config Defaults — No Setup Requirement

Hardcoded defaults apply from first run. Orgs are not required to configure fieldforce settings before creating tasks.

Reduces friction for first-time use. Defaults are sensible and can be overridden later via the settings page.

Rejected: blocking task creation until config row exists (unnecessary friction, defaults are safe).

overdue_notify_after_hours default
0 (notify immediately)
escalation_after_hours default
24
Config check on task creation
None — overdue job uses defaults if no row exists

8. CSV Export Scope

Curated columns only: timestamp, user_name, action, task_id, details. Role gate same as audit log page. No date range limit.

Internal columns (id, created_by_id) have no value to the exporting user and expose DB internals. Pagination deferred.

Rejected: raw DB stream without column filtering (exposes internal columns).

Gaps & Spec Updates Required

Five gaps were identified in existing specs. Each must be updated before implementation.

  • Go spec Attachment linking atomicity — update "activity created even if link fails" to "rolled back on link failure" Gap 1
  • Go spec Add rule: once done: true, item is read-only; PATCH returns 422 on done/ticked_at/ticked_by modification Gap 2
  • SolidStart spec Add UI rule: ticked items rendered read-only; manager cannot edit text or state Gap 2
  • Go spec CSV export: clarify curated columns — timestamp, user_name, action, task_id, details; omit id, created_by_id Gap 3
  • Astro spec Add scenario: dismiss with pending upload → warning modal shows attachment ID + filename → user acknowledges or cancels Gap 4
  • SolidStart spec Add rule: ticked checklist items (done: true) are read-only in task form; manager can view ticked_at and ticked_by metadata only Gap 5

Critical Test Cases

  1. Activity + Attachment Atomicity

    Create activity with 3 attachment IDs; 2 valid, 1 already linked. Assert: activity is not created (transaction rolled back); response is 422.

  2. Checklist Item Immutability

    Tick an item on mobile (sets done: true, ticked_at, ticked_by). Manager tries to edit text or toggle done via PATCH. Assert: 422 "Cannot modify ticked checklist items".

  3. Pending Attachment Warning

    Upload photo in mobile sheet; don't submit activity. Try to dismiss sheet. Assert: warning modal appears; sheet does not close until acknowledged.

  4. CSV Export Columns

    Export audit log as CSV. Assert: CSV contains only timestamp, user_name, action, task_id, details. Assert: no id, created_by_id, or DB metadata columns present.

  5. Self-Approval

    Manager creates task, assigns to self, completes it, then approves it. Assert: status transitions to approved with no error.

  6. Config Defaults on First Run

    Create task in org with no org_module_configs row. Wait for overdue job to tick. Assert: job uses hardcoded defaults; no error.

Implementation Order (Recommended)

Go Backend

first
  1. Migration: 005_fieldforce_phase2.sql (attachments, org_module_configs, task columns)
  2. Attachment upload + atomic linking (transaction rollback on link failure)
  3. Checklist immutability validation on PATCH
  4. Overdue job (3 passes)
  5. Org module config API
  6. CSV export on audit endpoint (GET /fieldforce/audit?format=csv)

Mobile (Astro)

second
  1. LogActivitySheet + island coordination for pending attachment warning
  2. Photo + signature tabs with immediate upload
  3. TaskTimeline attachment rendering

Panel (SolidStart)

third
  1. Approval workflow (approve/reject buttons, review notes history)
  2. Photo + signature tabs in LogActivitySheet
  3. Pending approvals widget on dashboard
  4. Fieldforce settings page (org_module_configs UI)
  5. Checklist management in task form (read-only for ticked items)
  6. CSV export button on audit page

Open Questions (Post-Phase 2)