diff --git a/docs/ap/hr/transformasjoner/_category_.json b/docs/ap/hr/transformasjoner/_category_.json
new file mode 100644
index 000000000..de7320695
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Transformasjoner",
+ "position": 1
+}
diff --git a/docs/ap/hr/transformasjoner/sap_10_ansettelsesdato.md b/docs/ap/hr/transformasjoner/sap_10_ansettelsesdato.md
new file mode 100644
index 000000000..04993d4d8
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_ansettelsesdato.md
@@ -0,0 +1,42 @@
+# sap_10_ansettelsesdato
+
+## Formål
+Henter ansettelsesdato fra PA0041 ved å søke gjennom 24 datotype/dato-kolonnepar. Prioriterer datotype '01' for HVL, deretter 'VB' for alle institusjoner.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0041** | Datoer knyttet til ansatte | Ingen | Hovedtabell med 24 datotype/dato-kolonnepar |
+| **PA0001** | Hovedstillingsdata | medarbeidergruppe_kode != '8' (i final select) | Sekundærtabell for datointervaller, brukes til å filtrere bort perioder med MG=8 |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **dato_ansettelse** | COALESCE over 24 kolonnepar: først dato_type='01' (kun HVL), deretter dato_type='VB' |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA0041 definerer gyldige datointervaller per ansatt
+- **Sekundærtabell:** PA0001 bidrar med datogrenser fra stillingsdata
+- **Nøkkelkolonner:** ansatt_nummer
+
+### 2. Tabellkoblinger
+Etter datointervallgenerering kobles følgende tabeller:
+- **PA0041** (alias `t`): Left join med datooverlapp
+- **PA0001** (alias `hovedstillinger`): Left join med datooverlapp
+
+### 3. Filtrering
+- Ekskluderer rader der medarbeidergruppe_kode = '8' (ekstern tilsettingstype)
+- Beholder rader uten match i PA0001 (null)
+
+### 4. Ansettelsesdato-logikk
+Bruker COALESCE over betingede uttrykk for å finne første gyldige ansettelsesdato:
+
+**HVL:**
+1. Sjekker dato_type_1 til dato_type_24 for verdi '01' – returnerer tilhørende dato
+2. Sjekker dato_type_1 til dato_type_24 for verdi 'VB' – returnerer tilhørende dato
+
+**Andre institusjoner:**
+1. Sjekker dato_type_1 til dato_type_24 for verdi 'VB' – returnerer tilhørende dato
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_fodselsdager.md b/docs/ap/hr/transformasjoner/sap_10_fodselsdager.md
new file mode 100644
index 000000000..37f5c8d48
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_fodselsdager.md
@@ -0,0 +1,31 @@
+# sap_10_fodselsdager
+
+## Formål
+Genererer en liste over alle fødselsdager for hver ansatt fra 1990 til neste år. Brukes til å skape datobrudd i `sap_20_stillinger*` slik at alder beregnes korrekt i alle datointervaller.
+
+## Datakilde
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0002** | Persondata | `DISTINCT` på `ansatt_nummer` og `dato_fodt` | Grunnlagstabell med fødselsdatoer |
+
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **dato_fodselsdag** | `add_months(dato_fodt, (aar - year(dato_fodt)) * 12)` — Beregner fødselsdagen for hvert år i perioden 1990 til neste år |
+
+## Transformasjonslogikk (PySpark)
+### 1. Load source data
+Laster `pa0002` fra `silver_sap`.
+
+### 2. Create unique list of birth dates
+Henter `DISTINCT` kombinasjoner av `ansatt_nummer` og `dato_fodt` fra PA0002.
+
+### 3. Create year dimension
+år fra 1990 til neste år.
+
+### 4. Transform data
+Cross join unike fødselsdatoer med årsdimensjon og beregner fødselsdagen for hvert år.
+
+### 5. Write to target
+Skriver resultatet til `transformation_hr.sap_10_fodselsdager` med `overwrite` og `overwriteSchema`.
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_fravaerstyper.md b/docs/ap/hr/transformasjoner/sap_10_fravaerstyper.md
new file mode 100644
index 000000000..d0661f586
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_fravaerstyper.md
@@ -0,0 +1,34 @@
+# sap_10_fravaerstyper
+
+## Formål
+Bygger en komplett oversikt over fraværstyper med tilhørende tekster, SAP-kategorier og BOTs egendefinerte kategorier/indikatorer. Brukes som oppslagstabell i fraværsanalyser.
+
+## Datakilde
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **T554S** | Fraværstyper med historikk | Siste versjon per `fravaerstype_kode` basert på `dato_til DESC` | Grunnlagstabell |
+| **T554T** | Tekster for fraværstyper | — | Tilfører `fravaerstype_navn` |
+| **T5A4O** | SAP fraværskategorier | — | Tilfører `fravaerskategori_kode` og `fravaerskategori_navn` |
+| **fravaerskategorier** | BOT egendefinerte kategorier | — | Tilfører hovedkategorier, underkategorier og indikatorer |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| Alle kategori- og indikatorkolonner | `coalesce(kilde, 'Ukjent')` — Defaulter til `Ukjent` dersom verdi mangler |
+| **fravaerskategori_kode** | `coalesce(kilde, '-1')` — Defaulter til `-1` dersom verdi mangler |
+
+## Transformasjonslogikk (PySpark)
+### 1. Load source data
+Laster `t554s`, `t554t`, `t5a4o` og `fravaerskategorier` fra `silver_sap`.
+
+### 2. Get latest version of T554S
+Bruker `row_number()` partisjonert på `fravaerstype_kode`, sortert på `dato_til DESC`, og filtrerer på `rn = 1`.
+
+### 3. Join with texts from T554T
+Left join med `t554t` på `fravaerstype_kode` og `zx_institusjonskode` for å hente `fravaerstype_navn`.
+
+### 4. Create final result with categories
+Left join med `t5a4o` på `fravaerskategori_kode` for SAP-kategorier, og left join med `fravaerskategorier` på `fravaerstype_kode` for BOTs egendefinerte kategorier og indikatorer.
+
+### 5. Write to target
+Skriver resultatet til `transformation_hr.sap_10_fravaerstyper` med `overwrite` og `overwriteSchema`.
diff --git a/docs/ap/hr/transformasjoner/sap_10_grunnlonn_pa0001.md b/docs/ap/hr/transformasjoner/sap_10_grunnlonn_pa0001.md
new file mode 100644
index 000000000..575348126
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_grunnlonn_pa0001.md
@@ -0,0 +1,118 @@
+# sap_10_grunnlonn_pa0001
+
+## Formål
+Beregner grunnlønn knyttet til stillinger i PA0001 basert på logikk for hovedtariffperiodene. Håndterer tre perioder:
+- 01.05.2020–30.04.2022
+- 01.05.2022–30.04.2024
+- 01.05.2024 og fremover (gjeldende)
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0008** | Direkte registrert lønn | Ingen | Hovedtabell som definerer lønn med tarifftype, tariffområde, tariffgruppe, lønnstrinn og beløp |
+| **T510** | Satser for bl.a. lønnstrinn | Pensjonistavtaler OR (lonnart_kode='1000', tariffavtale_kode='3') | Tilfører standardiserte lønnssatser basert på tariffkombinasjon |
+| **T512T** | Tekster knyttet til lønnarter | Ingen | Legger til tekst for hver lønnartkode i PA0008 |
+| **YHR_PSRCL** | Stigejusteringsprosent | lonnart_kode='108A' | Legger til stigeprosent for ansiennitetsberegning |
+| **T530F** | Tekst knyttet til lønnsendringsårsak | infotype_kode='0008' | Legger til tekstbeskrivelse for lønnsendring |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **belop_grunnlonn** | Beregning basert på logikk knyttet til hver hovedtariffperiode |
+| **endring_aarsak_lonn_kode** | Hentes fra endring_aarsak_kode i PA0008 |
+| **endring_aarsak_lonn_tekst** | Hentes fra endring_aarsak_tekst i T530F |
+| **lonnart** | Kombinasjon av alle 40 lønnartkoder i PA0008 med navn fra T512T, separert med komma |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA0008 definerer gyldige datointervaller per ansatt
+- **Sekundærtabell:** T510 (med forretningsnøkler fra PA0008) bidrar med datogrenser fra lønnssatser
+- **Nøkkelkolonner:** ansatt_nummer
+
+### 2. Forretningsnøkler til sekundærtabeller
+T510 mangler ansatt_nummer og må berikes før datointervallgenerering:
+- Joines mot PA0008 på tarifftype, tariffområde, tariffgruppe, lønnstrinn og datooverlapp
+- Returnerer ansatt_nummer + dato_fra/dato_til for bruk i combine_date_intervals
+
+### 3. Tabellkoblinger
+Etter datointervallgenerering kobles følgende tabeller:
+- **PA0008**: Hovedtabell med datooverlapp
+- **T510**: Lønnssatser med tariffnøkkel og datooverlapp
+- **YHR_PSRCL**: Stigeprosent med tariffnøkkel og lonnart_kode='108A'
+- **T530F**: Endringsårsaktekst med infotype_kode='0008'
+- **T512T**: 40 koblinger for lønnarttekster
+
+### 4. Grunnlønnsberegning per hovedtariffperiode
+Beregningen av belop_grunnlonn avhenger av hvilken hovedtariffperiode intervallet faller i.
+
+**Hjelpeuttrykk:**
+- `belop_sum`: Sum av belop_1 til belop_40 fra PA0008
+- `has_lonnstrinn` / `no_lonnstrinn`: Sjekker om lønnstrinn er registrert
+- `stige_multiplier`: Beregner (1 + stige.prosent/100) for ansiennitetslogikk
+
+#### Hovedtariffperiode 01.05.2020–30.04.2022
+| Tarifftype | Område | Gruppe | Formel |
+|------------|--------|--------|--------|
+| 71 | Alle | Alle | COALESCE(satser.belop, 0) + COALESCE(belop_sum, 0) |
+| 72 | Alle | Med lønnstrinn | satser.belop |
+| 72 | Alle | Uten lønnstrinn | belop_sum |
+| 73 | 91 | Alle | belop_sum |
+| 73 | 95 | Alle | belop_sum * stige_multiplier |
+| 74 | 90 | PERS | satser.belop |
+| 75 | 90 | INDIVID | belop_sum * 12 |
+| 75 | 90 | UARB | satser.belop |
+| 75 | 90 | PENSJAVT | satser.belop * 1950 |
+| 76 | AA | %HLÆ% | satser.belop |
+| 76 | AA | IND% | belop_sum * 12 |
+
+#### Hovedtariffperiode 01.05.2022–30.04.2024
+| Tarifftype | Område | Gruppe | Formel |
+|------------|--------|--------|--------|
+| 71 | 91, 95 | Alle | COALESCE(satser.belop, 0) + COALESCE(belop_sum, 0) |
+| 72 | Alle | Med lønnstrinn | satser.belop |
+| 72 | Alle | Uten lønnstrinn | belop_sum |
+| 73 | 91 | Alle | belop_sum |
+| 73 | 95 | Alle | belop_sum * stige_multiplier |
+| 74 | 90 | PERS | satser.belop |
+| 75 | 90 | INDIVID | belop_sum * 12 |
+| 75 | 90 | UARB | satser.belop |
+| 75 | 90 | PENSJAVT | satser.belop * 1950 |
+| 76 | AA | %HLÆ% | satser.belop |
+| 76 | AA | IND% | belop_sum * 12 |
+
+(samme som forrige med unntak av tarifftype 71 som er begrenset til område 91 og 95)
+
+#### Hovedtariffperiode 01.05.2024 og fremover (gjeldende)
+Samme logikk som 2022–2024.
+
+### 5. T510 filtrering (lønnssatser)
+
+**Pensjonistavtaler:**
+- lonnart_kode = ''
+- tariffavtale_kode = '1'
+- tarifftype_kode = '75'
+- tariffomraade_kode = '90'
+- tariffgruppe_kode = 'PENSJAVT'
+
+**Alle andre:**
+- lonnart_kode = '1000'
+- tariffavtale_kode = '3'
+- Ikke pensjonistavtaler
+
+**Merk:** Dersom DFØ rydder i pensjonistoppsettet, kan logikken forenkles til kun tariffavtale='3' og lonnart='1000'.
+
+### 6. Lønnarttekster (T512T)
+- 40 separate koblinger (l1-l40) for hver lonnart_kode_1 til lonnart_kode_40
+- Kombineres til én kolonne med concat_ws og array_compact for å fjerne tomme verdier
+
+## Tarifftype-forklaring
+| Tarifftype | Betydning |
+|------------|-----------|
+| 71 | Statlig tariffavtale |
+| 72 | Tariffavtale med lønnstrinn |
+| 73 | Tariffavtale med ansiennitet/stigeprosent |
+| 74 | Personlig avtale |
+| 75 | Spesielle avtaler (individuelle, uten arbeid, pensjonister) |
+| 76 | Andre avtaler (høgskolelærere, individuelle) |
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_kommunikasjonsinformasjon.md b/docs/ap/hr/transformasjoner/sap_10_kommunikasjonsinformasjon.md
new file mode 100644
index 000000000..d3f135141
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_kommunikasjonsinformasjon.md
@@ -0,0 +1,72 @@
+# sap_10_kommunikasjonsinformasjon
+
+## Formål
+Henter kommunikasjonsinformasjon for ansatte fra PA0105 og PA9052. Inneholder brukernavn, e-postadresser og telefonnumre (jobb og privat). Kun siste gjeldende versjon per ansatt; ingen historikk.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0105** | Kommunikasjonsinformasjon | Siste rad per `kommunikasjonstype_kode` (`ROW_NUMBER` på `dato_til DESC`) | Grunnlagstabell for brukernavn, e-post og telefon |
+| **PA9052** | Mobilnummer | Siste rad per `deltype_kode` (`ROW_NUMBER` på `dato_til DESC`) | Overstyrer mobilnummer registrert i PA0105 |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **brukernavn_feide** | `LOWER(kommunikasjon_id_lang)` hvor `kommunikasjonstype_kode = '9020'` |
+| **brukernavn_dfo** | `kommunikasjon_id` hvor `kommunikasjonstype_kode = '0001'` |
+| **epost_jobb** | `LOWER(kommunikasjon_id_lang)` hvor `kommunikasjonstype_kode = '0010'` |
+| **epost_privat** | `LOWER(kommunikasjon_id_lang)` hvor `kommunikasjonstype_kode = '0030'` |
+| **telefon_fast_jobb** | `kommunikasjon_id_lang` hvor `kommunikasjonstype_kode = '0020'` |
+| **telefon_mobil_jobb** | `COALESCE(PA9052.telefon_mobil, PA0105.kommunikasjon_id)` for jobb (PA9052 `deltype_kode = '0001'`, PA0105 `kommunikasjonstype_kode = '9003'`) |
+| **telefon_mobil_privat** | `COALESCE(PA9052.telefon_mobil, PA0105.kommunikasjon_id)` for privat (PA9052 `deltype_kode = '0002'`, PA0105 `kommunikasjonstype_kode = '9004'`) |
+| **telefon_mobil (PA9052)** | `CONCAT(retning_tegn, retning_nummer, telefon_nummer)` |
+
+## Transformasjonslogikk
+
+### 1. PA0105 – Kommunikasjonsinformasjon
+- Henter all kommunikasjonsinformasjon fra PA0105
+- `ROW_NUMBER()` partisjonert på `ansatt_nummer` og `kommunikasjonstype_kode`
+- Sortert på `dato_til DESC` for å hente siste gjeldende rad
+- Kun rader med `rn = 1` beholdes
+
+**Kommunikasjonstyper fra PA0105**
+| kommunikasjonstype_kode | Betydning | Kolonne |
+|-------------------------|-----------|---------|
+| 9020 | Feide-brukernavn | brukernavn_feide |
+| 0001 | DFØ-brukernavn | brukernavn_dfo |
+| 0010 | E-post jobb | epost_jobb |
+| 0030 | E-post privat | epost_privat |
+| 0020 | Fasttelefon jobb | telefon_fast_jobb |
+| 9003 | Mobil jobb (fallback) | telefon_mobil_jobb |
+| 9004 | Mobil privat (fallback) | telefon_mobil_privat |
+
+### 2. PA9052 – Mobilnummer (overstyrt)
+- Henter mobilnummer fra PA9052
+- `ROW_NUMBER()` partisjonert på `ansatt_nummer` og `deltype_kode`
+- Sortert på `dato_til DESC`
+- Bygger komplett nummer: `CONCAT(retning_tegn, retning_nummer, telefon_nummer)`
+- Kun rader med `rn = 1` beholdes
+
+**Deltyper fra PA9052**
+| deltype_kode | Betydning | Kolonne |
+|--------------|-----------|---------|
+| 0001 | Mobil jobb | telefon_mobil_jobb |
+| 0002 | Mobil privat | telefon_mobil_privat |
+
+### 3. Prioritering av mobilnummer
+- PA9052 prioriteres over PA0105
+- `COALESCE(PA9052.telefon_mobil, PA0105.kommunikasjon_id)`
+ - Hvis PA9052 har verdi → bruk denne
+ - Ellers → bruk PA0105-fallback
+
+### 4. Pivot-struktur med LEFT JOIN
+- Starter med alle unike ansatte fra PA0105
+- LEFT JOIN mot PA0105 én gang per kommunikasjonstype (7 ganger)
+- LEFT JOIN mot PA9052 to ganger (jobb og privat mobil)
+- Filtrerer på `rn = 1` i alle join-operasjoner
+- `SELECT DISTINCT` sikrer én rad per ansatt
+
+### 5. Ingen datointervaller
+- Tabellen er punkt-i-tid (ingen `dato_fra` / `dato_til`)
+- Kun siste gjeldende kommunikasjonsinformasjon per ansatt
+- Direkte SELECT med flere LEFT JOIN
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_kontering_overstyrt_pa0509.md b/docs/ap/hr/transformasjoner/sap_10_kontering_overstyrt_pa0509.md
new file mode 100644
index 000000000..1b29382fd
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_kontering_overstyrt_pa0509.md
@@ -0,0 +1,41 @@
+# sap_10_kontering_overstyrt_pa0509
+
+## Formål
+Henter overstyrt kontering for tilleggsstillinger basert på ASSHR og ASSOB. Brukes når det er satt overstyrt kontering (infotype 0509) i SAP.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **ASSHR** | HR-tilordninger | `infotype_kode = '0509'` | Grunnlagstabell med datointervaller for overstyrt kontering |
+| **ASSOB** | Konteringsobjekter | Ingen | Beriker med koststed, delprosjekt og arbeidspakke/bygg |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **prosent_kontering** | `lit(1).cast("decimal(5,2)")` — settes til 1 (100%) siden ASSHR/ASSOB ikke har delt kontering |
+
+## Transformasjonslogikk (PySpark)
+
+### 1. Load source data
+Laster `asshr` fra `silver_sap` filtrert på `infotype_kode = '0509'` og `assob`.
+
+### 2. Join ASSHR med ASSOB
+Joiner ASSHR med ASSOB på:
+- `ansatt_nummer`
+- `pd_sekvens_nummer`
+
+Henter konteringsinformasjon:
+- `koststed_kode`
+- `delprosjekt_nummer`
+- `arbeidspakke_bygg_nummer`
+
+### 3. Select final columns
+Filtrerer ut rader hvor `pd_sekvens_nummer` er NULL og velger:
+- `ansatt_nummer`
+- `dato_fra`, `dato_til`
+- `koststed_kode`, `delprosjekt_nummer`, `arbeidspakke_bygg_nummer`
+- `prosent_kontering` (hardkodet til 1)
+- Metadata-kolonner (`zx_*`)
+
+### 4. Write to target
+Skriver resultatet til `transformation_hr.sap_10_kontering_overstyrt_pa0509` med `overwrite` og `overwriteSchema`.
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_kontering_pa0001_pa0509.md b/docs/ap/hr/transformasjoner/sap_10_kontering_pa0001_pa0509.md
new file mode 100644
index 000000000..d702424d5
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_kontering_pa0001_pa0509.md
@@ -0,0 +1,49 @@
+# sap_10_kontering_pa0001_pa0509
+
+## Formål
+Henter standard kontering for stillinger fra PA0027. Støtter delt kontering (flere konteringsobjekter med prosent). Brukes for PA0001/PA0509-stillinger med mindre stillingen har overstyrt kontering — da brukes `sap_10_kontering_overstyrt_pa0509`.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0027** | Kontering | `kostnadstype_fordeling_kode = '01'`, `prosent_kontering <> 0` | Grunnlagstabell med konteringsobjekter fordelt på 12 kolonner |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **koststed_kode** | Unpivot via `stack()` fra `koststed_kode_1`–`koststed_kode_12` |
+| **delprosjekt_nummer** | Unpivot via `stack()` fra `delprosjekt_nummer_1`–`delprosjekt_nummer_12` |
+| **arbeidspakke_bygg_nummer** | Unpivot via `stack()` fra `arbeidspakke_bygg_nummer_1`–`arbeidspakke_bygg_nummer_12` |
+| **prosent_kontering** | Unpivot via `stack()` fra `prosent_kontering_1`–`prosent_kontering_12` |
+
+## Transformasjonslogikk (PySpark)
+
+### 1. Load source data
+Laster `pa0027` fra `silver_sap`.
+
+### 2. Transform data - Stack/Unpivot
+PA0027 har 12 nummererte kolonnesett for kontering. Bruker `stack(12, ...)` for å unpivote alle fire kolonnetyper i én operasjon:
+- `koststed_kode_1`–`koststed_kode_12`
+- `delprosjekt_nummer_1`–`delprosjekt_nummer_12`
+- `arbeidspakke_bygg_nummer_1`–`arbeidspakke_bygg_nummer_12`
+- `prosent_kontering_1`–`prosent_kontering_12`
+
+Hver kilderad blir til opptil 12 rader (én per kolonne_nummer).
+
+### 3. Filtrering
+- **`kostnadstype_fordeling_kode = '01'`** — kun standard fordelingsnøkkel
+- **`prosent_kontering IS NOT NULL AND <> 0`** — fjerner tomme/null-allokeringer
+- **Minst ett konteringselement** — fjerner rader hvor alle konteringsfelter er NULL
+
+### 4. Select final columns
+Velger og caster kolonner til riktig datatype:
+- `koststed_kode`, `delprosjekt_nummer`, `arbeidspakke_bygg_nummer` → `string`
+- `prosent_kontering` → `decimal(5,2)`
+
+### 5. Write to target
+Skriver resultatet til `transformation_hr.sap_10_kontering_pa0001_pa0509` med `overwrite` og `overwriteSchema`.
+
+## Delt kontering
+Tabellen støtter delt kontering (flere rader per ansatt/dato):
+- Eksempel: 60% til koststed A, 40% til koststed B
+- Sumsjekk mot 100% utføres ikke i denne tabellen
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_kontering_pa9024.md b/docs/ap/hr/transformasjoner/sap_10_kontering_pa9024.md
new file mode 100644
index 000000000..270df491a
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_kontering_pa9024.md
@@ -0,0 +1,19 @@
+# sap_10_kontering_pa9024
+
+## Formål
+- Beregner konteringsprosent for stillinger fra PA9024.
+- Grupperer konteringsdata fra YHR_P9024_LINJER og beregner kostnadsfordelingsprosenten på hver linje basert på totalt kontraktsbeløp eller totale kontraktstimer.
+
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **YHR_P9024_LINJER** | Konteringsdata | Ingen | Grunnlagstabell med timer, beløp og konteringsdimensjoner (koststed, delprosjekt, arbeidspakke, arbeidsoppgave, lønnsart) |
+| **PA9024** | kontraktinformasjon | Ingen | |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **antall_timer_kontrakt** | Total timer per kontrakt - partisjonert på ansatt_nummer, kontrakt_nummer |
+| **belop_kontrakt** | Totalbeløp per kontrakt - partisjonert på ansatt_nummer, kontrakt_nummer |
+| **prosent_kontering** | Hvis `type_kontrakt_t_kode = 'T1'` → `antall_timer_kontering/antall_timer_kontrakt * 100`, ellers `belop_kontering/belop_kontrakt * 100` |
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_kronetillegg_pa0001.md b/docs/ap/hr/transformasjoner/sap_10_kronetillegg_pa0001.md
new file mode 100644
index 000000000..c305ecc4b
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_kronetillegg_pa0001.md
@@ -0,0 +1,92 @@
+# sap_10_kronetillegg_pa0001
+
+## Formål
+- Beregner kronetillegg for stillinger i PA0001 basert på PA0014 og et definert sett med lønnarter.
+- Genererer datointervaller uten overlapp og summerer alle tillegg som gjelder i samme periode, siden en ansatt kan ha flere lønnarter som inngår i et samlet kronetillegg samtidig.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0014** | Tilleggslønn | lonnart_kode IN (82 utvalgte lønnarter) | Hovedtabell for månedlige tilleggsbeløp per lønnsart |
+| **T512T** | Tekster knyttet til lønnarter | Ingen | Legger til tekst for hver lønnart som hentes fra PA0014 |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **belop_kronetillegg** | SUM(belop) * 12 — summerer alle tillegg i perioden og konverterer fra månedlig til årlig beløp |
+| **lonnart** | Kombinasjon av alle registrerte lønnartkoder fra PA0014 med navn fra T512T, separert med komma |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA0014 (filtrert på 82 utvalgte lønnarter) definerer gyldige datointervaller per ansatt
+- **Sekundærtabeller:** Ingen
+- **Nøkkelkolonner:** ansatt_nummer
+
+### 2. Tabellkoblinger
+Etter datointervallgenerering kobles følgende tabeller:
+- **PA0014**: Hovedtabell med datooverlapp og lonnart_kode-filter
+- **T512T**: Lønnarttekst
+
+### 3. Filtrering på lønnarter
+Kun 82 lønnarter basert på avtale mellom UiB, UiO og UiT inkluderes.
+Følgende kategorier brukes for å gruppere lønnartene (basert på SAP HR T512T):
+
+**Kategorier**
+
+- **Tilleggslønn:**
+ 1109, 1112, 1114–1119, 1120–1122, 112A–112H, 112J, 112K, 112L, 112T, 113D, 1151, 1378, 3318–3319, 3321, 4655
+
+- **Kompensasjoner (tid/helg/kveld/reserve):**
+ 1142 (natt), 1143 (lør/søn), 1144–1146 (morgen/kveld)
+
+- **Godtgjørelser:**
+ 1153–1156, 1162, 1165, 1167, 1179, 1184, 1199, 1289, 1305, 1422, 3081, 3227, 3256, 3450, 3607–3610, 3720
+
+- **Reisegodtgjørelser:**
+ 3015, 301H, 3030
+
+- **Husleiekompensasjon:**
+ 3012, 3022, 3037–3038
+
+- **Spesialordninger (polartillegg / særavtaler):**
+ 112M, 112P, 114A, 3377–3379
+
+- **Fast overtid og faste tillegg:**
+ 1300–1301
+
+- **Refusjoner:**
+ 1302 (bredbånd), 1340, 1489
+
+- **Styrehonorar:**
+ 1330, 1350
+
+- **Tillitsvalgt:**
+ 3047
+
+- **Andre ordninger:**
+ 1170 (hjemme-PC), 1195 (ventelønn), 1306 (ventelønn), 1328 (manuell korrigering), 2705 (utvidet arbeidstid)
+
+### 4. Summering av overlappende tillegg
+- PA0014 kan inneholde flere aktive tillegg for samme ansatt i samme periode
+- Datointervallgenereringen splitter perioder ved enhver endring
+- Summen av beløp per intervall gir ett samlet kronetillegg
+
+**Resultat:** Én rad per periode med totalbeløp for alle gjeldende tillegg.
+
+### 5. Konvertering fra månedlig til årlig beløp
+- Beløp i PA0014 er månedlige
+- Multipliseres med 12 → gir årlig verdi i belop_kronetillegg
+
+### 6. Gruppering og aggregering
+Gruppering gjøres på:
+- ansatt_nummer
+- dato_fra, dato_til (fra datointervallgenereringen)
+- Tekniske metadata (zx_institusjonskode og tidsstempler)
+
+Aggregering:
+- `lonnart`: collect_list + concat_ws for å samle alle lønnarter med beskrivelser
+- `belop_kronetillegg`: sum * 12 for årlig totalbeløp
+
+Dette sikrer at alle tillegg som gjelder i samme tidsperiode summeres til én rad.
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_lonn_pa0509.md b/docs/ap/hr/transformasjoner/sap_10_lonn_pa0509.md
new file mode 100644
index 000000000..31db37aa5
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_lonn_pa0509.md
@@ -0,0 +1,58 @@
+# sap_10_lonn_pa0509
+
+## Formål
+- Beregner lønn for tilleggsstillinger i PA0509 som også tar hensyn til lønnstrinn.
+- Beregner lønn ved å velge høyeste av verdien som er registrert direkte i PA0509 og satsen for eventuelt lønnstrinn i T510.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0509** | Tilleggsstillinger | Ingen | Hovedtabell for tilleggsstillinger med lønnsdata |
+| **T510** | Satser for bl.a. lønnstrinn | tariffavtale_kode='3' | Standardiserte lønnssatser basert på tariffkombinasjon og lønnstrinn |
+| **T512T** | Tekster knyttet til lønnarter | Ingen | Legger til tekst for hver lønnart som hentes fra PA0509 |
+| **T530F** | Tekst knyttet til lønnsendringsårsak | infotype_kode='0509' | Beskrivende tekst for lønnsendring |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **belop_grunnlonn** | Hvis belop_grunnlonn > 0 → bruk denne, ellers → bruk satser.belop |
+| **endring_aarsak_lonn_kode** | Hentet direkte fra PA0509 |
+| **endring_aarsak_lonn_tekst** | Hentet fra T530F |
+| **lonnart** | Kombinasjon av lønnartkode og navn fra T512T |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA0509 definerer gyldige datointervaller per ansatt og stilling
+- **Sekundærtabell:** T510 (med forretningsnøkler fra PA0509) bidrar med datogrenser fra lønnssatser
+- **Nøkkelkolonner:** ansatt_nummer, stilling_id
+
+### 2. Forretningsnøkler til sekundærtabeller
+T510 mangler ansatt_nummer og stilling_id og må berikes før datointervallgenerering:
+- Joines mot PA0509 på tarifftype, tariffområde, tariffgruppe, lønnstrinn og datooverlapp
+- Returnerer ansatt_nummer, stilling_id + dato_fra/dato_til for bruk i combine_date_intervals
+
+### 3. Tabellkoblinger
+Etter datointervallgenerering kobles følgende tabeller:
+- **PA0509**: Hovedtabell med datooverlapp på ansatt_nummer + stilling_id
+- **T510**: Lønnssatser med tariffnøkkel og datooverlapp
+- **T512T**: Lønnarttekst
+- **T530F**: Endringsårsaktekst med infotype_kode='0509'
+
+### 4. Grunnlønnsberegning
+Enkel prioritering:
+1. Hvis `PA0509.belop_grunnlonn > 0` → bruk denne (individuell avtale)
+2. Ellers → bruk `T510.belop` (tariffsats)
+
+**Forskjell fra PA0001:**
+Ingen komplekse tariffperioder, stigeprosent eller mange kasus. Kun et enkelt valg mellom to verdier.
+
+### 5. T510 filtrering (lønnssatser)
+- Filtrert på tariffavtale_kode='3'
+- Joines på tarifftype, tariffområde, tariffgruppe og lønnstrinn (med COALESCE til '-1')
+- Gir tariffbasert sats (satser.belop)
+
+### 6. Lønnsendringskoder (T530F)
+- Joines på infotype_kode='0509'
+- Gir tekstforklaring til endring_aarsak_lonn_kode
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_lonn_pa9024.md b/docs/ap/hr/transformasjoner/sap_10_lonn_pa9024.md
new file mode 100644
index 000000000..3d2053bca
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_lonn_pa9024.md
@@ -0,0 +1,88 @@
+# sap_10_lonn_pa9024
+
+## Formål
+- Beregner lønn for stillinger i PA9024 .
+- Beregner lønn ved å velge høyeste verdi mellom det som er direkte registrert i PA9024 og satsen for eventuelt lønnstrinn i T510.
+- Særskilt håndtering av pensjonistkontrakter siden disse registreres med timelønn og ganges med 1950 for å få årslønn.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA9024** | Kontrakter | hvis h.r-1.1 kontrakt_overlapp='X' eller ingen filtrering | Hovedtabell for kontrakter med overlapp |
+| **ZEAC_CONTRA_DATA** | Kontraktsdata | Ingen | Kobler PA9024 mot T510 via tariffnøkkel |
+| **T510** | Satser for bl.a. lønnstrinn | Pensjonistavtaler OR (lonnart_kode='1000', tariffavtale_kode='3') | Tariffbaserte lønnssatser |
+| **YHR_P9024_LINJER** | Kontraktslinjer | Ingen | Kobler lonnart_kode til kontrakter |
+| **T512T** | Tekster knyttet til lønnarter | Ingen | Legger til tekst for hver lønnart |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **belop_grunnlonn** | Hvis belop_grunnlonn > 0 → bruk denne, elif pensjonist → satser.belop * 1950, else → satser.belop |
+| **lonnart** | Kombinasjon av lønnartkoder fra YHR_P9024_LINJER med navn fra T512T, separert med komma |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA9024 (filtrert på kontrakt_overlapp='X') hvis h.r-1.1 ellers ingen filtrering. definerer gyldige datointervaller per ansatt og kontrakt
+- **Sekundærtabell:** T510 (med forretningsnøkler fra zeac_contra_data og PA9024) bidrar med datogrenser fra lønnssatser
+- **Nøkkelkolonner:** ansatt_nummer, kontrakt_nummer
+
+### 2. Forretningsnøkler til sekundærtabeller
+T510 mangler ansatt_nummer og kontrakt_nummer og må berikes før datointervallgenerering:
+- Joines mot zeac_contra_data på tarifftype, tariffområde, tariffgruppe og lønnstrinn
+- Joines videre mot PA9024 på kontrakt_nummer og datooverlapp
+- Returnerer ansatt_nummer, kontrakt_nummer + dato_fra/dato_til for bruk i combine_date_intervals
+
+### 3. Tabellkoblinger
+Etter datointervallgenerering kobles følgende tabeller:
+- **PA9024**: Hovedtabell med datooverlapp på ansatt_nummer + kontrakt_nummer
+- **ZEAC_CONTRA_DATA**: Kontraktsdata med tariffnøkkel
+- **T510**: Lønnssatser med tariffnøkkel og datooverlapp
+- **YHR_P9024_LINJER**: Kontraktslinjer for lonnart
+- **T512T**: Lønnarttekst
+
+### 4. Grunnlønnsberegning
+Tre-trinns prioritering:
+1. Hvis PA9024.belop_grunnlonn > 0 → bruk denne (individuell avtale)
+2. Elif pensjonist (75/90/PENSJAVT) → satser.belop * 1950 (timelønn til årslønn, 1950 = 37,5 t/uke × 52 uker)
+3. Else → satser.belop (standard tarifflønn)
+
+Ingen stigeprosent eller ansiennitetsberegning.
+
+### 5. T510 filtrering (lønnssatser)
+
+**Pensjonistavtaler:**
+- lonnart_kode = ''
+- tariffavtale_kode = '1'
+- tarifftype_kode = '75'
+- tariffomraade_kode = '90'
+- tariffgruppe_kode = 'PENSJAVT'
+
+**Alle andre:**
+- lonnart_kode = '1000'
+- tariffavtale_kode = '3'
+- Ikke pensjonistavtaler
+
+**Merk:** Dersom DFØ rydder i pensjonistoppsettet, kan logikken forenkles til kun tariffavtale='3' og lonnart='1000'.
+
+### 6. Kronetillegg
+- Hentes direkte fra PA9024.belop_kronetillegg
+- Ingen summering eller transformasjon
+
+### 7. Lønnarttekster (YHR_P9024_LINJER + T512T)
+
+- Joiner YHR_P9024_LINJER på ansatt_nummer + kontrakt_nummer
+- Joiner T512T på lonnart_kode
+- Kombineres med collect_list + concat_ws + array_compact
+
+### 8. Gruppering og aggregering
+Gruppering gjøres på alle ikke-aggregerte kolonner for å støtte LISTAGG av lonnart.
+
+Aggregering:
+- `lonnart`: collect_list + concat_ws for å samle alle lønnarter med beskrivelser
+- `belop_grunnlonn`: beregnet basert på pensjonistlogikk
+
+### 9.Slutt tabell
+Hvis h.r-1.1 data lagres i sap_10_lonn_pa9024x som er eklusive for overlapp kontrakter
+ellers data lagres i sap_10_lonn_pa9024
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_medarbeidergrupper.md b/docs/ap/hr/transformasjoner/sap_10_medarbeidergrupper.md
new file mode 100644
index 000000000..48733bc7c
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_medarbeidergrupper.md
@@ -0,0 +1,31 @@
+# sap_10_medarbeidergrupper
+
+## Formål
+Tabell for medarbeidergrupper med BOT-definert gruppering av alle medarbeidergrupper i `tilknytningsform`.
+
+## Datakilde
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **T501T** | Medarbeidergrupper (SAP-standard) | Ingen | Gir medarbeidergruppekoder og -navn |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **tilknytningsform_kode** | CASE-logikk som mapper medarbeidergruppe til kode (FA/AA/MA/NAV/EMO/EUO/-1) |
+| **tilknytningsform_navn** | CASE-logikk som mapper medarbeidergruppe til beskrivelse (Fast ansatt / Åremålsansatt / Midlertidig ansatt / Tiltak NAV / Ekstern med oppdrag / Ekstern uten oppdrag / Ukjent) |
+
+## Transformasjonslogikk
+
+### Tilknytningsform-mapping
+BOT-definert klassifisering basert på medarbeidergruppe.
+
+| Medarbeidergruppe | Tilknytningsform kode | Tilknytningsform navn |
+|-------------------|-----------------------|------------------------|
+| 1, 2 | FA | Fast ansatt |
+| 3 | AA | Åremålsansatt |
+| 4, 5, 6 | MA | Midlertidig ansatt |
+| 7 | NAV | Tiltak NAV |
+| 8 | EMO | Ekstern med oppdrag |
+| 9 | EUO | Ekstern uten oppdrag |
+| B, E, F, L, M, P, S, T, V, X | -1 | Ukjent |
+| Andre | -1 | Ukjent |
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_medarbeiderundergrupper.md b/docs/ap/hr/transformasjoner/sap_10_medarbeiderundergrupper.md
new file mode 100644
index 000000000..0e52ab02b
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_medarbeiderundergrupper.md
@@ -0,0 +1,34 @@
+# sap_10_medarbeiderundergrupper
+
+## Formål
+Tabell for medarbeiderundergrupper med BOT-definert gruppering av alle medarbeidergrupper i `avlonningsform`. Dette gjør at man enkelt kan skille ut f.eks. måneds- eller timelønnede stillinger.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **T503T** | Medarbeiderundergruppe-tekster | Ingen | Gir koder og navn for medarbeiderundergrupper |
+| **T503K** | Medarbeiderundergruppe-validering | Ingen (INNER JOIN) | Ekskluderer ubrukte eller inaktive undergrupper |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **avlonningsform_kode** | Mappes basert på `medarbeiderundergruppe_kode` |
+| **avlonningsform_navn** | Mappes basert på `medarbeiderundergruppe_kode` |
+
+## Transformasjonslogikk
+
+### 1. Avlønningsform-mapping
+Mapping av medarbeiderundergrupper til BOT-definerte avlønningsformer:
+
+| Avlønningsform | Kode | Medarbeiderundergrupper |
+|----------------|------|--------------------------|
+| Månedslønn | MAA | 01, 02, 03, 10, 11, 12, 13, 14, 20, 21, 29, 33, 39, 40, 43 |
+| Timelønn | TIM | 04, 15, 22, 30, 35 |
+| Honorar | HON | 23, 38, 50 |
+| Stipend | STI | 59 |
+| Uten lønn | UT | 44, 94 |
+| Ukjent | -1 | Alle andre koder |
+
+### 2. Datakvalitet
+- INNER JOIN mot T503K sikrer at kun gyldige medarbeiderundergrupper inkluderes
+- `DISTINCT` brukes for å fjerne eventuelle duplikater og sikre én rad per undergruppe
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_organisasjonsenheter.md b/docs/ap/hr/transformasjoner/sap_10_organisasjonsenheter.md
new file mode 100644
index 000000000..89686045b
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_organisasjonsenheter.md
@@ -0,0 +1,161 @@
+# sap_10_organisasjonsenheter
+
+## Formål
+- Lager en utflatet organisasjonsstruktur med opptil 10 nivåer og historiske data basert på HRP1001-relasjoner.
+- Strukturen inneholder informasjon om overordnede enheter, ledere, DBH-avdelinger og koststedsinformasjon med historikk.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **HRP1000** | Objektinformasjon | `objekttype_kode = 'O'` (org.enheter), `objekttype_kode = '03'` (DBH) | Definerer org.enheter og DBH-avdelinger |
+| **HRP1001** | Objektrelasjoner | Flere relasjonstype-filtre | Definerer relasjon mellom organisasjonsenheter, leder, DBH-avdelinger og hovedkostnadssted |
+| **HRP1008** | Relasjon til PDO | `objekttype_kode = 'O'`, `planversjon_kode = '10'`, `planleggingsstatus_kode = '1'`, `infotype_kode = '1008'` | Definerer relasjon mellom organisasjonsenheter og PDO |
+| **HRP1018** | Relasjoner til kostnadsfordeling | `objekttype_kode = 'O'`, `planversjon_kode = '10'`, `planleggingsstatus_kode = '1'`, `infotype_kode = '1018'` | Definerer relasjonen mellom organisasjonsenheter og kostnadsfordelingsinformasjonen i `HRP1018` via `tabellreferanse_nummer` |
+| **HRT1018** | Kostnadsfordeling per `tabellreferanse_nummer`i HRP1018 | `prosent_kontering = '100` (ingen organisasjonsenheter skal ha splittet kostnadsfordeling) | Inneholder selve kostnadsfordelingen med koststed, delprosjekt og arbeidspakke_bygg for en gitt `organisasjon_id` (og `tabellreferanse_nummer`) i HRP1018 |
+| **PA0001** | Stillinger | Ingen | Knytter leder-stilling til ansatt_nummer. Behøves fordi leder for organisasjonsenhet registreres via stillings-ID-en til lederen |
+| **PA0002** | Persondata | Siste rad per ansatt | Henter ledernavn |
+| **T001P** | Navn på PDO | Ingen | Henter navn på PDO |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **level** | Iterativ beregning fra rotnode (nivå 0) |
+| **resolved_personaldelomraade_kode** | `COALESCE(personaldelomraade_kode, parent_resolved_personaldelomraade_kode)` |
+| **resolved_koststed_hoved_kode** | `COALESCE(koststed_hoved_kode, parent_resolved_koststed_hoved_kode)` |
+| **organisasjon_id_nivaa_0 → _nivaa_10** | Flatet hierarki fra barn til rot |
+| **navn_nivaa_0 → _nivaa_10** | Navn per nivå |
+| **leder_ansatt_nummer_nivaa_X** | Ansattnummer for leder på nivå X (default `-1`) |
+| **leder_navn_nivaa_X** | Navn for leder på nivå X (default `Ukjent`) |
+| **dbh_avdeling_kode_nivaa_X** | DBH-avdeling per nivå (default `-1`) |
+| **personaldelomraade_kode_nivaa_X** | Arvet PDO per nivå |
+| **personaldelomraade_navn_nivaa_X** | Arvet PDO-navn per nivå |
+| **koststed_hoved_kode_nivaa_X** | Arvet koststed per nivå |
+| **koststed_kode_nivaa_x** | Konteringskoststed på nivå X (default `-1`) |
+| **delprosjekt_nummer_nivaa_x** | Delprosjekt på nivå X (default `-1`) |
+| **arbeidspakke_bygg_nummer_nivaa_x** | Arbeidspakke/bygg på nivå X (default `-1`) |
+
+## Transformasjonslogikk
+
+### 1. Laste data
+- **HRP1000:** Objektdata for org.enheter og DBH
+- **HRP1001:** Alle relasjoner (barn–forelder, leder, koststed, DBH)
+- **HRP1008:** Relasjoner til PDO per organisasjonsenhet
+- **HRP1018:** Relasjoner til kostnadsfordeling per organisasjonsenhet
+- **HRT1018:** Kostnadsfordeling per organisasjonsenhet
+- **PA0001:** Stilling → ansatt_nummer
+- **PA0002:** Ansattnummer → navn
+- **T001P:** Navn på PDO
+
+### 2. Bygge DataFrames på dagnivå
+
+#### a) Organisasjonsenheter med foreldre
+- HRP1000 filtrert til `objekttype_kode = 'O'`
+- HRP1001 filtrert til:
+ - `objekttype_kode = 'O'` → `relasjon_objekttype_kode = 'O'`
+ - `relasjonstype_kode = '002'` (hierarki)
+ - `relasjonsretning_kode = 'B'` (overordnet)
+- Eksploderer datoer til dagnivå
+- Joiner barnet med parent-enhet
+
+#### b) Organisasjonsenheter med PDO
+- HRP1008 filtrert til:
+ - `objekttype_kode = 'O'`
+ - `planversjon_kode = '10'`
+ - `planleggingsstatus_kode = '1'`
+ - `infotype_kode = '1008'`
+- Joiner mot org.enhet
+
+#### c) Organisasjonsenheter med hovedkoststed
+- HRP1001 filtrert til:
+ - `objekttype_kode = 'O'` → `relasjon_objekttype_kode = 'K'`
+ - `relasjonstype_kode = '011'`
+ - `relasjonsretning_kode = 'A'`
+- Ekstraherer koststed fra `relasjon_objekt_id`
+- Joiner mot org.enhet
+
+#### d) Kostnadsfordeling per organisasjonsenhet
+- HRP1018 filtrert til:
+ - `objekttype_kode = 'O'`
+ - `planversjon_kode = '10'`
+ - `planleggingsstatus_kode = '1'`
+- HRT1018 filtrert til:
+ - `prosent_kontering = 100` (skal ikke være splittet kontering på organisasjonsenheter, hvis ikke blir granulariteten i output feil)
+
+#### e) Ledere for organisasjonsenheter
+- HRP1001 filtrert til:
+ - `objekttype_kode = 'O'` → `relasjon_objekttype_kode = 'S'`
+ - `relasjonstype_kode = '012'`
+ - `relasjonsretning_kode = 'B'`
+- Ekspanderes til dagnivå
+- Join mot PA0001 (stilling → ansatt_nummer)
+- Join mot PA0002 (ansatt_nummer → navn)
+- Fjerner feilrader med flere ledere samme dag
+
+#### f) Organisasjonsenheter med DBH-avdeling
+- HRP1000 filtrert til `objekttype_kode = '03'` (DBH)
+- HRP1001 filtrert til:
+ - `objekttype_kode = 'O'` → `relasjon_objekttype_kode = '03'`
+ - `relasjonstype_kode = 'Z30'`
+ - `relasjonsretning_kode = 'A'`
+- Ekstraherer DBH-kode fra `navn_kort`
+- Fjerner duplikater og feil koblinger
+
+### 3. Bygge organisasjonshierarki
+
+#### a) Rotnode
+- Enheter der `parent_organisasjon_id IS NULL`
+- `level = 0`
+- `resolved_personaldelomraade_kode = personaldelomraade_kode`
+- `resolved_personaldelomraade_navn = personaldelomraade_navn`
+- `resolved_koststed_hoved_kode = koststed_hoved_kode`
+
+#### b) Iterativ hierarkiprosess (maks 10 nivåer)
+1. Start med rotnode
+2. Finn barn for alle foreldre
+3. Sett `level = parent_level + 1`
+4. Arv koststed og personaldelområde
+5. Unionér inn i resultatsett
+6. Bruk barna som nye foreldre
+7. Stopp når ingen nye barn finnes
+
+#### c) Ledere, DBH-avdelinger og kostnadsfordeling inn i hierarkiet
+- LEFT JOIN mot leder-DF, DBH-DF og kostnadsfordeling-DF
+- Default-verdier settes ved NULL:
+ - `leder_ansatt_nummer = '-1'`
+ - `leder_navn = 'Ukjent'`
+ - `dbh_avdeling_kode = '-1'`
+ - `koststed_kode = '-1'`
+ - `delprosjekt_nummer = '-1'`
+ - `arbeidspakke_bygg_nummer = '-1'`
+
+#### d) Flatstruktur til 10 nivåer
+- Bruker top-down-join fra nivå 10 → nivå 0
+- For hvert nivå:
+ `COALESCE(parent.field, child.field_nivaa_{level+1})`
+- Sikrer at alle enheter får komplett linje opp til rot
+
+### 4. Legge til zx-kolonner
+- Join mot HRP1000 på `organisasjon_id_nivaa_10` og dato
+- Legger til:
+ - `zx_institusjonskode`
+ - `zx_tidspunkt_lastet`
+ - `zx_tidspunkt_bronze`
+ - `zx_tidspunkt_silver`
+
+### 5. Aggregere dagnivå til datointervaller
+- Setter `dato_fra` og `dato_til`
+- Slår sammen identiske perioder med `merge_identical_consecutive_rows()`
+- Avsluttende perioder settes til `9999-12-31`
+
+### 6. Omorganisere kolonner
+- `dato_fra`, `dato_til` først
+- Deretter alle `_nivaa_X`-kolonner
+- Til slutt zx-kolonnene
+
+## HRP1001 – Relasjonstyper brukt
+| Relasjonstype | Fra objekt | Til objekt | Retning | Betydning |
+|---------------|------------|------------|---------|-----------|
+| **002** | O | O | B | Forelder–barn-relasjon |
+| **011** | O | K | A | Hovedkoststed |
+| **012** | O | S | B | Leder (stilling) |
+| **Z30** | O | 03 | A | DBH-avdeling |
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_personer.md b/docs/ap/hr/transformasjoner/sap_10_personer.md
new file mode 100644
index 000000000..011b58187
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_personer.md
@@ -0,0 +1,97 @@
+# sap_10_personer
+
+## Formål
+- Sammenstiller informasjon relatert til personer med historikk fra PA-tabeller til en helhetlig personvisning med `dato_fra` og `dato_til`.
+- Inneholder demografiske data, utdanningsinformasjon, adresse, bankinformasjon, arbeidsprosent, ansettelsesdatoer, fratredelsesdatoer **og klassifisering av skattekort**.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0000** | Ansettelsesstatus | Ingen | Status og fratredelser (typer 10, 11, 40) |
+| **PA0002** | Persondata | Ingen | Navn, fødselsdato, kjønn, nasjonalitet, språk |
+| **PA0006** | Adresse | `deltype_kode = '1'` | Postadresse |
+| **PA0007** | Arbeidstid | Ingen | Timer per uke (brukes til prosent_arbeid) |
+| **PA0009** | Bankinformasjon | `bankinformasjon_type IN ('0','2')` | Bankland og valuta for lønn/reise |
+| **PA0019** | Fratredelsesdato | `datotype = '79'` | Historiske fratredelser |
+| **PA0022** | Utdanning | `utdanningstype_kode = '01'`, `sekvens_nummer = '000'` | Siste utdanningskode per ansatt |
+| **PA0105** | Tlf, epost, feideid osv | `kommunikasjonstype_kode IN ('9020', '0001', '0010', '0030', '0020', '9003', '9004')` | Tlf, epost, feideid osv |
+| **PA0173** | Skattekort | første gyldige organisasjon_nummer i T5V2K, `aar_skattekort <> ''` (kriterie for manglende skattekort) | Skattekorttype (hoved og bi) |
+| **PA0185** | Identifikasjon | `identifikasjonstype_kode = '02'` | Statsborgerskap |
+| **PA3363** | Arbeidsland | `deltype_kode IN ('9901','9902')` | Land for arbeidssted |
+| **PA9008** | Hovedsammenslutning | Ingen | Hovedsammenslutningkode og hovedsammenslutningtekst (Akademikerne, YS osv.) |
+| **PA9052** | Tlf mobil | `deltype_kode IN ('0001','0002')` | Tlf mobil |
+| **T518B** | Utdanningsnavn | Lookup | Beskrivende navn for utdanningskode |
+| **T529U** | Statusbeskrivelse | `status_nummer = '2'` | Beskrivelse av ansettelsesstatus |
+| **T530T** | Fratredelsesbeskrivelse | Lookup | Navn på fratredelsesårsak |
+| **T002T** | Språk | Lookup | Språknavn |
+| **T5V2K** | Gjeldende organisasjons_nummer |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **dato_fratredelse** | Historiske rader: fratredelse fra PA0000. Aktive/fremtidige: første fremtidige fratredelse (ROW_NUMBER = 1). Filtrert på typer 10/11/40. |
+| **prosent_arbeid** | `(timer_per_uke / 37.5) * 100` fra PA0007 |
+| **kjonn_navn** | CASE: 1 = Mann, 2 = Kvinne, ellers Ukjent |
+| **fullt_navn** | `etternavn + ', ' + fornavn` |
+| **ansatt_navn** | `fornavn + ' ' + etternavn` |
+| **land_kode_arbeid** | Søk i PA3363 attributt_id_1–30 etter `9901`/`9902`. Hent tilhørende attributt_verdi_X. Prioritet: 9901 → 9902. |
+| **skattekorttype_hoved** | Klassifiserer hovedskattekort basert på `skattekorttype_kode_hoved` fra PA0173:
• `P` → Prosentskattekort
• `T` → Tabellkort
• `F` → Frikort
• `U` → Ubegrenset
• `''` eller `NULL` → Ingen skattekort
• Ellers → Annet |
+| **skattekorttype_bi** | Klassifiserer bi-skattekort basert på `skattekorttype_kode_bi` fra PA0173:
• `P` → Prosentskattekort
• `T` → Tabellkort
• `F` → Frikort
• `U` → Ubegrenset
• `''` eller `NULL` → Ingen skattekort
• Ellers → Annet |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA0002 definerer gyldige datointervaller per ansatt
+- **Sekundærtabell:** pa0000, pa0006, pa0007, pa0009, pa0022, pa3363
+- **Nøkkelkolonner:** ansatt_nummer
+
+### 2. Fratredelsesdato (PA0000)
+Todelt logikk:
+
+**Historiske perioder (dato_til < dagens dato):**
+- Fratredelse som overlapper intervallet
+- Typer 10, 11, 40
+
+**Aktive/fremtidige perioder (dato_til ≥ dagens dato):**
+- Første fremtidige rad (`ROW_NUMBER = 1`)
+- Filtrert på samme typer
+
+### 3. Arbeidsprosent (PA0007)
+- Henter timer_per_uke
+- Konverterer til prosent basert på 37,5-timers uke
+
+### 4. Utdanning (PA0022)
+- Filter: `utdanningstype_kode = '01'`, `sekvens_nummer = '000'`
+- ROW_NUMBER på (`dato_fra`, `dato_til`)
+- Sortert på `siste_endring_dato DESC`
+- Henter siste gyldige kode per ansatt og periode
+
+### 5. Statsborgerskap (PA0185)
+- Filter: `identifikasjonstype_kode = '02'`
+- ROW_NUMBER per ansatt
+- Sortert på `dato_til DESC`
+- Returnerer siste registrerte statsborgerskap
+
+### 6. Arbeidsland (PA3363)
+- Søk gjennom attributt_id_1–30 etter deltype `9901`/`9902`
+- Prioritet: `9901` → `9902`
+- Hvis ingen treff: `Ukjent`
+
+### 7. Skattekort (PA0173)
+- Leser skattekorttype for hoved- og biarbeidsforhold
+- filtrert data som har gjeldene organisasjons_nummer
+- Mapper tekniske koder til funksjonelle, lesbare verdier
+- Tom eller manglende verdi behandles eksplisitt som **Ingen skattekort**
+
+### 8. Kommunikasjonsinformasjon (PA0105 og PA9052)
+- Utleder brukernavn_feide, brukernavn_dfo, epost_jobb, epost_privat, telefon_fast_jobb, telefon_mobil_jobb og telefon_mobil_privat
+
+### 9. Hovedsammenslutning (PA9008)
+- Henter hovedsammenslutning_kode fra silver_sap.pa9008
+- Utleder hovedsammenslutning_tekst med følgende logikk:
+ - 01 = Akademikerne
+ - 02 = YS
+ - 03 = LO
+ - 04 = Unio
+ - 05 = Annet
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_stillinger_pa0001.md b/docs/ap/hr/transformasjoner/sap_10_stillinger_pa0001.md
new file mode 100644
index 000000000..ffd5e0e51
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_stillinger_pa0001.md
@@ -0,0 +1,21 @@
+# sap_10_stillinger_pa0001
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0001** | Hovedstillinger | Ingen | Definerer hovedstillinger med organisasjon, medarbeidergruppe, lovhjemmel, koststed og stillingskode |
+| **PA0509** | Tilleggsstillinger | `aarsak_kode = 'AC'` | Legger til stillingsprosent ved fungering i perioden hovedstillingen løper |
+| **HRP1051** | Stillingens yrkeskoder | `objekttype_kode = 'S'`, `planversjon_kode = '10'`, `planleggingsstatus_kode = '1'`, `deltype_kode = 'NOYK'` | Legger til STYRK/yrkesklassifisering |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **stillingskode** | `SUBSTR(stillingskode, LENGTH(stillingskode) - 3, 4)` |
+| **type_stilling_kode** | Konstant verdi: `"HOVED"` |
+| **ekstraerverv** | `CASE WHEN lovhjemmel_kode IN ('11','28','65','66') THEN 'Ja' ELSE 'Nei' END` |
+| **prosent_stilling_fungering** | `fungeringer.prosent_stilling` (fra PA0509 med `aarsak_kode = 'AC'`) |
+
+## Transformasjonslogikk
+- PA0001 er hovedtabell.
+- PA0509 og HRP1051 berikes med forretningsnøkler via join mot PA0001.
+- Datointervaller kombineres med `combine_date_intervals` før endelig join.
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_stillinger_pa9024.md b/docs/ap/hr/transformasjoner/sap_10_stillinger_pa9024.md
new file mode 100644
index 000000000..b0025e68e
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_stillinger_pa9024.md
@@ -0,0 +1,75 @@
+# sap_10_stillinger_pa9024
+
+## Formål
+- Kombinerer kontraktsdata i PA9024 og ZEAC_CONTRA_DATA.
+- Legger til lønnsavregningsgruppe fra PA0001.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA9024** | Kontraktsforhold | Ingen | kontrakter |
+| **ZEAC_CONTRA_DATA** | Kontraktsdetaljer | Ingen | Gir stillingskode, organisasjon, tariff, lovhjemmel og kontraktstype |
+| **PA0001** | Hovedstilling | Join mot PA9024 | Henter lønnsavregningsgruppe fra hovedstilling |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **stillingskode** | `SUBSTR(stillingskode, LENGTH(stillingskode) - 3, 4)` |
+| **type_stilling_kode** | `CASE WHEN kontrakt_overlapp='X' AND type_kontrakt_t_kode like 'T%' THEN concat('X','type_kontrakt_t_kode') ELSE 'type_kontrakt_t_kode' END` |
+| **ekstraerverv** | `CASE WHEN lovhjemmel_kode IN ('11','28','65','66') THEN 'Ja' ELSE 'Nei' END` |
+| **medarbeidergruppe_kode** | Mappes fra `type_kontrakt_t_kode` + `kontraktstype_c_kode` (se tabell under) |
+| **medarbeiderundergruppe_kode** | Mappes fra samme regelsett (se tabell under) |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA9024 - definerer gyldige datointervaller per ansatt og kontrakt
+- **Sekundærtabell:** PA0001
+- **Nøkkelkolonner:** `ansatt_nummer`, `kontrakt_nummer`
+
+### 2. Forretningsnøkler til sekundærtabeller
+PA0001 mangler kontrakt_nummer og må berikes før datointervallgenerering:
+- Joines mot PA9024 på kontrakt_nummer og datooverlapp
+- Returnerer ansatt_nummer, kontrakt_nummer + dato_fra/dato_til for bruk i combine_date_intervals
+
+### 3. Tabellkoblinger
+Etter datointervallgenerering kobles følgende tabeller:
+- **PA9024**: Hovedtabell med datooverlapp på ansatt_nummer + kontrakt_nummer
+- **ZEAC_CONTRA_DATA**: Kontraktsdata med tariffnøkkel
+- **PA0001**: Lønnsavregningsgruppe fra hovedstillingen
+
+### 2. Medarbeidergruppemapping
+Regel basert på T-kode + C-kode:
+
+| type_kontrakt_t_kode | kontraktstype_c_kode | medarbeidergruppe_kode |
+|----------------------|----------------------|------------------------|
+| T1 | C10 | 3 (Åremål) |
+| T1 | C1 | 4 (Midlertidig) |
+| T1 | Andre | 4 (Midlertidig) |
+| T3 | C10 | 3 (Åremål) |
+| T3 | Andre | 4 (Midlertidig) |
+| Andre | – | -1 (Ukjent) |
+
+### 3. Medarbeiderundergruppemapping
+| type_kontrakt_t_kode | kontraktstype_c_kode | medarbeiderundergruppe_kode |
+|----------------------|----------------------|-----------------------------|
+| T1 | C10 | 04 |
+| T1 | C1 | 30 |
+| T1 | Andre | 04 |
+| T3 | C10 | 01 |
+| T3 | Andre | 01 |
+| Andre | – | -1 (Ukjent) |
+
+### 4. Ekstraervervklassifisering
+Lovhjemmelkoder styrer klassifiseringen:
+
+- **11** – Timelønn / ekstrahjelp
+- **28** – Honorar
+- **65** – Bistilling
+- **66** – Ekstraarbeid
+- **Andre** → *Nei*
+
+### 5. Stillingstypeklassifisering\n
+- **XT1,XT2,XT3:** Overlappende T-kontrakt
+- **T1,T2,T3** T-kontrakter uten overlapp
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_stillingsansiennitet.md b/docs/ap/hr/transformasjoner/sap_10_stillingsansiennitet.md
new file mode 100644
index 000000000..266682d84
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_stillingsansiennitet.md
@@ -0,0 +1,34 @@
+# sap_10_stillingsansiennitet
+
+## Formål
+Henter stillingsansiennitet (`dato_ansiennitet_stilling`) fra PA0041 basert på `dato_type = 'ST'`. Benyttes som lookup-tabell for å berike stillinger fra PA0001 med ansiennitetsdato.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0041** | Datoer | `dato_type_X = 'ST'` | Inneholder stillingsansiennitetsdato (kan ligge i ett av 24 datofelt) |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **dato_ansiennitet_stilling** | Søker gjennom `dato_type_1`–`dato_type_24` etter `'ST'` og returnerer tilhørende `dato_X`. CASE-implementasjon som stopper ved første match. |
+
+## Transformasjonslogikk
+
+### 1. Filtrering på dato_type = 'ST'
+- Filtrerer PA0041 for rader hvor minst én av `dato_type_1`–`dato_type_24` er `'ST'`
+- `ST` = Stillingsansiennitet (seniority in position)
+- WHERE-klausulen sjekker alle 24 datotype-kolonner (OR-logikk)
+
+### 2. Ekstraksjon av ansiennitetsdato
+- Går systematisk gjennom `dato_type_1` → `dato_type_24`
+- Når `'ST'` finnes: hent `dato_X`
+- Første match prioriteres (laveste X vinner)
+
+**Eksempel:**
+Hvis `dato_type_3 = 'ST'` → `dato_3` brukes som `dato_ansiennitet_stilling`.
+
+### 3. Ingen datointervallgenerering
+- Benytter eksisterende `dato_fra` / `dato_til` fra PA0041
+- Ingen CTE-basert intervallkonstruksjon
+- Direkte SELECT fra kildetabell
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_10_terminslutt.md b/docs/ap/hr/transformasjoner/sap_10_terminslutt.md
new file mode 100644
index 000000000..4132c6897
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_10_terminslutt.md
@@ -0,0 +1,35 @@
+# sap_10_terminslutt
+
+## Formål
+Henter terminslutt-datoer fra PA0019 for utvalgte `dato_type`-verdier og lagrer siste gyldige terminslutt per institusjon, ansatt og kode.
+
+## Datakilder
+| Tabell | Formål | Filtre | Rolle |
+|--------|--------|--------|-------|
+| **PA0019** | Datoer knyttet til ulike terminslutt-typer | `dato_type IN ('20','66','72','79')` | Grunnlagstabell for terminslutt |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **terminslutt_kode** | Direkte mapping fra `dato_type` |
+| **dato_terminslutt** | Direkte fra `dato` i PA0019 |
+| **rangering** | `ROW_NUMBER()` per ( `ansatt_nummer`, `dato_type`) sortert på `siste_endring_dato DESC` |
+
+## Transformasjonslogikk (PySpark)
+### 1. Load source data
+Laster `pa0019` fra `silver_sap`.
+
+### 2. Transform data
+Filtrerer til `dato_type` i `('20','66','72','79')`, oppretter `terminslutt_kode` og `dato_terminslutt`, og rangerer rader med vindusfunksjon.
+
+### 3. Velg siste registrering
+Beholder kun rader med `rangering = 1` for å sikre sist registrerte terminslutt.
+
+### 4. Select final set of columns
+Velger endelig kolonneutvalg for måltabellen.
+
+### 5. Write to target
+Skriver resultatet til `transformation_hr.sap_10_terminslutt` med `overwrite` og `overwriteSchema`.
+
+## Datointervallgenerering
+Ingen datointervallgenerering brukes i denne tabellen (punkt-i-tid-tabell uten `dato_fra`/`dato_til`).
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_20_stillinger_pa0001.md b/docs/ap/hr/transformasjoner/sap_20_stillinger_pa0001.md
new file mode 100644
index 000000000..13e85b9c1
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_20_stillinger_pa0001.md
@@ -0,0 +1,72 @@
+# sap_20_stillinger_pa0001
+
+## Formål
+- Sammenstiller informasjon relatert til stillinger i PA0001 fra 10-tabellene til én tabell.
+- Inkluderer beregnet årsverk, alder, ansiennitet og kostnadsfordeling.
+
+## Datakilder (lag 10)
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_stillinger_pa0001** | Hovedstillingsdata, definerer datointervaller | Ingen |
+| **sap_10_fodselsdager** | Fødselsdager, genererer datobrudd for korrekt aldersberegning | Ingen |
+| **sap_10_grunnlonn_pa0001** | Grunnlønn, prosent_stilling, fungering | Ingen |
+| **sap_10_kontering_pa0001_pa0509** | Kostnadsfordeling | `kostnadstype_fordeling_kode = '01'` |
+| **sap_10_kronetillegg_pa0001** | Kronetillegg | Ingen |
+| **sap_10_stillingsansiennitet** | Ansiennitetsdato | Ingen |
+| **sap_10_fravaer_permisjon** | Fravær/permisjon til bruk i årsverk eks. permisjon | Ingen |
+| **sap_10_fravaer_dbh** | DBH-fravær | Ingen |
+| **sap_10_personer** | Personinformasjon (demografi, alder, kjønn, statsborgerskap) | Ingen |
+| **sap_10_terminslutt** | Terminslutt for hovedstilling | `terminslutt_kode = '72'` |
+| **sap_10_organisasjonsenheter** | Organisasjonsstruktur (nivå 0–10) | Join på `organisasjon_id_nivaa_10` |
+| **sap_10_medarbeidergrupper** | Lookup for tilknytningsform | Ingen |
+| **sap_10_medarbeiderundergrupper** | Lookup for avlønningsform | Ingen |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **aaremaal** | `CASE WHEN medarbeidergruppe_kode = '3' THEN 'Ja' ELSE 'Nei' END` |
+| **alder** | Validerer fødselsdato og beregner alder basert på dato_fra/dato_til/GETDATE(). Ugyldig: 1900-01-01 eller utenfor 16–110 → `-1`. |
+| **prosent_stilling** | Hentet fra `sap_10_grunnlonn_pa0001.prosent_stilling` |
+| **aarsverk** | Gjelder kun MAA: `(prosent_stilling - COALESCE(prosent_stilling_fungering, 0)) × (prosent_kontering / 100) / 100` |
+| **aarsverk_eks_permisjon** | Som over, men multiplisert med `(prosent_arbeidsfor / 100)` |
+| **aarsverk_dbh** | Som over, men multiplisert med `(prosent_arbeidsfor_dbh / 100)` |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Bygger konsistente datointervaller ved å:
+- samle alle start-/sluttdatoer fra ~10 Layer 10-tabeller
+- identifisere datobrudd
+- generere nye intervaller når attributter endrer seg
+
+Gir én rad per ansatt/stilling per konsistent periode.
+
+### 2. Årsverksberegning
+Gjelder **kun** månedslønnede (`avlonningsform_kode = 'MAA'`):
+
+- **aarsverk:**
+ `(prosent_stilling - fungering) × kostnadsfordeling / 100`
+- **aarsverk_eks_permisjon:**
+ `(prosent_stilling - fungering) × kostnadsfordeling × arbeidsforhold_permisjon / 100`
+- **aarsverk_dbh:**
+ `… × arbeidsforhold_dbh / 100`
+
+Andre avlønningsformer → `0`.
+
+### 3. Aldersberegning
+Kontrollerer datokvalitet og beregner alder i tre scenarier:
+
+**Historiske rader (dato_til < dagens dato)**
+`alder = DATEDIFF(year, dato_fodt, LEAST(GETDATE(), dato_til))`
+
+**Aktive rader (dato_fra ≤ dagens dato ≤ dato_til)**
+`alder = DATEDIFF(year, dato_fodt, GETDATE())`
+
+**Fremtidige rader (dato_fra > dagens dato)**
+`alder = DATEDIFF(year, dato_fodt, dato_fra)`
+
+Feilaktige/ugyldige fødselsdatoer → `-1`.
+
+### 4. Åremål-identifisering
+- `medarbeidergruppe_kode = '3'` → Åremål = **Ja**
+- Alle andre → **Nei**
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_20_stillinger_pa0509.md b/docs/ap/hr/transformasjoner/sap_20_stillinger_pa0509.md
new file mode 100644
index 000000000..38faf8927
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_20_stillinger_pa0509.md
@@ -0,0 +1,83 @@
+# sap_20_stillinger_pa0509
+
+## Formål
+- Sammenstiller informasjon og historikk for **tilleggsstillinger og fungeringer** registrert i PA0509.
+- Inkluderer data om lønn, kontering, permisjon, alder, ansiennitet og arbeidsprosent.
+
+## Datakilder (lag 10)
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_stillinger_pa0509** | Sammenstilt informasjon relatert til stillinger i PA0509 fra silver | Ingen |
+| **sap_10_fodselsdager** | Fødselsdatoer | Ingen |
+| **sap_10_fravaer_permisjon** | Fravær/permisjon | Ingen |
+| **sap_10_fravaer_dbh** | DBH-fravær | Ingen |
+| **sap_10_kontering_pa0001_pa0509** | Kostnadsfordeling | Kun rader *uten* overstyrt kontering |
+| **sap_10_kontering_overstyrt_pa0509** | Overstyrt kostnadsfordeling | Kun rader *med* overstyrt kontering |
+| **sap_10_lonn_pa0509** | Lønn for tilleggsstillinger | Ingen |
+| **sap_10_personer** | Personinformasjon | Ingen |
+| **sap_10_organisasjonsenheter** | Organisasjonsstruktur (nivå 0–10) | Join på `organisasjon_id_nivaa_10` |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **dato_terminslutt** | Hvis `aarsak_kode = 'MP'` (tilleggsstilling) → terminslutt med `terminslutt_kode = '66'`. Hvis `aarsak_kode = 'AC'` (fungering) → terminslutt med `terminslutt_kode = '20'`. Faller tilbake til `1900-01-01` hvis ingen treff. |
+| **dato_fratredelse** | `COALESCE(person.dato_fratredelse, '1900-01-01')` – brukes som teknisk "ingen fratredelse". |
+| **koststed_kontering_kode** | `COALESCE(kontering.koststed_kode, kontering_overstyrt.koststed_kode)` – prioriteter standard kontering, ellers overstyrt. |
+| **delprosjekt_nummer** | `COALESCE(kontering.delprosjekt_nummer, kontering_overstyrt.delprosjekt_nummer)` |
+| **arbeidspakke_bygg_nummer** | `COALESCE(kontering.arbeidspakke_bygg_nummer, kontering_overstyrt.arbeidspakke_bygg_nummer)` |
+| **koststed_hoved_kode** | Hentes fra `sap_10_organisasjonsenheter.koststed_hoved_kode_nivaa_10` basert på organisasjon_id. |
+| **styrk_kode** | Hardkodet til `'-1'` (STYRK registreres ikke for PA0509-stillinger). |
+| **aaremaal** | `CASE WHEN medarbeidergruppe_kode = '3' THEN 'Ja' WHEN medarbeidergruppe_kode IS NULL THEN 'Ukjent' ELSE 'Nei' END` |
+| **prosent_arbeid** | Hentet fra `sap_10_personer.prosent_arbeid` (basert på PA0007). |
+| **alder** | Validerer fødselsdato fra `sap_10_personer`. Ugyldig (1900-01-01 eller under 16/over 110 år) → `-1`. Ellers: framtidige rader bruker `dato_fra`, historiske/aktive rader bruker `LEAST(GETDATE(), dato_til)`. |
+| **prosent_stilling** | Hentet fra `sap_10_lonn_pa0509.prosent_stilling`. |
+| **prosent_kontering** | `COALESCE(kontering.prosent_kontering, kontering_overstyrt.prosent_kontering * 100, 100.00)` – standard kontering først, ellers overstyrt (skalert til prosent), ellers 100%. |
+| **aarsverk** | `prosent_stilling × (prosent_kontering / 100) / 100`. Resultat castes til `decimal(4,3)`. |
+| **aarsverk_eks_permisjon** | Samme logikk som `aarsverk`, men multiplisert med `(COALESCE(fravaer_permisjon.prosent_arbeidsfor, 100.00) / 100.00)`. |
+| **aarsverk_dbh** | Samme logikk som `aarsverk`, men multiplisert med `(COALESCE(fravaer_dbh.prosent_arbeidsfor, 100.00) / 100.00)`. |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Bygger konsistente datointervaller for hver ansatt og tilleggsstilling ved å:
+- hente start-/sluttdatoer fra `EndeligeDatointervaller` (samlet fra alle relevante Layer 10-tabeller)
+- identifisere datobrudd når attributter endrer seg
+- generere nye intervaller som sikrer stabil informasjon per periode
+
+Resultatet er én rad per ansatt/stilling per konsistent periode.
+
+### 2. Korrigering av sluttdatoer for midlertidige ansatte
+- Terminslutt (fra `sap_10_terminslutt`) brukes for å sette `dato_terminslutt` for:
+ - tilleggsstillinger (`terminslutt_kode = '66'`, `aarsak_kode = 'MP'`)
+ - fungeringer (`terminslutt_kode = '20'`, `aarsak_kode = 'AC'`)
+- Hvis ingen terminslutt finnes i intervallet, settes teknisk verdi til `1900-01-01`.
+
+### 3. Tilleggsstillingstype
+Fastsettes ut fra:
+- saksbehandling i **PA0000** (`90`/`95`)
+- lønnart-navn (dekodet via T512T)
+
+Gir verdier som **TILL**, **FUNG**, **STEDF**, eller `-1`.
+
+### 4. Årsverksberegning
+Følger samme prinsipp som for hovedstillinger, men med PA0509-prosentene:
+
+**Formler:**
+- **aarsverk:**
+ `prosent_stilling × (prosent_kontering / 100) / 100`
+- **aarsverk_eks_permisjon:**
+ `… × (prosent_arbeidsfor / 100)`
+- **aarsverk_dbh:**
+ `… × (prosent_arbeidsfor_dbh / 100)`
+
+### 5. Person- og utdanningsinformasjon
+- Hentes fra `sap_10_personer` (dato_ansettelse, dato_fratredelse, kjønn, landkoder, språk, prosent_arbeid)
+- Utdanningskode fra `sap_00_pa0022` (utdanningstype 01, sekvens 000) hvis denne koblingen tas inn i senere versjon.
+
+### 6. Lønn og kontering
+- Lønn: `sap_10_lonn_pa0509` (grunnlønn, lønnstrinn, prosent_stilling, endring_aarsak_lonn_kode/tekst)
+- Kontering:
+ - Standard: `sap_10_kontering_pa0001_pa0509` (`kostnadstype_fordeling_kode = '01'`, ikke overstyrt)
+ - Overstyrt: `sap_10_kontering_overstyrt_pa0509` (kun der `overstyrt_kontering = 'X'`)
+
+`COALESCE`-logikk sikrer at enten standard eller overstyrt kontering brukes, med default 100% dersom ingen kontering finnes.
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_20_stillinger_pa9024.md b/docs/ap/hr/transformasjoner/sap_20_stillinger_pa9024.md
new file mode 100644
index 000000000..0bccaf5cf
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_20_stillinger_pa9024.md
@@ -0,0 +1,79 @@
+# sap_20_stillinger_pa9024
+
+## Formål
+- Sammenstiller informasjon relatert til stillinger og kontrakter i PA9024 fra 10-tabellene til én tabell.
+- Inneholder data om kontraktstype, lønn, kontering, organisasjon, ansiennitet, alder og diverse land-/personattributter.
+
+## Datakilder (Layer 10)
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_stillinger_pa9024** | Grunnlagstabell for PA9024-kontrakter, definerer datointervaller (dato_fra/dato_til) | |
+| **sap_10_lonn_pa9024** | Lønn for PA9024-kontrakter (grunnlønn, kronetillegg, prosent_stilling, lønnstrinn) | Ingen |
+| **sap_10_kontering_pa9024** | Kostnadsfordeling for PA9024-kontrakter (koststed, delprosjekt, arbeidspakke, prosent_kontering) | Ingen |
+| **sap_10_personer** | Personinformasjon ( dato_fratredelse, demografi, landkoder, prosent_arbeid, dato_fodt) | Ingen |
+| **sap_10_fodselsdager** | Fødselsdager – brukes til å skape datobrudd for korrekt aldersberegning innenfor kontraktsperioder | Ingen |
+| **sap_10_organisasjonsenheter** | Organisasjonsstruktur (nivå 0–10) – brukes for å skape datobrudd ved organisasjonsendringer | Join på `organisasjon_id_nivaa_10` mot `organisasjon_id` i stilling |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **dato_fratredelse** | `COALESCE(person.dato_fratredelse, '1900-01-01')` – teknisk “ingen fratredelse” når NULL. |
+| **koststed_kontering_kode** | Direkte fra `sap_10_kontering_pa9024.koststed_kode`. |
+| **delprosjekt_nummer** | Direkte fra `sap_10_kontering_pa9024.delprosjekt_nummer`. |
+| **arbeidspakke_bygg_nummer** | Direkte fra `sap_10_kontering_pa9024.arbeidspakke_bygg_nummer`. |
+| **styrk_kode** | Hardkodet til `'-1'` (ingen STYRK fra HRP1051 i denne tabellen). |
+| **aaremaal** | `CASE WHEN medarbeidergruppe_kode = '3' THEN 'Ja' WHEN medarbeidergruppe_kode = '-1' THEN 'Ukjent' ELSE 'Nei' END`. |
+| **prosent_arbeid** | Hentet fra `sap_10_personer.prosent_arbeid` (basert på PA0007). |
+| **alder** | Validerer dato_fodt fra `sap_10_personer`. Ugyldig (dato_fodt = 1900-01-01 eller alder < 16 / > 110 år) → `-1`. Ellers: framtidige rader bruker `dato_fra`; historiske og aktive rader bruker `LEAST(GETDATE(), dato_til)`. |
+| **prosent_stilling** | Hentet fra `sap_10_lonn_pa9024.prosent_stilling`. |
+| **prosent_kontering** | Direkte fra `sap_10_kontering_pa9024.prosent_kontering` (ingen fallbackverdi i denne tabellen). |
+| **belop_grunnlonn** | Hentet fra `sap_10_lonn_pa9024.belop_grunnlonn`. |
+| **belop_kronetillegg** | Hentet fra `sap_10_lonn_pa9024.belop_kronetillegg`. |
+
+## Transformasjonslogikk
+
+### 1. Datointervallgenerering
+Kombinerer historikk fra følgende tabeller:
+- **Hovedtabell:** PA0014 (filtrert på 82 utvalgte lønnarter) definerer gyldige datointervaller per ansatt
+- **Sekundærtabeller:** Ingen
+- **Nøkkelkolonner:** ansatt_nummer
+
+### 2. Sammenstilling av kontraktsdata
+EndeligeDatointervaller joines mot:
+
+- **sap_10_stillinger_pa9024** (`t`) – kontrakts- og stillingsattributter (type_kontrakt_t_kode, type_stilling_kode, lovhjemmel, medarbeidergruppe, medarbeiderundergruppe, organisasjon, lønnsavregningsgruppe, yrkeskode, ekstraerverv m.m.).
+- **sap_10_lonn_pa9024** (`lonn`) – lønn, prosent_stilling, lønnstrinn, grunnlønn, kronetillegg.
+- **sap_10_kontering_pa9024** (`kontering`) – koststed, delprosjekt, arbeidspakke, prosent_kontering.
+- **sap_10_personer** (`person`) – persondata, landkoder, språk, dato_fratredelse, prosent_arbeid, dato_fodt.
+
+Joins skjer alltid på overlappende dato-intervaller (tabellens `dato_fra`/`dato_til` mot interallene fra EndeligeDatointervaller).
+
+### 3. Aldersberegning
+Alder beregnes med robust logikk:
+
+- Først sjekkes datokvalitet:
+ - `dato_fodt = '1900-01-01'` → ugyldig
+ - Alder < 16 eller > 110 år (målt mot `LEAST(GETDATE(), dato_til)`) → ugyldig
+ → settes da til `-1`.
+
+- Hvis raden er **fremtidig** (dvs. `dato_fra` > dagens dato):
+ `alder = DATEDIFF(year, dato_fodt, dato_fra)`
+
+- Ellers (historiske og aktive rader):
+ `alder = DATEDIFF(year, dato_fodt, LEAST(GETDATE(), dato_til))`
+
+Dette gir korrekt alder på hvert intervall uten å bruke fødselsdags-tabellen direkte i denne SELECTen (den brukes kun til datobrudd).
+
+### 4. Åremål-identifisering
+`aaremaal` settes basert på medarbeidergruppe:
+
+- `medarbeidergruppe_kode = '3'` → **Ja** (åremål)
+- `medarbeidergruppe_kode = '-1'` → **Ukjent**
+- Andre verdier → **Nei**
+
+### 5. Konterings- og lønnsinformasjon
+- Kontering (koststed, delprosjekt, arbeidspakke, prosent_kontering) hentes fra **sap_10_kontering_pa9024** per kontrakt.
+- Lønn:
+ - `prosent_stilling`, `lonnstrinn_stigetrinn`, `belop_grunnlonn`, `belop_kronetillegg` hentes fra **sap_10_lonn_pa9024**.
+
+Ingen årsverksberegning gjøres i denne tabellen fordi alle kontrakter i PA9024 med overlapp er timekontrakter.
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_arbeidsflytbrukere.md b/docs/ap/hr/transformasjoner/sap_30_arbeidsflytbrukere.md
new file mode 100644
index 000000000..76a18a6db
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_arbeidsflytbrukere.md
@@ -0,0 +1,78 @@
+# sap_30_arbeidsflytbrukere
+
+## Formål
+- Vise hvilke brukere som er en del av arbeidsflyten i hver organisasjonsenhet.
+- Danner grunnlaget for **fak_arbeidsflytbrukere** i tjeneste 2.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **HRP1001** | Relasjoner mellom organisasjonsenheter og brukere (arbeidsflyt) | `objekttype_kode = 'O'`, `relasjon_objekttype_kode = 'US'`, `relasjonstype_kode = 'ZWF'` |
+| **HRP1000** | Organisasjonsenheter (navn og gyldighet) | `objekttype_kode = 'O'`, kun rader hvor `GETDATE()` ligger mellom `dato_fra` og `dato_til` |
+| **PA0105** | Kommunikasjonsinformasjon (brukernavn) | `kommunikasjonstype_kode = '0001'` (DFØ-brukernavn) |
+| **PA0002** | Persondata (navn m.m.) | Ingen (seneste rad per ansatt) |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **organisasjon_id** | `t.objekt_id` fra HRP1001 (organisasjonsenhet) |
+| **organisasjon_navn** | Hentes fra HRP1000 (`navn`) for `objekt_id`, seneste rad (`ROW_NUMBER() = 1`) |
+| **brukernavn_dfo** | `t.relasjon_objekt_id` fra HRP1001, kobles mot `PA0105.kommunikasjon_id` med `kommunikasjonstype_kode = '0001'` |
+| **ansatt_nummer** | Hentes fra PA0105 (seneste rad per ansatt og kommunikasjonstype, `ROW_NUMBER() = 1`) |
+| **fullt_navn** | Hentes fra PA0002 (seneste rad per ansatt, `ROW_NUMBER() = 1`) |
+| **dato_fra / dato_til** | Kopieres direkte fra HRP1001 for relasjonen mellom org-enhet og bruker |
+| **zx-kolonner** | `zx_institusjonskode`, `zx_tidspunkt_lastet`, `zx_tidspunkt_bronze`, `zx_tidspunkt_silver` kopieres fra HRP1001 |
+
+## Transformasjonslogikk
+
+### 1. Brukernavn (PA0105)
+CTE **brukernavn**:
+- Filtrerer PA0105 til `kommunikasjonstype_kode = '0001'` (DFØ-brukernavn).
+- Bruker `ROW_NUMBER() OVER (PARTITION BY zx_institusjonskode, ansatt_nummer, kommunikasjonstype_kode ORDER BY dato_til DESC)` for å finne **siste registrerte** brukernavn per ansatt.
+- Kun rader med `rn = 1` brukes videre.
+
+### 2. Personer (PA0002)
+CTE **personer**:
+- Leser PA0002 (persondata).
+- Bruker `ROW_NUMBER() OVER (PARTITION BY zx_institusjonskode, ansatt_nummer ORDER BY dato_til DESC)` for å hente **siste rad** per ansatt.
+- Kun rader med `rn = 1` beholdes.
+- Leverer bl.a. `ansatt_nummer` og `fullt_navn`.
+
+### 3. Organisasjonsenheter (HRP1000)
+CTE **organisasjonsenheter**:
+- Filtrerer HRP1000 til organisasjonsenheter (`objekttype_kode = 'O'`).
+- Begrenser til **aktive** org-enheter: `GETDATE() BETWEEN dato_fra AND dato_til`.
+- Bruker `ROW_NUMBER() OVER (PARTITION BY zx_institusjonskode, objekt_id ORDER BY dato_til DESC)` for å hente siste gyldige rad per org-enhet.
+- Kun rader med `rn = 1` inngår i sluttresultatet.
+- Leverer bl.a. `objekt_id` (org-id) og `navn` (org-navn).
+
+### 4. Arbeidsflytbrukere (HRP1001 + joins)
+Endelig SELECT:
+
+- Starter fra **HRP1001** (`t`):
+ - `objekttype_kode = 'O'` (organisasjonsenhet)
+ - `relasjon_objekttype_kode = 'US'` (bruker)
+ - `relasjonstype_kode = 'ZWF'` (arbeidsflyt-relasjon)
+
+- INNER JOIN mot **organisasjonsenheter**:
+ - `organisasjonsenheter.objekt_id = t.objekt_id`
+ - `organisasjonsenheter.rn = 1`
+ - Sikrer at kun aktive organisasjonsenheter med siste navn tas med.
+
+- LEFT JOIN mot **brukernavn**:
+ - `brukernavn.kommunikasjon_id = t.relasjon_objekt_id`
+ - `brukernavn.rn = 1`
+ - Oversetter HRP1001-bruker (US-objekt) til ansatt_nummer via DFØ-brukernavn.
+
+- LEFT JOIN mot **personer**:
+ - `personer.ansatt_nummer = brukernavn.ansatt_nummer`
+ - `personer.rn = 1`
+ - Henter `fullt_navn` og sikrer at kun siste personoppføring brukes.
+
+Resultatet er én rad per **organisasjonsenhet × arbeidsflytbruker**, med:
+- organisasjon_id og organisasjon_navn
+- brukernavn_dfo
+- ansatt_nummer
+- fullt_navn
+- gyldighetsperiode (`dato_fra` / `dato_til`) for arbeidsflytrelasjonen
+- zx-metadata fra HRP1001
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_fravaer.md b/docs/ap/hr/transformasjoner/sap_30_fravaer.md
new file mode 100644
index 000000000..e4fc57470
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_fravaer.md
@@ -0,0 +1,66 @@
+# sap_30_fravaer
+
+## Formål
+- Etablere faktatabellen **fak_fravaer**, som viser fravær på datonivå og er koblet til korrekt stillingsinformasjon.
+- Sikre korrekt dimensjonstilknytning ved å bryte ned fraværsintervaller til én rad per dato.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_fravaer** | Grunnlagstabell for fravær | `dato_til >= '2014-01-01'` |
+| **dim_dato** | Gir én rad per dag for nedbrytning av intervaller | `dato BETWEEN dato_fra AND dato_til` |
+| **sap_30_stillinger** | Stillingsinformasjon på stillingsnivå | Aggregert fra stillingsfakta |
+
+## Behandling
+
+### 1. Utgangspunkt: sap_10_fravaer
+- Henter fraværsintervaller med blant annet:
+ - `fravaerstype_kode`
+ - `prosent_fravaer`
+ - `prosent_arbeidsfor`
+ - `dato_fra`, `dato_til`
+
+### 2. Nedbrytning til datonivå
+- Fraværsperioder joines mot **dim_dato**.
+- For hver dag i perioden genereres én rad.
+
+### 3. Stillingsinformasjon
+- **sap_30_stillinger** grupperes til stillingsnivå (ikke konteringsnivå) ved å bruke DISTINCT.
+- Kobles på fravær ved:
+ - `ansatt_nummer`
+ - dato-overlapp mellom stillingsintervall og fraværsdato.
+
+### 4. Beregninger
+- **antall_fravaersdager** = 1 per dato.
+- **antall_fravaersdagsverk** =
+ `(prosent_stilling / 100) × (prosent_kontering / 100) × (prosent_fravaer / 100)`.
+
+### 5. Rensing
+- `delprosjekt_nummer` renses for UB/UT-prefikser med `REGEXP_REPLACE('^[A-Z]{2}', '')`.
+
+## Nøkler og dimensjonstilknytning
+| Dimensjon | Fakta-key | Dim-key | Kommentar |
+|-----------|-----------|----------|-----------|
+| dim_alder | alder | alder | Fellesdimensjon |
+| dim_fravaerskode | fravaerstype_kode | fravaerstype_kode | SAP |
+| dim_kjonn | kjonn_navn | kjonn_navn | Fellesdimensjon |
+| dim_koststed | koststed_kode | koststed_kode | Felles |
+| dim_land | land_kode_adresse | land_kode | Felles |
+| dim_medarbeidergruppe | medarbeidergruppe_kode | medarbeidergruppe_kode | SAP |
+| dim_medarbeiderundergruppe | medarbeiderundergruppe_kode | medarbeiderundergruppe_kode | SAP |
+| dim_organisasjon_sap | organisasjon_id | organisasjon_id | SAP |
+| dim_person | ansatt_nummer + dato | ansatt_nummer + dato_fra + dato_til | Fakta-dato må ligge innenfor intervallet |
+| dim_poststed | postnummer_adresse | postnummer | Felles |
+| dim_spraak | spraak_kode_kommunikasjon | spraak_kode | Felles |
+| dim_stillingskode | stillingskode | stillingskode | Felles |
+| dim_styrk_kode | styrk_kode | styrk_kode | Felles |
+| dim_tariffgruppe | tariffgruppe_kode | tariffgruppe_kode | SAP |
+| dim_tariffomraade | tariffomraade_kode | tariffomraade_kode | SAP |
+| dim_tarifftype | tarifftype_kode | tarifftype_kode | SAP |
+| dim_utdanningskode | utdanningskode | utdanningskode | Felles |
+| dim_arbeidspakke_bygg | arbeidspakke_bygg_nummer | arbeidspakke_bygg_nummer | UBW |
+| dim_delprosjekt | delprosjekt_nummer | delprosjekt_nummer | UBW |
+| dim_prosjekt | prosjekt_nummer | prosjekt_nummer | UBW (via dim_delprosjekt) |
+
+## Kommentar
+- Koblingen mot `sap_30_stillinger` må endres for å unngå avhengighet til et view på samme nivå (self-reference).
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_fravaerstyper.md b/docs/ap/hr/transformasjoner/sap_30_fravaerstyper.md
new file mode 100644
index 000000000..e4a232ba3
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_fravaerstyper.md
@@ -0,0 +1,17 @@
+# sap_30_fravaerstyper
+
+## Formål
+- Etablere dimensjonstabellen **dim_fravaerstype** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_fravaerstyper** | Grunnlagstabell for fraværstyper | Ingen |
+
+## Behandling
+- Leser alle rader direkte fra **sap_10_fravaerstyper**.
+- Ingen transformasjoner, filtrering eller berikelse.
+- Hele datasettet skrives til **sap_30_fravaerstyper** uendret, men med standard metadatafelter.
+
+## Nøkler
+- **fravaerstype_kode**
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_kontraktstyper_c.md b/docs/ap/hr/transformasjoner/sap_30_kontraktstyper_c.md
new file mode 100644
index 000000000..71100c1b7
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_kontraktstyper_c.md
@@ -0,0 +1,29 @@
+# sap_30_kontraktstyper_c
+
+## Formål
+Tilgjengeliggjøre kontraktstyper som grunnlag for **dim_kontraktstype_c** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **zeac_kontr_typ_t** | Lookup-tabell for kontraktstyper | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner – alle felter videreføres direkte fra `zeac_kontr_typ_t`.
+
+| Kolonne | Kilde / Logikk |
+|---------|----------------|
+| **kontraktstype_c_kode** | Direkte fra kilden |
+| **kontraktstype_c_navn** | Direkte fra kilden |
+| **zx_institusjonskode** | Tekniske metadata |
+| **zx_tidspunkt_lastet** | Tekniske metadata |
+| **zx_tidspunkt_bronze** | Tekniske metadata |
+| **zx_tidspunkt_silver** | Tekniske metadata |
+
+## Transformasjonslogikk
+- En direkte SELECT fra `zeac_kontr_typ_t`.
+- Ingen join, filtrering eller intervallbygging.
+- Resultatet er en ren referansetabell som brukes i dimensjonsmodellering.
+
+## Nøkler
+- **Primærnøkkel:** `kontraktstype_c_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_ledere.md b/docs/ap/hr/transformasjoner/sap_30_ledere.md
new file mode 100644
index 000000000..6ad71be57
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_ledere.md
@@ -0,0 +1,78 @@
+# sap_30_ledere
+
+## Formål
+- Vise hvem som er **leder for hver organisasjonsenhet**.
+- Danner grunnlaget for **fak_ledere** i tjeneste 2.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **HRP1001** | Relasjoner mellom organisasjonsenheter og lederstillinger | `objekttype_kode = 'O'`, `relasjon_objekttype_kode = 'S'`, `relasjonstype_kode = '012'`, `relasjonsretning_kode = 'B'` |
+| **HRP1000** | Organisasjonsenheter (navn og gyldighet) | `objekttype_kode = 'O'`, kun rader hvor `GETDATE()` ligger mellom `dato_fra` og `dato_til` |
+| **PA0001** | Stillinger (kobler stilling til ansatt) | `stilling_id` fra HRP1001, kun aktive rader (`GETDATE()` mellom `dato_fra` og `dato_til`) |
+| **PA0002** | Persondata (navn m.m.) | Ingen (seneste rad per ansatt) |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **organisasjon_id** | `t.objekt_id` fra HRP1001 (organisasjonsenhet) |
+| **organisasjon_navn** | Hentes fra HRP1000 (`navn`) for `objekt_id`, seneste gyldige rad (`ROW_NUMBER() = 1`) |
+| **stilling_id** | `t.relasjon_objekt_id` fra HRP1001 (lederstilling) |
+| **ansatt_nummer** | Hentes fra PA0001 basert på `stilling_id` og aktiv periode |
+| **fullt_navn** | Hentes fra PA0002 for `ansatt_nummer`, seneste rad (`ROW_NUMBER() = 1`) |
+| **dato_fra / dato_til** | Kopieres direkte fra HRP1001 for lederrelasjonen |
+| **zx-kolonner** | `zx_institusjonskode`, `zx_tidspunkt_lastet`, `zx_tidspunkt_bronze`, `zx_tidspunkt_silver` kopieres fra HRP1001 |
+
+## Transformasjonslogikk
+
+### 1. Personer (PA0002)
+CTE **personer**:
+- Leser PA0002 (persondata).
+- Bruker
+ `ROW_NUMBER() OVER (PARTITION BY zx_institusjonskode, ansatt_nummer ORDER BY dato_til DESC)`
+ for å hente **siste rad per ansatt**.
+- Kun `rn = 1` brukes videre.
+- Leverer bl.a. `ansatt_nummer` og `fullt_navn`.
+
+### 2. Organisasjonsenheter (HRP1000)
+CTE **organisasjonsenheter**:
+- Filtrerer HRP1000 til organisasjonsenheter (`objekttype_kode = 'O'`).
+- Begrenser til **aktive** org-enheter:
+ `GETDATE() BETWEEN dato_fra AND dato_til`.
+- Bruker
+ `ROW_NUMBER() OVER (PARTITION BY zx_institusjonskode, objekt_id ORDER BY dato_til DESC)`
+ for å hente siste gyldige rad per org-enhet.
+- Kun `rn = 1` beholdes.
+- Leverer bl.a. `objekt_id` (org-id) og `navn` (org-navn).
+
+### 3. Lederrelasjoner (HRP1001 + PA0001 + PA0002)
+Endelig SELECT:
+
+- Starter fra **HRP1001** (`t`):
+ - `objekttype_kode = 'O'` (organisasjonsenhet)
+ - `relasjon_objekttype_kode = 'S'` (stilling)
+ - `relasjonstype_kode = '012'` (lederrelasjon)
+ - `relasjonsretning_kode = 'B'` (stilling som overordnet til org-enhet)
+
+- INNER JOIN mot **organisasjonsenheter**:
+ - `organisasjonsenheter.objekt_id = t.objekt_id`
+ - `organisasjonsenheter.rn = 1`
+ - Sikrer at kun aktive organisasjonsenheter med siste navn tas med.
+
+- LEFT JOIN mot **PA0001**:
+ - `pa0001.stilling_id = t.relasjon_objekt_id`
+ - `GETDATE()` mellom `pa0001.dato_fra` og `pa0001.dato_til`
+ - Kobler leder-stilling til ansatt (`ansatt_nummer`).
+
+- LEFT JOIN mot **personer**:
+ - `personer.ansatt_nummer = pa0001.ansatt_nummer`
+ - `personer.rn = 1`
+ - Henter `fullt_navn` for lederen basert på seneste personoppføring.
+
+Resultatet er én rad per **organisasjonsenhet × leder**, med:
+- organisasjon_id og organisasjon_navn
+- stilling_id for leder
+- ansatt_nummer
+- fullt_navn
+- gyldighetsperiode (`dato_fra` / `dato_til`) for lederrelasjonen
+- zx-metadata fra HRP1001
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_lovhjemler.md b/docs/ap/hr/transformasjoner/sap_30_lovhjemler.md
new file mode 100644
index 000000000..1bf6f6b27
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_lovhjemler.md
@@ -0,0 +1,29 @@
+# sap_30_lovhjemler
+
+## Formål
+- Tilgjengeliggjøre lovhjemler som benyttes i SAP som grunnlag for **dim_lovhjemmel** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **T542T** | Lovhjemmeltekster (SAP-standard) | Begrenset til relevant landkode (`MOLGA = '20'`) i kildeuttrekket |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner – alle felter leses direkte fra T542T.
+
+| Kolonne | Kilde / Logikk |
+|---------|----------------|
+| **lovhjemmel_kode** | Direkte fra `T542T.lovhjemmel_kode` |
+| **lovhjemmel_beskrivelse** | Direkte fra `T542T.lovhjemmel_beskrivelse` |
+| **zx_institusjonskode** | Tekniske metadata fra kilden |
+| **zx_tidspunkt_lastet** | Tekniske metadata fra kilden |
+| **zx_tidspunkt_bronze** | Tekniske metadata fra kilden |
+| **zx_tidspunkt_silver** | Tekniske metadata fra kilden |
+
+## Transformasjonslogikk
+- Leser alle relevante rader fra **T542T** som gjelder for landkode `MOLGA = '20'` (Norge).
+- Ingen ytterligere filtrering, pivotering eller aggregering.
+- Resultatet er en ren referansetabell med én rad per lovhjemmelkode.
+
+## Nøkler
+- **Primærnøkkel:** `lovhjemmel_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_medarbeidergrupper.md b/docs/ap/hr/transformasjoner/sap_30_medarbeidergrupper.md
new file mode 100644
index 000000000..5029d400f
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_medarbeidergrupper.md
@@ -0,0 +1,31 @@
+# sap_30_medarbeidergrupper
+
+## Formål
+- Tilgjengeliggjøre medarbeidergrupper som grunnlag for **dim_medarbeidergruppe** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_medarbeidergrupper** | Lookup-tabell for medarbeidergrupper og BOT-definerte tilknytningsformer | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner – alle felter videreføres direkte fra `sap_10_medarbeidergrupper`.
+
+| Kolonne | Kilde / Logikk |
+|---------|----------------|
+| **medarbeidergruppe_kode** | Direkte fra kilden |
+| **medarbeidergruppe_navn** | Direkte fra kilden |
+| **tilknytningsform_kode** | BOT-mapping fra layer 10 |
+| **tilknytningsform_navn** | BOT-mapping fra layer 10 |
+| **zx_institusjonskode** | Tekniske metadata |
+| **zx_tidspunkt_lastet** | Tekniske metadata |
+| **zx_tidspunkt_bronze** | Tekniske metadata |
+| **zx_tidspunkt_silver** | Tekniske metadata |
+
+## Transformasjonslogikk
+- En direkte SELECT fra `sap_10_medarbeidergrupper`.
+- Ingen join, filtrering eller intervallbygging.
+- Resultatet er en ren referansetabell som brukes i dimensjonsmodellering.
+
+## Nøkler
+- **Primærnøkkel:** `medarbeidergruppe_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_medarbeiderundergrupper.md b/docs/ap/hr/transformasjoner/sap_30_medarbeiderundergrupper.md
new file mode 100644
index 000000000..4ce266b7b
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_medarbeiderundergrupper.md
@@ -0,0 +1,31 @@
+# sap_30_medarbeiderundergrupper
+
+## Formål
+- Tilgjengeliggjøre medarbeiderundergrupper som grunnlag for **dim_medarbeiderundergruppe** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_medarbeiderundergrupper** | Lookup-tabell for medarbeiderundergrupper og avlønningsformer | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner – alle felter videreføres direkte fra `sap_10_medarbeiderundergrupper`.
+
+| Kolonne | Kilde / Logikk |
+|---------|----------------|
+| **medarbeiderundergruppe_kode** | Direkte fra kilden |
+| **medarbeiderundergruppe_navn** | Direkte fra kilden |
+| **avlonningsform_kode** | BOT-mapping fra layer 10 |
+| **avlonningsform_navn** | BOT-mapping fra layer 10 |
+| **zx_institusjonskode** | Tekniske metadata |
+| **zx_tidspunkt_lastet** | Tekniske metadata |
+| **zx_tidspunkt_bronze** | Tekniske metadata |
+| **zx_tidspunkt_silver** | Tekniske metadata |
+
+## Transformasjonslogikk
+- En direkte SELECT fra `sap_10_medarbeiderundergrupper`.
+- Ingen join, filtrering eller intervallbygging.
+- Resultatet er en ren referansetabell som brukes i dimensjonsmodellering.
+
+## Nøkler
+- **Primærnøkkel:** `medarbeiderundergruppe_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_organisasjonsenheter.md b/docs/ap/hr/transformasjoner/sap_30_organisasjonsenheter.md
new file mode 100644
index 000000000..b31be26fa
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_organisasjonsenheter.md
@@ -0,0 +1,25 @@
+# sap_30_organisasjonsenheter
+
+## Formål
+- Tilgjengeliggjøre organisasjonsenheter som grunnlag for **dim_organisasjon_sap** i Analyseplattformen.
+- Berike med flagg for aktiv rad basert på gjeldende dato.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_organisasjonsenheter** | Komplett organisasjonshierarki med nivåer, ledere, DBH-koder og koststeder | Ingen |
+
+## Kalkulerte kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **zx_aktiv_rad** | `CASE WHEN dato_fra ≤ current_date AND dato_til ≥ current_date THEN 'Ja' ELSE 'Nei' END` – indikerer om raden er aktiv i dag |
+
+Alle øvrige kolonner videreføres direkte fra `sap_10_organisasjonsenheter`.
+
+## Transformasjonslogikk
+- En ren SELECT og overskriving av tabellen i transformation-laget.
+- Setter flagg for om raden er aktiv basert på sammenligning av `dato_fra`/`dato_til` mot dagens dato.
+- Ingen join, filtrering eller datointervallgenerering — strukturen fra Layer 10 beholdes uendret.
+
+## Nøkler
+- **Primærnøkkel:** `organisasjon_id_nivaa_10`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_personaldelomraader.md b/docs/ap/hr/transformasjoner/sap_30_personaldelomraader.md
new file mode 100644
index 000000000..aa68871d8
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_personaldelomraader.md
@@ -0,0 +1,21 @@
+# sap_30_personaldelomraader
+
+## Formål
+- Etablere transformasjonstabell **sap_30_personaldelomraader** som danner grunnlaget for dim_personaldelomraade i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **t001p** | Personaldelområde-data | `molga = 20` (filtrert til silver) |
+| **t5v0p** | Bedriftsnummer-kobling | Kobles på personalområde og personaldelområde |
+| **t5v2g** | Organisasjonsnummer og AGA-sone | Aggregert til siste gyldige rad per bedrift |
+| **t5v2l** | Bedriftsnavn | Kobles på bedriftsnummer |
+
+## Behandling
+1. Henter data fra t001p knyttet til MOLGA = 20 (Norge).
+2. Kobler med t5v0p for å få bedriftsnummer.
+3. Kobler med t5v2g for å få organisasjonsnummer og AGA-sone (kun siste gyldige rad per bedrift).
+4. Kobler med t5v2l for å få bedriftsnavn.
+
+## Nøkler
+- **personaldelomraade_kode**
diff --git a/docs/ap/hr/transformasjoner/sap_30_personer.md b/docs/ap/hr/transformasjoner/sap_30_personer.md
new file mode 100644
index 000000000..b7b7dd616
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_personer.md
@@ -0,0 +1,65 @@
+# sap_30_personer
+
+## Formål
+- Tilgjengeliggjøre personhistorikk som grunnlag for **dim_person** i Analyseplattformen.
+- Berike personinformasjon med kommunikasjonsdata (brukernavn, e-post, telefon).
+- Identifisere aktive rader og slå sammen like påfølgende historikkperioder.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **sap_10_personer** | Full personhistorikk med demografi, ansettelse, statsborgerskap, språk, adresse m.m. | Ingen |
+| **sap_10_ansettelsesdato** | dato_ansettelse | Ingen |
+| **pa9024 (silver)** | Kontroll for tilstedeværelse av toakontrakter | Ingen |
+
+## Kalkulerte og avledede kolonner
+| Kolonne | Formel / Logikk |
+|---------|-----------------|
+| **zx_aktiv_rad** | `Ja` dersom:
• Raden er aktiv i dag (`dato_fra ≤ current_date ≤ dato_til`), eller
• Det er seneste rad for personen og `dato_til` er passert
Ellers `Nei` |
+| **toakontrakter_finnes** | `Ja` hvis personen har minst én PA9024-kontrakt som overlapper radens dato-intervall, ellers `Nei` |
+
+## Transformasjonslogikk
+
+### 1. Hente grunnlag fra sap_10_personer
+- Leser full historikk fra `transformation_hr.sap_10_personer`.
+- Bevarer alle opprinnelige personfelt.
+
+### 2. Berike med ansettelsedato informasjon
+- leser dato_ansettelse fra sap_10_ansettelsesdato
+
+### 3. Slå sammen like påfølgende rader
+- Bruker `merge_identical_consecutive_rows()` til å:
+ - slå sammen identiske rader som ligger **rett etter hverandre**,
+ - bevare separate perioder dersom like rader er avbrutt av andre perioder.
+
+### 4. Legge på aktiv-rad-flagg
+Regler:
+
+1. **Aktiv i dag:**
+ `dato_fra ≤ current_date ≤ dato_til` → `Ja`
+
+2. **Siste historiske rad:**
+ Hvis raden er siste rad (row_number = 1) og `dato_til < current_date` → `Ja`
+
+3. **Ellers:**
+ `Nei`
+
+### 5. Identifisere toakontrakter
+- Left join mot `silver_sap.pa9024` på ansattnummer og overlappende datoer.
+- Beregner `toakontrakter_finnes = Ja` dersom minst én overlappende rad finnes.
+
+### 6. Kolonnerekkefølge
+- Dato-kolonner først
+- Deretter alle øvrige fagkolonner
+- Til slutt alle `zx_*`-kolonner
+
+### 7. Skrive resultattabell
+- Skrives som Delta-tabell til:
+ **`{catalog}.transformation_hr.sap_30_personer`**
+- Mode: `overwrite`
+- Schema overwrites enabled
+
+## Nøkler
+- **ansatt_nummer**
+- **dato_fra**
+- **dato_til**
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_stillinger.md b/docs/ap/hr/transformasjoner/sap_30_stillinger.md
new file mode 100644
index 000000000..abaecde54
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_stillinger.md
@@ -0,0 +1,68 @@
+# sap_30_stillinger
+
+## Formål
+- Sammenstille alle stillingsforhold for ansatte i UH-sektoren til én samlet faktatabell (**fak_stillinger**) i tjeneste 2.
+- Kombinere hovedstillinger, tilleggsstillinger og TOA-stillinger fra de tre relevante 20-viewene.
+- Harmoniserer datointervaller og fjerner nullverdier i attributter for robust dimensjonstilknytning.
+
+## Datakilder (lag 20)
+| Tabell | Rolle | Filtre |
+|--------|-------|--------|
+| **sap_20_stillinger_pa0001** | Hovedstillinger | Ingen |
+| **sap_20_stillinger_pa0509** | Tilleggsstillinger og fungeringer | Ingen |
+| **sap_20_stillinger_pa9024x** | TOA-stillinger | Ingen |
+
+## Transformasjonslogikk
+
+### 1. Kombinering av kilder
+Alle tre stillingstabeller kombineres med `UNION ALL` via `unionByName(allowMissingColumns=True)`, slik at manglende kolonner fylles med null og skjemaene håndteres fleksibelt.
+
+### 2. Håndtering av nullverdier
+Nullverdier i sentrale attributter erstattes for å:
+- sikre stabil join mot dimensjoner,
+- sikre sammenlignbar hashing av rader,
+- unngå brudd i datointervaller.
+
+Kolonner som standardiseres inkluderer bl.a.
+`ansatt_nummer`, `organisasjon_id`, `stilling_id`, `koststed_kontering_kode`, `medarbeidergruppe_kode`, `kjonn_navn`, `utdanningskode`, `yrkeskode`, mm.
+
+### 3. Rensing av delprosjekt
+Fjerner prefiks med to bokstaver (f.eks. *UT*, *UB*) fra `delprosjekt_nummer` for å speile praksis fra UBW-kildedata.
+
+### 4. Mengdeutjevning via datointervall-sammenslåing
+Like påfølgende rader (dvs. rader hvor alle kolonner utenom `dato_fra` og `dato_til` er identiske) slås sammen til ett datointervall.
+Dette gjøres ved:
+
+1. Beregning av hash for alle kolonner unntatt dato.
+2. Sammenligning av hash med hash på forrige rad innen samme ansatt/stillingsforhold.
+3. Slå sammen intervaller der hashen matcher.
+
+Resultatet er én rad per unikt stillingsforhold per konsistent periode.
+
+## Nøkler og dimensjonstilknytning
+
+| Dimensjonstabell | Business key (fakta) | Business key (dimensjon) | Kommentar |
+|------------------|-----------------------|---------------------------|-----------|
+| **dim_alder** | alder | alder | Fellesdimensjon |
+| **dim_kjonn** | kjonn_navn | kjonn_navn | Fellesdimensjon |
+| **dim_koststed** | koststed_kode | koststed_kode | Fellesdimensjon |
+| **dim_land** | land_kode_adresse | land_kode | Fellesdimensjon |
+| **dim_medarbeidergruppe** | medarbeidergruppe_kode | medarbeidergruppe_kode | SAP-dimensjon |
+| **dim_medarbeiderundergruppe** | medarbeiderundergruppe_kode | medarbeiderundergruppe_kode | SAP-dimensjon |
+| **dim_organisasjon_sap** | organisasjon_id | organisasjon_id | SAP-dimensjon |
+| **dim_person** | ansatt_nummer
dato_fra
dato_til | ansatt_nummer
dato_fra
dato_til | SAP-dimensjon (fakta‐intervall må overlappe dim‐intervall) |
+| **dim_poststed** | postnummer_adresse | postnummer | Fellesdimensjon |
+| **dim_spraak** | spraak_kommunikasjon | spraak_kode | Fellesdimensjon |
+| **dim_stillingskode** | stillingskode | stillingskode | Fellesdimensjon |
+| **dim_styrk_kode** | styrk_kode | styrk_kode | Fellesdimensjon |
+| **dim_tariffgruppe** | tariffgruppe_kode | tariffgruppe_kode | SAP-dimensjon |
+| **dim_tariffomraade** | tariffomraade_kode | tariffomraade_kode | SAP-dimensjon |
+| **dim_tarifftype** | tarifftype_kode | tarifftype_kode | SAP-dimensjon |
+| **dim_utdanningskode** | utdanningskode | utdanningskode | Fellesdimensjon |
+
+## Skriving til mål
+- Resultatet skrives til:
+ **`{catalog}.transformation_hr.sap_30_stillinger`**
+- Format: Delta
+- Mode: `overwrite`
+- Skjemautvidelser tillates (`overwriteSchema = true`)
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_stillingskoder.md b/docs/ap/hr/transformasjoner/sap_30_stillingskoder.md
new file mode 100644
index 000000000..628c2bf9b
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_stillingskoder.md
@@ -0,0 +1,26 @@
+# sap_30_stillingskoder
+
+## Formål
+- Tilgjengeliggjøre stillingskoder som grunnlag for **dim_stillingskode** i Analyseplattformen.
+- Baseres på manuelt vedlikeholdt kodeverk med utgangspunkt i DBHs stillingsregister.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **stillingskoder** (silver_sap) | Manuelt kodeverk for stillingskoder basert på DBH-register | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner – alle felter videreføres direkte fra `silver_sap.stillingskoder`.
+
+- `sap_30_stillingskoder` er per nå en 1:1-kopi av kildetabellen.
+
+## Transformasjonslogikk
+- En ren `SELECT t.*` fra `silver_sap.stillingskoder`.
+- Ingen join, filtrering, mapping eller datointervallgenerering.
+- Kommentar fra implementasjon:
+ > Inntil videre bare laget rett mot grunntabellen. Dette må endres i Databricks.
+
+Tabellen fungerer dermed som et midlertidig speil av det manuelle kodeverket inntil videre modellering/foredling etableres.
+
+## Nøkler
+- **Primærnøkkel:** `stillingskode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_tariffgrupper.md b/docs/ap/hr/transformasjoner/sap_30_tariffgrupper.md
new file mode 100644
index 000000000..9c8342df7
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_tariffgrupper.md
@@ -0,0 +1,21 @@
+# sap_30_tariffgrupper
+
+## Formål
+- Tilgjengeliggjøre tariffgrupper som grunnlag for **dim_tariffgruppe** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **pa0008** (silver_sap) | Kilde for tariffgruppe‐kode | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner.
+Tabellen inneholder kun unike rader basert på `tariffgruppe_kode`.
+
+## Transformasjonslogikk
+- Leser alle rader fra `silver_sap.pa0008`.
+- Plukker ut **DISTINCT tariffgruppe_kode** sammen med metadatafeltene.
+- Ingen join, filtrering eller videre transformasjoner.
+
+## Nøkler
+- **Primærnøkkel:** `tariffgruppe_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_tariffomraader.md b/docs/ap/hr/transformasjoner/sap_30_tariffomraader.md
new file mode 100644
index 000000000..f7e9ed3c4
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_tariffomraader.md
@@ -0,0 +1,21 @@
+# sap_30_tariffomraader
+
+## Formål
+- Tilgjengeliggjøre tariffområder som grunnlag for **dim_tariffomraade** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **t510g** (silver_sap) | Kilde for tariffområdekode og beskrivelse | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner.
+Tabellen eksponerer verdier direkte fra T510G.
+
+## Transformasjonslogikk
+- Leser alle rader fra `silver_sap.t510g`.
+- Returnerer `tariffomraade_kode`, `tariffomraade_navn` og metadatafelter.
+- Ingen join, konsolidering eller filtrering.
+
+## Nøkler
+- **Primærnøkkel:** `tariffomraade_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_tarifftyper.md b/docs/ap/hr/transformasjoner/sap_30_tarifftyper.md
new file mode 100644
index 000000000..10245b6dd
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_tarifftyper.md
@@ -0,0 +1,21 @@
+# sap_30_tarifftyper
+
+## Formål
+- Tilgjengeliggjøre tarifftyper som grunnlag for **dim_tarifftype** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **t510a** (silver_sap) | Kilde for tarifftypekode og tilhørende navn | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner.
+Alle verdier leses direkte fra T510A.
+
+## Transformasjonslogikk
+- Leser alle rader fra `silver_sap.t510a`.
+- Returnerer `tarifftype_kode`, `tarifftype_navn` og metadatafelter.
+- Ingen join, konsolidering eller filtrering.
+
+## Nøkler
+- **Primærnøkkel:** `tarifftype_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_toa_stillinger.md b/docs/ap/hr/transformasjoner/sap_30_toa_stillinger.md
new file mode 100644
index 000000000..9053ed64e
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_toa_stillinger.md
@@ -0,0 +1,29 @@
+# sap_30_toa_stillinger
+
+## Formål
+- Lage grunnlagstabell for fak_toa_stillinger i lag 30.
+- Erstatter nullverdier i attributtkolonner med APs standardverdier.
+- Fjerner prefiks med to bokstaver fra `delprosjekt_nummer` for å matche delprosjekt mot Unit4-data.
+
+## Datakilder (lag 20)
+| Tabell | Rolle | Filtre |
+|--------|-------|--------|
+| **sap_20_stillinger_pa9024** | TOA-stillinger | Ingen |
+
+## Transformasjonslogikk
+
+### 1. Håndtering av nullverdier
+Nullverdier i sentrale attributter erstattes for å:
+- sikre stabil join mot dimensjoner,
+- sikre sammenlignbar hashing av rader,
+- unngå brudd i datointervaller.
+
+### 2. Rensing av delprosjekt
+Fjerner prefiks med to bokstaver (f.eks. *UT*, *UB*) fra `delprosjekt_nummer` for å speile praksis fra Unit4.
+
+## Skriving til mål
+- Resultatet skrives til:
+ **`{catalog}.transformation_hr.sap_30_toa_stillinger`**
+- Format: Delta
+- Mode: `overwrite`
+- Skjemautvidelser tillates (`overwriteSchema = true`)
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_typer_kontrakt_t.md b/docs/ap/hr/transformasjoner/sap_30_typer_kontrakt_t.md
new file mode 100644
index 000000000..3f9ab0e09
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_typer_kontrakt_t.md
@@ -0,0 +1,29 @@
+# sap_30_typer_kontrakt_t
+
+## Formål
+Tilgjengeliggjøre kontraktstyper som grunnlag for **dim_type_kontrakt_t** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **zeac_asgn_type_t** | Lookup-tabell for kontraktstyper | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner – alle felter videreføres direkte fra `zeac_asgn_type_t`.
+
+| Kolonne | Kilde / Logikk |
+|---------|----------------|
+| **type_kontrakt_t_kode** | Direkte fra kilden |
+| **type_kontrakt_t_navn** | Direkte fra kilden |
+| **zx_institusjonskode** | Tekniske metadata |
+| **zx_tidspunkt_lastet** | Tekniske metadata |
+| **zx_tidspunkt_bronze** | Tekniske metadata |
+| **zx_tidspunkt_silver** | Tekniske metadata |
+
+## Transformasjonslogikk
+- En direkte SELECT fra `zeac_asgn_type_t`.
+- Ingen join, filtrering eller intervallbygging.
+- Resultatet er en ren referansetabell som brukes i dimensjonsmodellering.
+
+## Nøkler
+- **Primærnøkkel:** `type_kontrakt_t_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_typer_stilling.md b/docs/ap/hr/transformasjoner/sap_30_typer_stilling.md
new file mode 100644
index 000000000..a01cde7ce
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_typer_stilling.md
@@ -0,0 +1,34 @@
+# sap_30_typer_stilling
+
+## Formål
+- Tilgjengeliggjøre kodeverk for **type stilling** som grunnlag for analyser og dimensjoner i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **Hardkodet datasett** | Midlertidig kilde til type_stilling-kodeverk | Ingen (manuelt definert) |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner.
+Tabellen består av statiske, hardkodede verdier.
+
+## Transformasjonslogikk
+- Oppretter en statisk DataFrame med følgende verdier:
+
+| type_stilling_kode | type_stilling_tekst | sortering |
+|---------------------|---------------------|-----------|
+| HOVED | Hovedstilling | 1 |
+| TILL | Tilleggsstilling | 2 |
+| STEDF | Stedfortredergodtgjørelse | 3 |
+| FUNG | Fungering over 2 år | 4 |
+| XT1 | Overlappende timekontrakt TOA | 5 |
+
+- Legger på metadatafelter:
+ - `zx_institusjonskode`
+ - `zx_tidspunkt_lastet`
+ - `zx_tidspunkt_bronze`
+ - `zx_tidspunkt_silver`
+- Skriver resultatet til `transformation_hr.sap_30_typer_stilling`.
+
+## Nøkler
+- **Primærnøkkel:** `type_stilling_kode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_utdanningskoder.md b/docs/ap/hr/transformasjoner/sap_30_utdanningskoder.md
new file mode 100644
index 000000000..e8bd4d1ac
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_utdanningskoder.md
@@ -0,0 +1,23 @@
+# sap_30_utdanningskoder
+
+## Formål
+- Etablere dimensjonen **dim_utdanningskode** i Analyseplattformen.
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **T518B** | Kilde for utdanningskoder og tilhørende navn | Ingen |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner. Alle verdier hentes direkte fra SAP-tabellen T518B.
+
+## Transformasjonslogikk
+- Leser rådata om utdanningskoder fra `silver_sap.t518b`.
+- Velger relevante kolonner:
+ - `utdanningskode`
+ - `utdanningskode_navn`
+ - metadatafeltene `zx_*`
+- Skriver resultatet til `transformation_hr.sap_30_utdanningskoder`.
+
+## Nøkler
+- **Primærnøkkel:** `utdanningskode`
\ No newline at end of file
diff --git a/docs/ap/hr/transformasjoner/sap_30_yrkeskoder.md b/docs/ap/hr/transformasjoner/sap_30_yrkeskoder.md
new file mode 100644
index 000000000..d7ce695a2
--- /dev/null
+++ b/docs/ap/hr/transformasjoner/sap_30_yrkeskoder.md
@@ -0,0 +1,25 @@
+# sap_30_yrkeskoder
+
+## Formål
+- Etablere dimensjonen **dim_yrkeskode** i Analyseplattformen.
+- Tilgjengeliggjøre yrkeskoder og yrkestitler basert på norsk yrkesklassifisering (NOYK).
+
+## Datakilder
+| Tabell | Formål / Rolle | Filtre |
+|--------|----------------|--------|
+| **T710ST** | Kilde for yrkeskoder og yrkestitler | `type_kode = 'NOYK'` |
+
+## Kalkulerte kolonner
+Ingen kalkulerte kolonner. Alle verdier leses direkte fra T710ST.
+
+## Transformasjonslogikk
+- Leser SAP-yrkeskoder fra `silver_sap.T710ST`.
+- Filtrerer på `type_kode = 'NOYK'` for å kun hente relevant norsk yrkesklassifisering.
+- Velger relevante kolonner:
+ - `yrkeskode`
+ - `yrkestittel`
+ - metadatafelt (`zx_institusjonskode`, `zx_tidspunkt_*`)
+- Skriver resultattabellen til `transformation_hr.sap_30_yrkeskoder`.
+
+## Nøkler
+- **Primærnøkkel:** `yrkeskode`
\ No newline at end of file
diff --git a/docs/ap/index.md b/docs/ap/index.md
new file mode 100644
index 000000000..a1b3201a2
--- /dev/null
+++ b/docs/ap/index.md
@@ -0,0 +1,14 @@
+---
+title: Analyseplattformen
+---
+# Velkommen til Analyseplattformen
+
+Analyseplattformen skal hjelpe faglig og administrativ ledelse på alle nivåer, samt analytikere, til å se helheten på tvers av sentrale fagområder (studier, forskning, ledelse og generell administrasjon). Tjenesten er under utvikling.
+
+Vi deler data gjennom Deltasharing, og dokumentasjonen for Deltashare finnes her:
+
+[Maskin-til-maskin deling (f.eks. Python)](https://learn.microsoft.com/en-us/azure/databricks/delta-sharing/sharing-over-oidc-m2m)
+
+[Bruker-til-maskin deling (PowerBI)](https://learn.microsoft.com/en-us/azure/databricks/delta-sharing/sharing-over-oidc-u2m)
+
+Brukerdokumentasjon for rapporter i power BI er under utvikling.
\ No newline at end of file
diff --git a/docs/ap/sidebars.js b/docs/ap/sidebars.js
new file mode 100644
index 000000000..024d33c66
--- /dev/null
+++ b/docs/ap/sidebars.js
@@ -0,0 +1,46 @@
+const fs = require('fs');
+const path = require('path');
+
+const transformasjonerDir = path.join(__dirname, 'hr', 'transformasjoner');
+
+const transformasjonDocIds = fs
+ .readdirSync(transformasjonerDir)
+ .filter((file) => file.endsWith('.md'))
+ .map((file) => `ap/hr/transformasjoner/${file.replace(/\.md$/, '')}`)
+ .sort((a, b) => a.localeCompare(b, 'en', { numeric: true }));
+
+const byPrefix = (prefix) =>
+ transformasjonDocIds.filter((docId) =>
+ path.basename(docId).startsWith(`${prefix}_`),
+ );
+
+module.exports = [
+ 'ap/index',
+ {
+ type: 'category',
+ label: 'HR',
+ items: [
+ {
+ type: 'category',
+ label: 'Transformasjoner',
+ items: [
+ {
+ type: 'category',
+ label: 'sap_10',
+ items: byPrefix('sap_10'),
+ },
+ {
+ type: 'category',
+ label: 'sap_20',
+ items: byPrefix('sap_20'),
+ },
+ {
+ type: 'category',
+ label: 'sap_30',
+ items: byPrefix('sap_30'),
+ },
+ ],
+ },
+ ],
+ },
+];
diff --git a/sidebars.js b/sidebars.js
index 25d18c475..93c5abc0b 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -2,6 +2,7 @@
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
+ ap: require('./docs/ap/sidebars.js'),
iam: require('./docs/iam/sidebars.js'),
cnaas: require('./docs/cnaas/sidebars.js'),
nettadministrasjon: require('./docs/nettadministrasjon/sidebars.js'),
diff --git a/src/pages/index.js b/src/pages/index.js
index ddf85642f..d16a34ae7 100644
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -4,9 +4,12 @@ import { Topic, TopicList } from '../components/topiclist';
const topics = (
<>
+
+ Analyseplattformen leverer datavarehus og rapporteringsløsninger for virksomhetsstyring. Dokumentasjonen er under utvikling.
+
- Cybersikkerhetssenteret er sektorvist responsmiljø (SRM) for norsk forskning og høyere utdanning.
- Vi leverer en rekke sikkerhetstjenester, og er samlingspunktet for sikkerhetskompetansen i kunnskapssektoren.
+ Cybersikkerhetssenteret er sektorvist responsmiljø (SRM) for norsk forskning og høyere utdanning.
+ Vi leverer en rekke sikkerhetstjenester, og er samlingspunktet for sikkerhetskompetansen i kunnskapssektoren.
Identitets- og tilgangsstyring (IAM) handler om å gi studenter, forskere
@@ -58,7 +61,7 @@ const topics = (
Kunnskapssektorens datafellesskap (KUDAF) er en tosidig plattform som skal
gjøre det lettere for offentlige virksomheter å dele data med forskere og
andre interessenter. Dokumentasjonen er under utvikling, send en e-post til
- kontakt@sikt.no med eventuelle spørsmål eller kommentarer.
+ kontakt@sikt.no med eventuelle spørsmål eller kommentarer.
>
);