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:
@@ -304,7 +304,7 @@ async function searchIssuesByKeys(issueKeys, opts) {
|
||||
// or similar, but key-based search is inherently scoped. We add updated
|
||||
// clause for compliance.
|
||||
const keyList = issueKeys.map(k => `"${k}"`).join(', ');
|
||||
const jql = `key in (${keyList}) AND updated >= -24h AND project = ${JIRA_PROJECT_KEY}`;
|
||||
const jql = `key in (${keyList}) AND updated >= -72h AND project = ${JIRA_PROJECT_KEY}`;
|
||||
const fields = (opts && opts.fields) || DEFAULT_FIELDS;
|
||||
const maxResults = Math.min((opts && opts.maxResults) || 1000, 1000);
|
||||
|
||||
|
||||
26
backend/helpers/teams.js
Normal file
26
backend/helpers/teams.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// Shared BU team constants and validation
|
||||
// Used by user management routes, auth middleware, and frontend-facing endpoints.
|
||||
|
||||
const KNOWN_TEAMS = ['STEAM', 'ACCESS-ENG', 'ACCESS-OPS', 'INTELDEV'];
|
||||
|
||||
/**
|
||||
* Parse and validate a comma-separated teams string.
|
||||
* @param {string} teamsString - Comma-separated team identifiers (e.g. 'STEAM,ACCESS-ENG')
|
||||
* @returns {{ valid: boolean, teams: string[], invalid: string[] }}
|
||||
*/
|
||||
function validateTeams(teamsString) {
|
||||
if (!teamsString || typeof teamsString !== 'string' || teamsString.trim() === '') {
|
||||
return { valid: true, teams: [], invalid: [] };
|
||||
}
|
||||
|
||||
const teams = teamsString.split(',').map(t => t.trim()).filter(Boolean);
|
||||
const invalid = teams.filter(t => !KNOWN_TEAMS.includes(t));
|
||||
|
||||
return {
|
||||
valid: invalid.length === 0,
|
||||
teams,
|
||||
invalid
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { KNOWN_TEAMS, validateTeams };
|
||||
Reference in New Issue
Block a user