feat: add multi-BU tenancy with per-user team scoping (Option B)
- Add bu_teams column to users table (migration + fresh schema) - Create shared KNOWN_TEAMS constant and validateTeams helper - Expose user teams in auth middleware, login, and /me responses - Add bu_teams CRUD to user management routes with audit logging - Make Ivanti FINDINGS_FILTERS configurable via IVANTI_BU_FILTER env var - Add query-time team filtering to GET /findings and /findings/counts - Update AuthContext with teams helpers and admin scope toggle - Create AdminScopeToggle component (My Teams / All BUs) - Scope ReportingPage findings fetch by user teams - Scope CompliancePage team selector by user teams - Scope ExportsPage findings exports by user teams - Add BU teams multi-select to UserManagement create/edit forms - Display team badges in user list table
This commit is contained in:
@@ -19,9 +19,9 @@ All API calls are made from a single Node.js backend process. The integration us
|
||||
| Inter-request delay — writes | 2 seconds minimum between PUT/POST/DELETE requests |
|
||||
| Explicit field lists | Every GET includes `?fields=` parameter; `/rest/api/2/field` is blocked |
|
||||
| No bulk updates | Issues are updated one at a time; `/rest/api/2/issue/bulk` is blocked |
|
||||
| Bulk reads via JQL | Multi-ticket sync uses a single `GET /rest/api/2/search` with JQL query parameters, not per-issue GETs |
|
||||
| Bulk reads via JQL | Multi-ticket sync uses a single `GET /rest/api/2/search` with predefined key-based JQL query parameters, not per-issue GETs; no arbitrary JQL passthrough |
|
||||
| Single-issue fetch via JQL | `GET /rest/api/2/search?jql=key="KEY" AND project=<KEY>&fields=...&maxResults=1` |
|
||||
| JQL scoping | All recurring JQL queries include `updated >= -Xh` clause and `project = <KEY>` scoping |
|
||||
| JQL scoping | All recurring JQL queries use predefined scoped patterns with `updated >= -72h` clause and `project = <KEY>` scoping; no arbitrary JQL passthrough |
|
||||
| `maxResults` cap | Search queries capped at 1 000 results per page |
|
||||
|
||||
---
|
||||
@@ -96,7 +96,7 @@ All API calls are made from a single Node.js backend process. The integration us
|
||||
| **Frequency** | Manual, estimated 5–10 per day |
|
||||
| **Purpose** | Move ticket through workflow states (e.g., Open to In Progress to Closed) |
|
||||
|
||||
### 8. JQL Search (Bulk Sync)
|
||||
### 8. Scoped Bulk Sync via JQL
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
@@ -104,10 +104,10 @@ All API calls are made from a single Node.js backend process. The integration us
|
||||
| **Trigger** | Admin clicks "Sync All" on the Jira tickets panel |
|
||||
| **Frequency** | Manual, estimated 1–3 times per day |
|
||||
| **Purpose** | Bulk-refresh all tracked tickets in a single request instead of per-issue GETs |
|
||||
| **JQL pattern** | `key in ("KEY-1", "KEY-2", ...) AND updated >= -24h AND project = <KEY>` |
|
||||
| **JQL pattern** | `key in ("KEY-1", "KEY-2", ...) AND updated >= -72h AND project = <KEY>` |
|
||||
| **Fields requested** | `summary, status, assignee, created, updated, priority, issuetype, project, resolution` |
|
||||
| **Batch size** | 100 keys per JQL query; multiple batches if needed |
|
||||
| **Notes** | Uses GET with URL-encoded query parameters per Charter compliance. Stops early if rate limit budget is running low (burst remaining <= 5 or daily remaining <= 10) |
|
||||
| **Notes** | Uses GET with URL-encoded query parameters per Charter compliance. JQL is predefined and scoped — constructed from known tracked issue keys, a fixed 72-hour window, and the configured project key. No arbitrary JQL is accepted from the frontend. Stops early if rate limit budget is running low (burst remaining <= 5 or daily remaining <= 10) |
|
||||
|
||||
### 9. Issue Lookup
|
||||
|
||||
@@ -131,7 +131,7 @@ All API calls are made from a single Node.js backend process. The integration us
|
||||
| Add comment | 5–15 | POST | 2s |
|
||||
| Get transitions | 5–10 | GET | 1s |
|
||||
| Transition issue | 5–10 | POST | 2s |
|
||||
| JQL search (sync) | 1–5 | GET | 1s |
|
||||
| Scoped bulk sync | 1–5 | GET | 1s |
|
||||
| Issue lookup | 5–15 | GET | 1s |
|
||||
| **Total estimated** | **43–120** | | |
|
||||
|
||||
@@ -145,6 +145,7 @@ The integration explicitly blocks these endpoints to comply with Charter policy:
|
||||
|
||||
- `/rest/api/2/field` — field metadata is never queried; fields are specified in code
|
||||
- `/rest/api/2/issue/bulk` — bulk updates are not used; issues are updated individually
|
||||
- `POST /rest/api/2/search` — arbitrary JQL search via POST is not used; all searches use `GET /rest/api/2/search` with URL-encoded query parameters and predefined scoped JQL patterns
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user