一键导入
endre-krav
Endring av eksisterende krav (endre rente og endre hovedstol): EndreKravService, request-DTOer, status-konformering og SKE API PUT-endepunkter
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Endring av eksisterende krav (endre rente og endre hovedstol): EndreKravService, request-DTOer, status-konformering og SKE API PUT-endepunkter
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Flyway-migrasjoner for PostgreSQL: navnekonvensjoner (V{n}__desc.sql), skjema for krav/feilmelding/filvalideringsfeil, DBListener-testing med TestContainers
Post-send livssyklus: StatusService poller /mottaksstatus; StoppKravService; RapportService + AvstemmingRouting-frontend for manuell reskontroføring
HOCON-basert konfigurasjon med PropertiesConfig singleton for Ktor batch-tjenester på NAIS (FSS)
SlackService feilakkumulering og Tags-basert varsling for prosesseringsfeil i SKE-batch
Kotest BehaviorSpec/MockK-mønstre for sokos-ske-krav: scenariostruktur, DBListener/SftpListener, MockHttpClient, circuit-breaker-reset og matchers
Idiomatic Kotlin: null safety, immutability, sealed types, structured concurrency, extension functions, DSL builders, Gradle Kotlin DSL
| name | endre-krav |
| description | Endring av eksisterende krav (endre rente og endre hovedstol): EndreKravService, request-DTOer, status-konformering og SKE API PUT-endepunkter |
Endring av eksisterende krav hos SKE: EndreKravService, NyHovedStolRequest, EndreRenteBeloepRequest, status-konformering og kravidentifikator-oppslag.
When a krav line has a non-empty
referansenummerGammelSakandbeløp != 0, it is classified as an "endring". Two separate DB records are created — oneENDRING_HOVEDSTOLand oneENDRING_RENTE— and two separate PUT requests are sent to SKE's API.
In CreateRequests.kt / KravLinje extensions:
fun KravLinje.isEndring() = (referansenummerGammelSak.isNotEmpty() && !isStopp())
fun KravLinje.isStopp() = (belop.toDouble().roundToLong() == 0L)
fun KravLinje.isOpprettKrav() = (!this.isEndring() && !this.isStopp())
Decision logic: referansenummerGammelSak present → endring. Beløp == 0 → stopp. Otherwise → nytt krav.
When KravRepository.insertAllNewKrav() encounters an endring line, it inserts two krav rows:
kravListe.forEach { krav ->
val type = when {
krav.isStopp() -> STOPP_KRAV
krav.isEndring() -> ENDRING_HOVEDSTOL // first record
else -> NYTT_KRAV
}
// ... insert krav with type ...
if (type == ENDRING_HOVEDSTOL) {
// insert SECOND krav with kravtype = ENDRING_RENTE (same data)
}
}
Both records share the same kravidentifikatorSKE and saksnummerNAV but have different kravtype and may have different corrId.
Input File (KravLinje with referansenummerGammelSak)
↓
KravRepository.insertAllNewKrav()
├─ Insert krav #1: kravtype = ENDRING_HOVEDSTOL
└─ Insert krav #2: kravtype = ENDRING_RENTE
↓
SkeService.sendKrav() → filter ENDRING_HOVEDSTOL | ENDRING_RENTE
↓
EndreKravService.sendAllEndreKrav()
├─ Group by: kravidentifikatorSKE + saksnummerNAV
├─ For each group:
│ ├─ sendEndreKrav(ENDRING_HOVEDSTOL) → PUT .../hovedstol
│ ├─ sendEndreKrav(ENDRING_RENTE) → PUT .../renter
│ └─ getConformedResponses() → align statuses
└─ databaseService.updateSentKrav()
kravidentifikatorSKE + saksnummerNAV before sendingcreateKravidentifikatorPair() for identifier resolutionCircuitBreakerException / CallNotPermittedExceptionbeforeEach of testscreateKravidentifikatorPair()