agmission/Development/server/docs/PILOT_DASHBOARD_BACKEND_SUMMARY.md

194 lines
8.2 KiB
Markdown

# Pilot Dashboard Backend Summary
> **Superseded** — This document was the initial design analysis and planning doc.
> The definitive API specification (including frontend integration guide) is now in:
> **[PILOT_DASHBOARD_API.md](./PILOT_DASHBOARD_API.md)**
>
> The content below is retained for historical context (original requirements analysis,
> open decisions log, and delivery plan).
---
## Document Info
- Scope: Backend support for Pilot Analytics Dashboard (Phase 1)
- Source inputs: Product Owner brief v1.5 and Requirements Analysis v1.5
- Validation status: aligned with current server codebase (models, constants, routes, middleware)
- Date: 2026-04-29
## 1. Objective
Build backend APIs and aggregation logic for a pilot-only analytics dashboard, using existing AgMission data (Job, Application, Application_Detail), with strict role/data isolation and production-safe query patterns.
## 2. Current Backend Baseline (Verified)
### 2.1 What already exists
- Pilot CRUD/search routes exist at /api/pilots via routes/pilot.js and controllers/pilot.js.
- Global route registration follows function-based mounting in routes/index.js.
- Auth middleware checkUser is applied globally before route mounting in server.js.
- Standard centralized error handling is already in place.
### 2.2 What does not exist yet
- No dashboard analytics controller/routes for pilots.
- No endpoints currently serving KPI/summary/trend/active-jobs/performance payloads.
- No implemented status transition endpoint for Mark as Completed.
### 2.3 Key model and constant facts
- Job status constants exist in helpers/job_constants.js:
- NEW 0, READY 1, DOWNLOADED 2, SPRAYED 3, COMPLETED 4, INVOICED 5, ARCHIVED 9.
- Job pilot assignment is by Job.operator (optional ObjectId).
- Job ownership is by Job.byPuid (Applicator account).
- Aircraft display source is Job.vehicle.
- Job_Assign is assignment workflow data and should not be used as pilot-job source of truth for dashboard metrics.
- Application links to job by numeric jobId.
- Application aggregates needed for dashboard already exist: totalSprayed, totalFlightTime, totalSprLength, totalSprayMat, avgSpraySpeed.
- Application_Detail contains xTrack, sprayHeight, radarAlt, gpsAlt and has primary index on fileId.
## 3. Confirmed Design Direction So Far
### 3.1 Pilot scoping model
The only reliable pilot scope for dashboard metrics is:
1. Resolve jobIds from Job where operator = current pilot user id.
2. Aggregate Application records where jobId is in that list.
3. For quality gauges, resolve recent app files and aggregate Application_Detail by fileId.
This avoids wrong assumptions around uploader identity and keeps logic aligned with how pilot assignment is represented.
### 3.2 Dashboard modules (backend perspective)
- KPI cards: assigned jobs/ha + sprayed today + flight hours today.
- Daily summary: today vs yesterday deltas for hectares, hours, ha/hr, speed, volume.
- Operations today: distance and spray volume totals.
- Active jobs panel: per-job progress and actual applied volume with status mapping.
- Trend: daily hours and hectares over date range (default current week).
- Performance indicators: average XT error and altitude, with threshold bands.
- Mark Job as Completed: manual SPRAYED to COMPLETED transition.
## 4. Proposed API Surface (Phase 1)
Suggested new route group:
- /api/dashboard/pilot
Suggested endpoints:
- GET /api/dashboard/pilot/kpi
- GET /api/dashboard/pilot/summary
- GET /api/dashboard/pilot/trend
- GET /api/dashboard/pilot/active-jobs
- GET /api/dashboard/pilot/performance
Job completion action:
- PATCH /api/jobs/:jobId/complete
Implementation notes:
- Keep endpoint naming camelCase where needed in path segments to match existing project conventions.
- Reuse existing auth middleware and error classes for consistency.
## 5. Query and Aggregation Approach
### 5.1 KPI and summary
- Base filter: Job.find({ operator: pilotId, markedDelete: { $ne: true } }).
- Read assigned hectares from Job.ttSprArea.
- Aggregate Applications by jobId with time-window filtering for today/yesterday.
- Convert units in backend responses:
- hours = seconds / 3600
- distance = meters / 1000
- speed = m/s to km/h when needed
### 5.2 Active jobs
- Start from pilot-scoped jobs.
- Aggregate per job from Application:
- haSprayed = sum totalSprayed
- volumeApplied = sum totalSprayMat
- Compute progressPct = min(100, max(0, haSprayed / haTotal * 100)).
- Status display mapping:
- NEW (0): no progress bar
- READY/DOWNLOADED/SPRAYED: IN PROGRESS behavior
- COMPLETED (4): full bar
### 5.3 Trend
- Accept startDate/endDate (max 90 days recommended).
- Default to current calendar week (Mon-Sun) in user timezone policy.
- Group by day and fill missing dates with zero values.
### 5.4 Performance
- Use recent application files only (for bounded cost).
- Fetch recent pilot-scoped Application records, then map to related fileIds.
- Query Application_Detail with fileId IN [...].
- Compute:
- avgXtErrorMeters = avg(abs(xTrack))
- altitude with source priority sprayHeight then radarAlt
- Return no-data state when sample is empty or sensor fields unavailable.
## 6. Authorization and Data Isolation
### 6.1 Pilot dashboard endpoints
- Must be pilot-only.
- Always derive pilotId from authenticated user context, never trust client-provided user ids.
- Never expose other pilots or global Applicator data.
### 6.2 Mark as Completed endpoint
- Allowed transition: SPRAYED (3) to COMPLETED (4) only.
- Recommended permission for Phase 1: Applicator owner only (Job.byPuid match).
- Return 409 for invalid state transition.
- Return 403 when caller is not authorized.
## 7. Performance and Scalability Considerations
- Application_Detail is large-scale; avoid broad scans.
- Always drive quality queries by fileId-scoped subsets.
- Keep performance endpoint sample bounded (for example, last 10 files as proposed).
- Ensure lean reads for read-only queries where practical.
- Add/validate indexes only where query plans prove necessary after measurement.
## 8. Key Product Decisions Still Open (Affect Backend)
- Active Jobs cutoff status set (exact statuses to include).
- Assigned Jobs KPI business meaning (all-time vs open vs season).
- Altitude fallback policy when sprayHeight/radarAlt is absent.
- Whether pilot can trigger completion action or Applicator-only.
- Final timezone policy for Today/Yesterday windows (requirements currently point to browser timezone).
## 9. Recommended Delivery Plan
### Phase A - Foundation
- Add dashboard route/controller/service skeleton.
- Add shared pilot scope resolver (pilot to jobIds).
- Add consistent response DTO contracts.
### Phase B - Core endpoints
- Implement kpi, summary, trend, active-jobs.
- Add input validation for date range/timezone params.
- Add empty-state and zero-safe calculations.
### Phase C - Performance indicators
- Implement performance endpoint with bounded recent-file strategy.
- Add explicit source label and no-data states.
### Phase D - Job completion workflow
- Implement PATCH complete endpoint with strict state and auth checks.
- Add/update JSDoc for API docs.
### Phase E - Verification
- Create tests scripts in tests/ for each endpoint and transition scenarios.
- Validate role isolation, response shapes, and edge cases (no jobs, no apps, missing altitude).
- Run scripts and record execution output.
## 10. Risks and Mitigations
- Risk: Missing Job.operator on some jobs leads to undercount.
- Mitigation: surface this as known data-quality dependency in API/docs.
- Risk: Inconsistent device coverage for altitude metrics.
- Mitigation: deterministic source priority + explicit no-data response.
- Risk: Heavy Application_Detail scans.
- Mitigation: strict fileId-scoped querying and bounded sample windows.
- Risk: Frontend status mismatch for COMPLETED/INVOICED labels.
- Mitigation: coordinate backend constants and frontend enum alignment before rollout.
## 11. Definition of Done for Backend
- Pilot dashboard endpoints implemented and documented.
- Mark Complete transition endpoint implemented with auth and state guards.
- APIs return stable contracts for all normal and empty-data scenarios.
- Endpoint behavior validated via executed test scripts.
- Relevant docs updated in docs/ and JSDoc included for apidoc generation.