Inställningar: admin väljer objekttyper och identifieringsmetoder
Ny inställningssida (/felsokning/installningar) där systemadmin väljer vad som visas när ett ärende startas. På plattformen sparas valet på organisationen (alla läser via GET /api/organisation, bara admin ändrar via POST /api/organisation/installningar); i lokalt läge gäller valet enheten. Nytt ärende-vyn filtrerar knapparna efter valet. - Klientmodul med normalisering: okända värden filtreras, tomma listor faller tillbaka till standard (går aldrig att låsa ute allt) - installningar-kolumn (jsonb) på organisationer, idempotent migrering - OpenAPI-specen utökad; paritets- och enhetstester - Integrationstest: läsning för alla, 403 för tekniker, org-bred effekt, 400 för tomma listor Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
This commit is contained in:
@@ -122,6 +122,23 @@ curl -s -X POST "$BAS/api/arenden/arende-test1/handelser" -H "Authorization: Bea
|
||||
-d '{"handelser":[{"id":"h-omf","tidpunkt":"2026-08-03T08:05:00Z","anvandare":"Lisa","handelse":{"typ":"ansvarig_satt","ansvarig":"Johan"}}]}' >/dev/null
|
||||
kontroll "översikten visar ny ansvarig" "$(curl -s "$BAS/api/oversikt" -H "Authorization: Bearer $TOKEN_L" | falt '.arenden[0].ansvarig')" "Johan"
|
||||
|
||||
# 9c. Organisationsinställningar: alla läser, bara admin ändrar
|
||||
INST=$(curl -s "$BAS/api/organisation" -H "Authorization: Bearer $TOKEN_J")
|
||||
kontroll "inloggad läser organisationen" "$(echo "$INST" | falt .namn)" "Verkstad A"
|
||||
KOD=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$BAS/api/organisation/installningar" \
|
||||
-H "Authorization: Bearer $TOKEN_J" -H 'Content-Type: application/json' \
|
||||
-d '{"objekttyper":["Fordon"],"identifieringsmetoder":["VIN"]}')
|
||||
kontroll "tekniker nekas ändra inställningar" "$KOD" "403"
|
||||
curl -s -X POST "$BAS/api/organisation/installningar" -H "Authorization: Bearer $TOKEN_A" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"objekttyper":["Fordon","Hydraulik"],"identifieringsmetoder":["VIN","Manuell inmatning"]}' >/dev/null
|
||||
INST=$(curl -s "$BAS/api/organisation" -H "Authorization: Bearer $TOKEN_J")
|
||||
kontroll "inställningarna gäller hela organisationen" "$(echo "$INST" | falt '.installningar.objekttyper.join(",")')" "Fordon,Hydraulik"
|
||||
KOD=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$BAS/api/organisation/installningar" \
|
||||
-H "Authorization: Bearer $TOKEN_A" -H 'Content-Type: application/json' \
|
||||
-d '{"objekttyper":[],"identifieringsmetoder":["VIN"]}')
|
||||
kontroll "tomma listor avvisas" "$KOD" "400"
|
||||
|
||||
# 10. Live Share-behörighetsnivåer: kund/partner/intern + återkallelse
|
||||
curl -s -X POST "$BAS/api/arenden/arende-test1/handelser" -H "Authorization: Bearer $TOKEN_A" -H 'Content-Type: application/json' \
|
||||
-d '{"handelser":[{"id":"h3","tidpunkt":"2026-08-03T08:03:00Z","anvandare":"Anna","handelse":{"typ":"hypotes","text":"Trasigt relä","niva":"lag"}}]}' >/dev/null
|
||||
|
||||
@@ -147,6 +147,48 @@ paths:
|
||||
"403": { $ref: "#/components/responses/Fel" }
|
||||
"409": { $ref: "#/components/responses/Fel" }
|
||||
|
||||
/api/organisation:
|
||||
get:
|
||||
tags: [Organisation]
|
||||
summary: Hämta organisationens namn och inställningar
|
||||
description: >
|
||||
Inställningarna styr vad som visas när ett ärende startas
|
||||
(objekttyper och identifieringsmetoder). Alla inloggade läser.
|
||||
responses:
|
||||
"200":
|
||||
description: Organisationen.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
namn: { type: string }
|
||||
installningar: { $ref: "#/components/schemas/OrganisationsInstallningar" }
|
||||
"401": { $ref: "#/components/responses/Fel" }
|
||||
|
||||
/api/organisation/installningar:
|
||||
post:
|
||||
tags: [Organisation]
|
||||
summary: Uppdatera organisationens inställningar
|
||||
description: Kräver rollen `admin`. Minst ett alternativ per lista.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/OrganisationsInstallningar" }
|
||||
responses:
|
||||
"200":
|
||||
description: Sparat.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
ok: { type: boolean }
|
||||
"400": { $ref: "#/components/responses/Fel" }
|
||||
"401": { $ref: "#/components/responses/Fel" }
|
||||
"403": { $ref: "#/components/responses/Fel" }
|
||||
|
||||
/api/arenden:
|
||||
get:
|
||||
tags: [Ärenden]
|
||||
@@ -456,6 +498,18 @@ components:
|
||||
Roll:
|
||||
type: string
|
||||
enum: [tekniker, arbetsledare, admin]
|
||||
OrganisationsInstallningar:
|
||||
type: object
|
||||
required: [objekttyper, identifieringsmetoder]
|
||||
properties:
|
||||
objekttyper:
|
||||
type: array
|
||||
minItems: 1
|
||||
items: { type: string }
|
||||
identifieringsmetoder:
|
||||
type: array
|
||||
minItems: 1
|
||||
items: { type: string }
|
||||
DelningsNiva:
|
||||
type: string
|
||||
enum: [kund, partner, intern]
|
||||
|
||||
@@ -266,6 +266,34 @@ export function skapaServer() {
|
||||
}
|
||||
}
|
||||
|
||||
// Organisationens inställningar: vad som visas när ett ärende
|
||||
// startas (objekttyper, identifieringsmetoder). Alla inloggade
|
||||
// läser; endast systemadministratören ändrar.
|
||||
if (req.method === "GET" && vag === "/api/organisation") {
|
||||
const rader = await pool.query(
|
||||
`select namn, installningar from organisationer where id = $1`,
|
||||
[anspr.org],
|
||||
);
|
||||
if (rader.rowCount === 0) return svara(res, 404, { error: "Organisationen finns inte." });
|
||||
return svara(res, 200, rader.rows[0]);
|
||||
}
|
||||
|
||||
if (req.method === "POST" && vag === "/api/organisation/installningar") {
|
||||
if (anspr.roll !== "admin") return svara(res, 403, { error: "Kräver administratörsbehörighet." });
|
||||
const { objekttyper, identifieringsmetoder } = await lasKropp(req);
|
||||
const giltigLista = (lista) =>
|
||||
Array.isArray(lista) && lista.length > 0 && lista.length <= 50 &&
|
||||
lista.every((v) => typeof v === "string" && v.length <= 100);
|
||||
if (!giltigLista(objekttyper) || !giltigLista(identifieringsmetoder)) {
|
||||
return svara(res, 400, { error: "Ange minst en objekttyp och en identifieringsmetod." });
|
||||
}
|
||||
await pool.query(
|
||||
`update organisationer set installningar = $2 where id = $1`,
|
||||
[anspr.org, JSON.stringify({ objekttyper, identifieringsmetoder })],
|
||||
);
|
||||
return svara(res, 200, { ok: true });
|
||||
}
|
||||
|
||||
// Organisationsöversikt för arbetsledare/admin: alla ärenden med
|
||||
// status, deltagande tekniker och sammanfattning — härlett ur
|
||||
// händelseloggen, aldrig lagrat separat.
|
||||
|
||||
Reference in New Issue
Block a user