📋 Description
The analytics service in src/services/analytics/service.ts (AnalyticsService.getSummary, refreshConcurrently, computeStaleness) serves aggregate metrics consumed by src/routes/analytics.ts. Aggregates must be computed within a single tenant's data; any path that omits the tenant filter risks cross-tenant data exposure.
This issue makes tenantId a required, validated input to getSummary and adds tests proving aggregates never include another tenant's rows — using the mandatory tenant context from src/middleware/tenantContext.ts.
Why this matters: an analytics aggregate that silently spans tenants is a serious data-isolation bug. Making tenant scope mandatory and tested closes the gap at the service boundary.
🎯 Requirements & Context
Functional requirements
Context & constraints
- Align with the project's mandatory tenant-context conventions in
src/middleware/tenantContext.ts and src/utils/tenantContext.ts.
- Do not change the metric definitions themselves; only their scoping.
🛠️ Suggested Execution
1. Fork & branch
git checkout -b security/analytics-tenant-scope
2. Implement changes
- Thread
tenantId through getSummary and queries; namespace cache keys by tenant.
- Add TSDoc on the tenant-scoping contract.
- Extend
src/services/analytics/service.test.ts with two-tenant isolation cases.
3. Test & commit
npm run test -- analytics
npm run lint
npm run build
- Edge cases: missing tenant, tenant with no data, identical metrics across tenants, cache key collision attempt.
Example commit message
security(analytics): require validated tenant scope on getSummary
Mandates tenantId, filters all queries, and namespaces cache keys per tenant
in services/analytics/service.ts.
✅ Acceptance Criteria & Guidelines
| Requirement |
Target |
| Mandatory validated tenant scope + cache namespacing |
Required |
| Two-tenant isolation tests |
Required |
| Coverage of analytics service |
≥ 95% |
npm run lint + npm run build clean |
Required |
| Timeframe |
96 hours from assignment |
💬 Community & Support
Questions and design discussion — join the GrantFox contributor community on Discord: https://discord.gg/nmnPBkBge
Please comment on this issue to ask to be assigned before you start. 🚀
📋 Description
The analytics service in
src/services/analytics/service.ts(AnalyticsService.getSummary,refreshConcurrently,computeStaleness) serves aggregate metrics consumed bysrc/routes/analytics.ts. Aggregates must be computed within a single tenant's data; any path that omits the tenant filter risks cross-tenant data exposure.This issue makes
tenantIda required, validated input togetSummaryand adds tests proving aggregates never include another tenant's rows — using the mandatory tenant context fromsrc/middleware/tenantContext.ts.🎯 Requirements & Context
Functional requirements
tenantIdargument ongetSummary(no implicit/default tenant fallback).tenant_id.computeStalenessand the cached path also respect tenant scoping (no cross-tenant cache key collisions).Context & constraints
src/middleware/tenantContext.tsandsrc/utils/tenantContext.ts.🛠️ Suggested Execution
1. Fork & branch
2. Implement changes
tenantIdthroughgetSummaryand queries; namespace cache keys by tenant.src/services/analytics/service.test.tswith two-tenant isolation cases.3. Test & commit
npm run test -- analytics npm run lint npm run buildExample commit message
✅ Acceptance Criteria & Guidelines
npm run lint+npm run buildclean💬 Community & Support
Questions and design discussion — join the GrantFox contributor community on Discord: https://discord.gg/nmnPBkBge
Please comment on this issue to ask to be assigned before you start. 🚀