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.
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:
- Global
admin_feature_flags (platform-wide kill switch).
- 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.