Fieldforce Backend Implementation

Overview

The Go backend for Fieldforce uses hexagonal clean architecture (Ports & Adapters + DDD), mirroring the pattern established by the leave module. It exposes RESTful HTTP endpoints for managing tasks, activities, and accessing audit logs.

Layered Structure

  • Domain Entities: Task, Activity, TaskStatus, TaskPriority.
  • Application Ports: Defines interfaces for Repositories (TaskRepository, ActivityRepository, AuditLogRepository) and Services (TaskService, ActivityService).
  • Use Cases: Core business logic in TaskService, wrapped by AuditedTaskService for automatic audit logging using a decorator pattern.
  • Persistence Adapter: PostgreSQL implementations mapped to DB row structs, handling junction tables seamlessly.
  • HTTP Adapter: Echo handlers under internal/modules/fieldforce/adapter/inbound/http/.

State Machine

Task status transitions are enforced using a pure-function generic state machine residing in the shared kernel (internal/shared/domain/statemachine).
The PATCH API uses event-based transitions (e.g., { "event": "approve" }) rather than target statuses to ensure the state machine executes all guard logic natively at the server. See ADR-0013.

Pagination

The backend API exposes an endpoint that supports dual pagination modes via the X-Pagination-Type header:
  • Offset Pagination: Commonly used by the Desktop Panel (SolidStart) via page and page_size.
  • Cursor Pagination: Used by the Mobile Web app (Astro) for stable infinite scrolling over tasks without skips.

Feature Flags (ADR-0016)

Two-tier feature flag middleware gates access to the Fieldforce module:
  1. Global admin_feature_flags (platform-wide kill switch).
  2. Per-org org_feature_flags (tenant-specific toggle).
Effective access requires both layers to be enabled. Missing rows are defensively treated as enabled.

Auditing and Feedback Loop

  • Audit Logs: All state transitions and task actions generate audit events written to the shared audit_log table with entity_type = 'FIELDFORCE_TASK'.
  • Append-Only Notes: Rejection feedback from managers is securely stored as an append-only JSONB array (review_notes) in ff_tasks (ADR-0015) to maintain explicit, immutable context across multiple review cycles.