Arbetsledarvyn: organisationsöversikt med status och statistik
Rollen arbetsledare får sin vy enligt Master Prompt ('se alla ärenden,
följa status, skapa statistik'):
- Ny behörighetsstyrd endpoint GET /api/oversikt (arbetsledare/admin):
organisationens alla ärenden med status, antal händelser, deltagande
tekniker, objekt och felbeskrivning — allt härlett ur händelseloggen
i en SQL-fråga, aldrig lagrat separat. Tekniker nekas med 403.
- Ny sida /felsokning/oversikt: statistikpanel (totalt/pågående/
avslutade + genomsnittlig ledtid), ärendelista med status och
'Öppna ärendet' som hämtar händelserna till enheten — konfliktfri
flätning om en lokal kopia redan finns. Länkas från kontopanelen
för arbetsledare/admin.
- Integrationstestet utökat: tekniker nekas översikten, arbetsledaren
ser organisationens ärenden och härledningarna (felbeskrivning,
status, händelseantal) stämmer.
Ej implementerat (medvetet): omfördelning av ärenden — överlämnings-
händelsen täcker handover tills en ansvarig-modell införs.
Verifierat: integrationstestets 17 kontroller gröna mot Postgres 16,
28 vitest-tester gröna, produktionsbygge ok, Playwright-röktest grönt.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
This commit is contained in:
@@ -99,4 +99,17 @@ kontroll "org A har två användare" "$ANTAL_ANV" "2"
|
||||
ANTAL=$(curl -s "$BAS/api/arenden/arende-test1/handelser" -H "Authorization: Bearer $TOKEN_J" | falt .handelser.length)
|
||||
kontroll "tekniker i samma org når ärendet" "$ANTAL" "2"
|
||||
|
||||
# 9. Organisationsöversikten: tekniker nekas; arbetsledare får status ur loggen
|
||||
KOD=$(curl -s -o /dev/null -w "%{http_code}" "$BAS/api/oversikt" -H "Authorization: Bearer $TOKEN_J")
|
||||
kontroll "tekniker nekas översikten" "$KOD" "403"
|
||||
curl -s -X POST "$BAS/api/anvandare" -H "Authorization: Bearer $TOKEN_A" -H 'Content-Type: application/json' \
|
||||
-d '{"epost":"lisa@a.se","losenord":"hemligt123","namn":"Lisa","roll":"arbetsledare"}' >/dev/null
|
||||
TOKEN_L=$(curl -s -X POST "$BAS/api/auth/logga-in" -H 'Content-Type: application/json' \
|
||||
-d '{"epost":"lisa@a.se","losenord":"hemligt123"}' | falt .token)
|
||||
OVERSIKT=$(curl -s "$BAS/api/oversikt" -H "Authorization: Bearer $TOKEN_L")
|
||||
kontroll "arbetsledaren ser organisationens ärenden" "$(echo "$OVERSIKT" | falt .arenden.length)" "1"
|
||||
kontroll "översikten härleder felbeskrivning" "$(echo "$OVERSIKT" | falt '.arenden[0].felbeskrivning')" "Startar inte"
|
||||
kontroll "översikten härleder status" "$(echo "$OVERSIKT" | falt '.arenden[0].avslutat')" "false"
|
||||
kontroll "översikten räknar händelser" "$(echo "$OVERSIKT" | falt '.arenden[0].antal_handelser')" "2"
|
||||
|
||||
echo "Integrationstest: allt grönt"
|
||||
|
||||
@@ -220,6 +220,35 @@ export function skapaServer() {
|
||||
}
|
||||
}
|
||||
|
||||
// Organisationsöversikt för arbetsledare/admin: alla ärenden med
|
||||
// status, deltagande tekniker och sammanfattning — härlett ur
|
||||
// händelseloggen, aldrig lagrat separat.
|
||||
if (req.method === "GET" && vag === "/api/oversikt") {
|
||||
if (anspr.roll !== "arbetsledare" && anspr.roll !== "admin") {
|
||||
return svara(res, 403, { error: "Kräver arbetsledar- eller administratörsbehörighet." });
|
||||
}
|
||||
const rader = await pool.query(
|
||||
`select a.id, a.nummer, a.skapad, a.delningskod, a.metodik_id,
|
||||
count(h.id)::int as antal_handelser,
|
||||
min(h.tidpunkt) as forsta,
|
||||
max(h.tidpunkt) as senaste,
|
||||
coalesce(bool_or(h.handelse->>'typ' = 'arende_avslutat'), false) as avslutat,
|
||||
(array_agg(h.handelse->'objekt'->>'beskrivning')
|
||||
filter (where h.handelse->>'typ' = 'objekt_identifierat'))[1] as objekt,
|
||||
(array_agg(h.handelse->>'text')
|
||||
filter (where h.handelse->>'typ' = 'felbeskrivning'))[1] as felbeskrivning,
|
||||
array_agg(distinct h.anvandare) filter (where h.anvandare is not null) as tekniker
|
||||
from felsokning_arenden a
|
||||
left join felsokning_handelser h on h.arende_id = a.id
|
||||
where a.organisation_id = $1
|
||||
group by a.id
|
||||
order by max(h.tidpunkt) desc nulls last
|
||||
limit 200`,
|
||||
[anspr.org],
|
||||
);
|
||||
return svara(res, 200, { arenden: rader.rows });
|
||||
}
|
||||
|
||||
if (req.method === "GET" && vag === "/api/arenden") {
|
||||
const rader = await pool.query(
|
||||
`select id, nummer, skapad, delningskod, metodik_id from felsokning_arenden
|
||||
|
||||
Reference in New Issue
Block a user