Introduce server-side team-scoped data access enforcement:
- Add TEAM_TO_IVANTI/IVANTI_TO_TEAM mapping to helpers/teams.js
- Add requireTeam() middleware to middleware/auth.js
- Admin bypass (req.teamScope = null)
- 403 for users with no team assignment
- Populates req.teamScope with short and ivanti name arrays
- Ivanti findings: replace client ?teams= param with req.teamScope filtering
on GET /, /counts, /counts/history, /fp-workflow-counts, POST /sync
- Override and note endpoints verify finding is in team scope
- Compliance: add requireTeam() router-level, validate ?team= param against scope
on GET /items and GET /summary
- CARD: validate teamName param on GET /teams/:teamName/assets
- Todo queue: verify findings belong to user's teams on POST /batch
- Clarify IVANTI_BU_FILTER comment (sync-level vs query-time filtering)
- Update 14 test files to include requireTeam in auth middleware mocks
Per-metric remediation plan scoping (GitLab issue #19):
- Add metric_id column to compliance_item_history table (migration)
- Extend PATCH /items/:hostname/metadata to accept metric_id/metric_ids
for targeting specific metrics instead of all active items
- Add MetricChipSelector UI in detail panel for choosing which metrics
to apply resolution_date and remediation_plan changes to
- Display per-metric labels (MetricChip or 'All metrics') on history entries
- Backward compatible: omitting metric_ids preserves hostname-level behavior
CI/CD pipeline improvements:
- Add migration idempotency integration test (runs against real Postgres)
- Add post-deploy smoke tests for compliance and VCL endpoints
- Bump lint --max-warnings from 10 to 25
- Configure varsIgnorePattern for _ prefix convention on unused vars
Closes#19