1 Commits
Author SHA1 Message Date
blandClaude Opus 5.5 88c2f75cfc Ny side, bygget av treneren: tilstand, prosjekt og søknad, fra henvendelse til levert
Fra plans/klingenbergbygg.yaml i uhhm/portal. Færre felt, én pult
(kontor), og kunden får innlogging når tilbudet er godtatt: egne
oppdrag og leverte dokumenter. Ordene er det gamle skjemaets der de
fantes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
2026-09-30 17:57:29 +02:00
14 changed files with 74 additions and 354 deletions

No files matched your search

+23 -13
View File
@@ -1,25 +1,35 @@
name: Deploy test instance
name: Deploy instance
# Branch `test` is portal.test.klingenbergbygg.no: the newest portal
# release (cut from uhhm/portal main), with a NATS of its own on kasse,
# so nothing tried here reaches production or mails a customer. The
# production site is branch `main`, pinned in its own deploy.yml.
# This content repo owns its portal instance: which portal version runs
# on kasse. uhhm/portal only publishes versioned release artifacts;
# PORTAL_RELEASE below pins the one this site runs, so every rollout is
# a commit - auditable, and revertable by reverting it.
#
# Content-only changes never come through here: lint-and-reload
# hot-swaps those into the running instance over NATS.
#
# Runs on the host runner, because a deploy has to touch this host's
# filesystem and its units. It is allowed exactly one root action:
# /usr/local/bin/deploy-portal-instance, which checks the instance
# against a fixed list and the tag against a release-tag shape before
# it touches anything, and health-checks the site afterwards without a
# forwarded header - a check that sends the header Caddy would send
# cannot tell you the site is broken for everything that is not Caddy.
# Every push: a test site that follows the newest release has no pin
# to change, so a push is the moment to pick the newest up.
on:
workflow_dispatch:
push:
branches: [test]
branches: [main]
paths:
- .gitea/workflows/deploy.yml
env:
INSTANCE: klingenberg-test
PORTAL_RELEASE: v0.6.2
INSTANCE: klingenberg-portal
jobs:
deploy:
runs-on: fish
steps:
- name: Ship the newest release and restart
run: |
tag=$(curl -sf https://project.uhhm.no/api/v1/repos/uhhm/portal/releases/latest | jq -r .tag_name)
sudo /usr/local/bin/deploy-portal-instance "$INSTANCE" "$tag"
- name: Ship the pinned release and restart
run: sudo /usr/local/bin/deploy-portal-instance "$INSTANCE" "$PORTAL_RELEASE"
+8 -8
View File
@@ -1,21 +1,21 @@
name: lint-and-reload
on:
push:
branches: [test]
branches: [main]
jobs:
lint:
runs-on: fish
steps:
- name: checkout
run: |
rm -rf checkout && git clone --depth 1 --branch test https://prosjekt.klingenbergbygg.no/klingenbergbygg/questions.git checkout
# The lint is portal itself, at the newest release: the one the
# test instance runs.
rm -rf checkout && git clone --depth 1 https://prosjekt.klingenbergbygg.no/klingenbergbygg/questions.git checkout
# The lint is portal itself (`portal lint`), at the version this
# site runs (PORTAL_RELEASE in deploy.yml).
- name: lint
env:
PORTAL_RELEASE: v0.6.2
run: |
tag=$(curl -sf https://project.uhhm.no/api/v1/repos/uhhm/portal/releases/latest | jq -r .tag_name)
curl -sfL "https://project.uhhm.no/uhhm/portal/releases/download/$tag/portal-x86_64-linux" -o portal && chmod +x portal
curl -sfL "https://project.uhhm.no/uhhm/portal/releases/download/$PORTAL_RELEASE/portal-x86_64-linux" -o portal && chmod +x portal
./portal lint --path checkout/questions
# The test instance's own NATS, never production's.
- name: reload
run: nats --server nats://127.0.0.1:4232 pub portal.content.reload ""
run: nats --server nats://127.0.0.1:4222 pub portal.content.reload ""
-24
View File
@@ -1,28 +1,4 @@
aggregates:
- bucket: ansatte
initial: open
states:
open:
event: received
sluttet:
event: sluttet
leaves_after:
minutes: 10
transitions:
open:
- sluttet
- bucket: erfaringer
initial: open
states:
open:
event: received
fjernet:
event: fjernet
leaves_after:
minutes: 10
transitions:
open:
- fjernet
- bucket: leveranser
initial: open
states:
+3 -10
View File
@@ -106,22 +106,15 @@ h1, h2, h3 {
opacity: 1;
}
/* Who is here sits on the wordmark's line, at the page's right edge. */
/* Who is here sits on the bar's line, at the page's right edge. */
.session {
top: 1.75rem;
right: max(1.5rem, calc((100vw - var(--measure)) / 2 + 1.5rem));
font-family: var(--heading);
font-weight: 500;
font-size: 0.85rem;
}
.hero-top {
justify-content: space-between;
}
.hero-top .session {
position: static;
transform: none;
}
.slideshow {
--swiper-navigation-size: 1.6rem;
background: var(--line);
-53
View File
@@ -89,7 +89,6 @@ needs:
i_arbeid: søknad under arbeid
levert: søknad levert
avslatt: avsluttet uten oppdrag
paused: true
- id: leveranse
who: kontoret, når en rapport, tegninger eller et vedtak er klart til kunden
wants: at kunden får dokumentet og vet at det ligger der
@@ -110,46 +109,6 @@ needs:
open: levert
arkivert: arkivert
enters_as: kontor
- id: ansatt
who: en av oss på kontoret, som vil vise hvem hen er og hva hen kan
wants: at den som vurderer oss ser hvem som gjør jobben
enters: /kontor/ansatt
via: Kortet ditt
lands_in: ansatte
handled_by: kontor
stages:
- open
- sluttet
done_when:
- sluttet
success:
- sluttet
max_steps: 1
max_fields: 4
stage_words:
open: vises på forsiden
sluttet: sluttet
enters_as: kontor
- id: erfaring
who: en av oss på kontoret, når et oppdrag er verdt å vise fram
wants: at den som vurderer oss ser hva vi har gjort
enters: /kontor/erfaring
via: Et oppdrag med bilde
lands_in: erfaringer
handled_by: kontor
stages:
- open
- fjernet
done_when:
- fjernet
success:
- fjernet
max_steps: 1
max_fields: 3
stage_words:
open: vises
fjernet: fjernet
enters_as: kontor
personas:
- id: kommune-skole
need: tilstand
@@ -172,16 +131,4 @@ personas:
- id: ansvarsrett
need: soknad
text: Vi har prosjektert ombyggingen selv, men mangler noen med ansvarsrett som kan stå for søknaden.
- id: rapport-klar
need: leveranse
text: Tilstandsrapporten til borettslaget er ferdig. Jeg vil at styreleder skal få den og vite at den ligger der.
- id: ny-hos-oss
need: ansatt
text: Jeg har nettopp begynt hos Klingenberg Bygg og vil at kundene skal se hvem jeg er og hva jeg kan.
- id: nytt-portrett
need: ansatt
text: Portrettet mitt på forsiden er fra da jeg begynte. Jeg vil bytte det uten å skrive alt det andre på nytt.
- id: brannstasjonen
need: erfaring
text: Brannstasjonen i Ytre Enebakk står ferdig, og vi har gode bilder fra fundamenteringen. Den vil jeg vise fram.
tones: []
-47
View File
@@ -1,47 +0,0 @@
name: Hvem består Klingenberg Bygg av?
description: Menneskene som gjør jobben, oppdragene vi har gjort, og det vi står for.
responsible:
name: Fredrik Borch Lynghaug
contact: fredrik@klingenbergbygg.no
alternatives:
- name: Menneskene
description: De som går befaringene, skriver rapportene og står for søknadene.
features:
- name: ''
description: ''
resource:
source:
kind: kv
bucket: ansatte
public: true
states:
- open
empty: Snart presenterer vi oss her.
jq: 'sort_by(.submitted_ms) | reverse | .[] | .responses |= {name: .name, rolle: .rolle, erfaring: .erfaring, portrett: .portrett}'
- name: Erfaringer
description: Et utvalg oppdrag, med bilder.
features:
- name: ''
description: ''
resource:
source:
kind: kv
bucket: erfaringer
public: true
states:
- open
empty: Snart viser vi fram oppdrag her.
jq: 'sort_by(.submitted_ms) | reverse | .[] | .responses |= {tittel: .tittel, bilde: .bilde, om: .om}'
- name: Verdier
description: Det vi står for.
features:
- name: Mål to ganger
description: Vi måler to ganger og skriver én gang. Det gjelder betong, og det gjelder rapporter.
icon: lucide:ruler
- name: Bygget først
description: Et bygg bryr seg ikke om hvem som har rett. Vi skriver det bygget trenger, ikke det som er lettest å si.
- name: Ingen overraskelser i veggen
description: Det vi finner, får du vite. Også sprekkene.
icon: lucide:search
- name: Vannet finner en vei
description: Vannet finner alltid en vei. Derfor leter vi etter den først.
+40 -20
View File
@@ -11,11 +11,6 @@ alternatives:
description: Vi utarbeider tilstandsrapporter etter NS-EN 3424 og NS 3423, med befaring, materialprøver og termofotografering. Skal bygget rives, leverer vi miljøsaneringsrapport; energibruk og besparelser hører med i vurderingen. Vi har samarbeidet med [Drammen Kommune](https://drammen.kommune.no), [Nordre Follo Kommune](https://nordrefollo.kommune.no) og [Bølerskogens Borettslag](https://bolerskogenborettslag.no/).
- name: Prosjekt og søknad, med ansvarsrett
description: 'Vi lager arbeidsbeskrivelse opp mot [NS 3420](https://standard.no/fagomrader/ns-3420-/) og fremdriftsplan, og utarbeider byggesøknaden. Vi har sentral [godkjenning](https://sgregister.dibk.no/enterprises/976015711) innen flere fagområder og kan stå med det offentligrettslige ansvaret. Samarbeidspartner: [Westra Engineering AS](https://www.westra-engineering.no/).'
- name: Hvem består Klingenberg Bygg av?
description: Mennesker, erfaringer og verdier.
action: /hvem
consequence:
- Bli kjent med oss
- name: Få kartlagt byggets tilstand
description: Vi utarbeider tilstandsrapporter som representerer bygget med hensyn til fremtidige mål.
action: /received/tilstand
@@ -35,12 +30,10 @@ alternatives:
label: Navn
type: text
placeholder: Navn
value: '{user.name}'
- name: email
label: E-post
type: email
placeholder: bruker@eksempel.no
value: '{user.email}'
- name: telefon
label: Telefon
type: tel
@@ -93,12 +86,10 @@ alternatives:
label: Navn
type: text
placeholder: Navn
value: '{user.name}'
- name: email
label: E-post
type: email
placeholder: bruker@eksempel.no
value: '{user.email}'
- name: telefon
label: Telefon
type: tel
@@ -125,11 +116,11 @@ alternatives:
encouragements:
- Gi det beste grunnlaget for utførelse.
- name: Ta det første spadetaket med en godkjent søknad
description: Er bygget ferdig prosjektert, kan vi utarbeide en byggesøknad og utførelsesbeskrivelse for offentlig godkjenning. Akkurat nå har vi ikke kapasitet til nye søknadsoppdrag; vi åpner igjen så snart vi kan.
description: Er bygget ferdig prosjektert, kan vi utarbeide en byggesøknad og utførelsesbeskrivelse for offentlig godkjenning.
action: /received/soknad
consequence:
- Send henvendelse
disabled: true
record_as: soknader
features:
- name: Slik går det videre
description: Vi går gjennom det du har, avtaler befaring eller forhåndskonferanse, og sender deg et tilbud. Du sier selv ja eller nei, og med et ja får du en innlogging der du følger søknaden og henter dokumentene.
@@ -137,6 +128,35 @@ alternatives:
- name: Hvem leser dette
description: Fredrik på kontoret leser henvendelsen og tar kontakt. Du når ham også på fredrik@klingenbergbygg.no.
icon: lucide:users
- name: Om tiltaket
requirements:
- name: name
label: Navn
type: text
placeholder: Navn
- name: email
label: E-post
type: email
placeholder: bruker@eksempel.no
- name: telefon
label: Telefon
type: tel
optional: true
placeholder: Telefonnummer
- name: adresse
label: Hvor ligger eiendommen?
type: text
placeholder: Adresse
- name: tiltak
label: Hva går tiltaket ut på?
type: textarea
placeholder: Tilbygg, ombygging, nybygg…
- name: tegninger
label: Tegninger og prosjektering
type: file
optional: true
description: Hva skal bygges, og hvor. Avhengig av størrelsen kan vi holde forhåndskonferanse med kommunen først.
icon: lucide:file-text
encouragements:
- Nesten som å ha gravemaskin!
slideshow:
@@ -185,19 +205,19 @@ slideshow:
- image: images/bildeserie/11.webp
width: 1050
height: 1400
caption: Solid veggprofil tilpasset lyd- og brannkrav
caption: Solid veggprofil tilpasset lyd og brann-krav
- image: images/bildeserie/12.webp
width: 1867
height: 1400
caption: Nye vinduer med tradisjonelt utseende «Restover»-glass som avslører utsikten fra Munkeramme på Hvitsten
caption: Nye vinduer med tradisjonelt-utseende «Restover» glass som avslører utsikten fra Munkeramme på Hvitsten
- image: images/bildeserie/13.webp
width: 2571
height: 1400
caption: Kjerneved til verandaen og inngangspartiet til Muncheramme
caption: Kjærneved til varanda og inngangspartiet til Muncheramme
- image: images/bildeserie/14.webp
width: 1050
height: 1400
caption: Drenering og riktige rammer før kunstgressbanen legges mesterfullt ned helt uten gummikuler
caption: Drenering og riktige rammer før kunsgressbanen legges mesterfullt ned helt uten gummikuler
- image: images/bildeserie/15.webp
width: 2098
height: 1400
@@ -209,11 +229,11 @@ slideshow:
- image: images/bildeserie/17.webp
width: 1050
height: 1400
caption: Etablering av ny byggekran
caption: Etanblering av ny byggekran
- image: images/bildeserie/18.webp
width: 1050
height: 1400
caption: Armeringskontroll før støping
caption: Armerignskontroll før støping
- image: images/bildeserie/19.webp
width: 1867
height: 1400
@@ -221,7 +241,7 @@ slideshow:
- image: images/bildeserie/20.webp
width: 1867
height: 1400
caption: Her heises Moelvens modulskole i Vestby på plass. Den blir stående i minst 10 år.
caption: Her heises Moelvens modulskole i vestby på plass. Den blir stående i 10 år.
- image: images/bildeserie/21.webp
width: 1867
height: 1400
@@ -233,7 +253,7 @@ slideshow:
- image: images/bildeserie/23.webp
width: 2095
height: 1400
caption: Nytt kunstgress med varme på Fredrikstad stasjon.
caption: Nytt kunstgress med varme på Fredikstad stasion.
- image: images/bildeserie/24.webp
width: 1050
height: 1400
@@ -241,4 +261,4 @@ slideshow:
- image: images/bildeserie/25.webp
width: 1487
height: 1400
caption: pH-test av borprøver i betong fra forskjellige dybder
caption: pH-test av borreprøver i mur fra forskjellige dybder
-10
View File
@@ -1,10 +0,0 @@
name: Kortet ditt er lagret
description: Slik står du nå på forsiden.
alternatives:
- name: Vil du endre noe?
description: 'Åpne «Hvordan presenterer du deg?» igjen: kortet ditt er fylt ut med det du har, og det du lagrer erstatter det.'
- name: Se alle ansatte
description: ''
action: /status/ansatte
consequence:
- Åpne
-40
View File
@@ -1,40 +0,0 @@
followup: false
name: Hvordan presenterer du deg?
description: Det du skriver her, står på kortet ditt blant menneskene på forsiden.
responsible:
name: Fredrik Borch Lynghaug
contact: fredrik@klingenbergbygg.no
alternatives:
- name: Kortet ditt
description: Rett det du vil og lagre. Du har ett kort, og det du lagrer erstatter det som står der nå.
action: /kontor/ansatt-sent
consequence:
- Lagre kortet
record_as: ansatte
features:
- name: Når du lagrer
description: Kortet ditt på forsiden endres med en gang.
icon: lucide:route
- name: Hvem ser det
description: Alle som besøker siden. Navnet ditt er det du er logget inn med.
icon: lucide:users
- name: Kortet ditt
requirements:
- name: name
label: Navn
type: text
value: '{user.name}'
- name: rolle
label: Rolle
type: text
placeholder: For eksempel daglig leder, rådgivende ingeniør
- name: erfaring
label: Erfaring
type: textarea
placeholder: Utdanning, fagområder, bygg du er stolt av. Du kan skrive **fet**, *kursiv*, lister med - og [lenker](https://…).
- name: portrett
label: Portrett
type: file
accept: image/jpeg,image/png,image/webp
placeholder: Et stående bilde, gjerne tatt i dagslys. Velger du ikke noe nytt, beholder du det du har.
one_per_person: true
-10
View File
@@ -1,10 +0,0 @@
name: Oppdraget vises nå
description: Det står blant erfaringene på «Hvem består Klingenberg Bygg av?».
alternatives:
- name: Skal det ned igjen?
description: Trykk «Fjern» på raden i listen over erfaringer her på kontoret. Det forsvinner fra listen ti minutter etter.
- name: Se alle erfaringer
description: ''
action: /status/erfaringer
consequence:
- Åpne
-35
View File
@@ -1,35 +0,0 @@
followup: false
name: Hvilket oppdrag vil du vise fram?
description: Det du legger inn her, står blant erfaringene på «Hvem består Klingenberg Bygg av?».
responsible:
name: Fredrik Borch Lynghaug
contact: fredrik@klingenbergbygg.no
alternatives:
- name: Et oppdrag med bilde
description: Et bilde og noen løse ord om hva vi gjorde. Det vises med en gang.
action: /kontor/erfaring-sent
consequence:
- Vis fram
record_as: erfaringer
features:
- name: Når du sender
description: Oppdraget vises blant erfaringene med en gang, til noen på kontoret fjerner det.
icon: lucide:route
- name: Hvem ser det
description: Alle som besøker siden. Skriv ikke noe om kunden de ikke ville lest selv.
icon: lucide:users
- name: Oppdraget
requirements:
- name: tittel
label: Hva var det?
type: text
placeholder: 'For eksempel: Brannstasjonen i Ytre Enebakk'
- name: bilde
label: Bilde
type: file
accept: image/jpeg,image/png,image/webp
placeholder: Et bilde fra oppdraget, gjerne liggende
- name: om
label: Noen ord om det
type: textarea
placeholder: Hva vi gjorde, og hva som var verdt å gjøre skikkelig. **Fet**, *kursiv*, lister og lenker går an.
-44
View File
@@ -4,40 +4,6 @@ responsible:
name: Fredrik Borch Lynghaug
contact: fredrik@klingenbergbygg.no
alternatives:
- name: Ansatte på forsiden
description: Menneskene slik besøkende ser dem. Hver retter sitt eget kort; herfra kan et kort tas ned.
action: /kontor
consequence:
- Bekreft
features:
- name: Ansatte
description: Hver rad er én person på forsiden.
resource:
source:
kind: kv
bucket: ansatte
requires_group: kontor
transitions:
- from: open
to: sluttet
label: Tatt av forsiden
- name: Erfaringer
description: Oppdragene slik besøkende ser dem.
action: /kontor
consequence:
- Bekreft
features:
- name: Erfaringer
description: Hver rad er ett oppdrag som vises nå.
resource:
source:
kind: kv
bucket: erfaringer
requires_group: kontor
transitions:
- from: open
to: fjernet
label: Fjern
- name: Leverte dokumenter
description: Rapporter, tegninger og vedtak som er sendt til kunder.
action: /kontor
@@ -165,16 +131,6 @@ alternatives:
action: /kontor/leveranse
consequence:
- Ny leveranse
- name: Hvordan presenterer du deg?
description: 'Kortet ditt på forsiden: rolle, erfaring og portrett.'
action: /kontor/ansatt
consequence:
- Åpne
- name: Hvilket oppdrag vil du vise fram?
description: Et bilde og noen løse ord, blant erfaringene.
action: /kontor/erfaring
consequence:
- Åpne
- name: Gi en kollega tilgang
description: De får en konto og plass på kontoret, og ser de samme sakene som deg.
action: /kontor
-20
View File
@@ -1,20 +0,0 @@
name: Hvem består Klingenberg Bygg av?
description: Menneskene som går befaringene, skriver rapportene og står for søknadene.
responsible:
name: Fredrik Borch Lynghaug
contact: fredrik@klingenbergbygg.no
alternatives:
- name: Menneskene
description: ''
features:
- name: Menneskene
description: Hver rad er én sak og hvor langt den har kommet. Navn og kontaktopplysninger vises ikke her.
resource:
source:
kind: kv
bucket: ansatte
public: true
states:
- open
empty: Snart presenterer vi oss her.
jq: 'sort_by(.submitted_ms) | reverse | .[] | .responses |= {name: .name, rolle: .rolle, erfaring: .erfaring, portrett: .portrett}'
-20
View File
@@ -1,20 +0,0 @@
name: Hva har Klingenberg Bygg gjort?
description: Et utvalg oppdrag, med bilder.
responsible:
name: Fredrik Borch Lynghaug
contact: fredrik@klingenbergbygg.no
alternatives:
- name: Erfaringer
description: ''
features:
- name: Erfaringer
description: Hver rad er én sak og hvor langt den har kommet. Navn og kontaktopplysninger vises ikke her.
resource:
source:
kind: kv
bucket: erfaringer
public: true
states:
- open
empty: Snart viser vi fram oppdrag her.
jq: 'sort_by(.submitted_ms) | reverse | .[] | .responses |= {tittel: .tittel, bilde: .bilde, om: .om}'