gigafibre-fsm/apps/ops/src/api/identity.js
louispaulb dec8321823 feat(ops): unified staff identity (label + email aliases + tech link + departed flag)
One person = one identity { label, primary_email (SSO login), alias_emails[],
tech_id, active, kind }. Every email + tech ID resolves to it.

Hub: lib/identity.js (NEW, SOURCE UNIQUE) — resolver + secured endpoints
(/identity/map|resolve read; upsert/alias/merge/delete admin-only). server.js
mounts /identity. auth.getDisplayNameByEmail consults the identity label first
(any alias → full name everywhere). Seed: Louis-Paul Bourdon, Louis Morneau.

SPA: composables/useIdentity + api/identity. IssueDetail dedupes assignment by
identity (m'ajouter + search = same person → no double chip), shows full names,
and hides departed people (active:false) from the picker. IdentityManager.vue
(Settings → Identités tab): edit label/aliases/tech link, merge duplicates,
block/reactivate (departed = non-destructive: hidden from pickers, history kept).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:22:48 -04:00

18 lines
1009 B
JavaScript

// API identité unifiée — appelle le hub /identity/* (écritures réservées admin côté hub).
import { HUB_URL as HUB } from 'src/config/hub'
async function j (path, init) {
const r = await fetch(HUB + path, init)
const d = await r.json().catch(() => ({}))
if (!r.ok) throw new Error(d.error || ('Identity API ' + r.status))
return d
}
const post = (path, body) => j(path, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body || {}) })
export const getIdentityMap = () => j('/identity/map')
// upsert : { key?, label, primary_email, alias_emails?, tech_id?, employee? }
export const upsertIdentity = (body) => post('/identity', body)
export const setAlias = (key, email, remove = false) => post('/identity/' + encodeURIComponent(key) + '/alias', { email, remove })
export const mergeIdentity = (into, from) => post('/identity/merge', { into, from })
export const deleteIdentity = (key) => j('/identity/' + encodeURIComponent(key), { method: 'DELETE' })