Repository: navikt/familie-ba-sak
Pull request #5140: Oppretter logikk og tester for oppretting av forenklet tilbakekreving vedtak
Author: login: UyQuangNguyen
Created: 2025-03-04T23:39:43Z | Merged: 2025-03-05T19:01:51Z

Favrokort: https://favro.com/organization/98c34fb974ce445eac854de0/1844bbac3b6605eacc8f5543?card=NAV-24545

Vi ønsker å ha et objekt Forenklet Tilbakekreving Vedtak (navn kan diskuteres) som skal styre om det skal sendes ut et ekstra vedtaksbrev i behandlingen. Vedtaksbrevet skal inneholde fritekst som SB har lagt inn. Objektet skal opprettes når behandlingen settes på vent grunnet motregning årsaken som opprettes i en annen favrokort.

Feltene i objektet:

- id: id på objektet
- behandlingId: id på behandlingen
- fritekst: fritekst felt som fylles først ut med standard tekst (denne kommer senere), og deretter kan justeres av SB. fritekstfeltet skal legges i vedtaksbrevet som kommer senere.
- samtykke: Sier om brukeren har samtykket. null betyr at SB ikke har hentet inn svar på samtykke enda.

I denne pullrequesten så har jeg

- Laget SQL tabell for Forenklet Tilbakekreving Vedtak 
- Laget entitets objekt og rest objekt for Forenklet Tilbakekreving Vedtak 
- Laget controller, service, og repository for Forenklet Tilbakekreving Vedtak 

Jeg har laget 4 nye endepunkter

- `GET /api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak` som returnerer objektet hvis det finnes
- `PATCH /api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak/fritekst` som oppdaterer fritekst på objektet 
- `PATCH /api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak/samtykke` som oppdaterer samtykke på objektet 
- `DELETE /api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak` som sletter objektet hvis det finnes.

Siden dette objektet bare brukes på simulering siden i frontend så velger jeg å ikke bake det inn i UtvidetBehandlingRespons.

Samtykke og fritekst oppdateres på forskjellige tidspunkt, som er derfor jeg har valgt å ha separat endepunkter for å endre på dem istedenfor å lage en PUT endepunkt. 
Jeg har også forsøkt meg på en litt mer RESTful approach for endepunktene vs det som finnes i ba-sak i dag. Tilbakemelding mottas gjerne!



Diff:
diff --git a/src/main/kotlin/no/nav/familie/ba/sak/ekstern/restDomene/RestForenkletTilbakekrevingVedtak.kt b/src/main/kotlin/no/nav/familie/ba/sak/ekstern/restDomene/RestForenkletTilbakekrevingVedtak.kt
new file mode 100644
index 00000000000..0ceab5fe4c4
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/ba/sak/ekstern/restDomene/RestForenkletTilbakekrevingVedtak.kt
@@ -0,0 +1,16 @@
+package no.nav.familie.ba.sak.ekstern.restDomene
+
+data class RestForenkletTilbakekrevingsvedtak(
+    val id: Long,
+    val behandlingId: Long,
+    val fritekst: String,
+    val samtykke: Boolean,
+)
+
+data class RestOppdaterForenkletTilbakekrevingsvedtakFritekst(
+    val fritekst: String,
+)
+
+data class RestOppdaterForenkletTilbakekrevingsvedtakSamtykke(
+    val samtykke: Boolean,
+)
diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/Logg.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/Logg.kt
index d7099b5ff33..1249d7e621d 100644
--- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/Logg.kt
+++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/Logg.kt
@@ -96,4 +96,8 @@ enum class LoggType(
     SAMMENSATT_KONTROLLSAK_LAGT_TIL("Sammensatt kontrollsak lagt til"),
     SAMMENSATT_KONTROLLSAK_ENDRET("Sammensatt kontrollsak endret"),
     SAMMENSATT_KONTROLLSAK_FJERNET("Sammensatt kontrollsak fjernet"),
+    FORENKLET_TILBAKEKREVINGSVEDTAK_OPPRETTET("Forenklet tilbakekrevingsvedtak opprettet"),
+    FORENKLET_TILBAKEKREVINGSVEDTAK_OPPDATERT_FRITEKST("Forenklet tilbakekrevingsvedtak fritekst oppdatert"),
+    FORENKLET_TILBAKEKREVINGSVEDTAK_OPPDATERT_SAMTYKKE("Forenklet tilbakekrevingsvedtak samtykke oppdatert"),
+    FORENKLET_TILBAKEKREVINGSVEDTAK_SLETTET("Forenklet tilbakekrevingsvedtak fjernet"),
 }
diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/LoggService.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/LoggService.kt
index 5a9306a1671..46228bccc9e 100644
--- a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/LoggService.kt
+++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/LoggService.kt
@@ -737,6 +737,58 @@ class LoggService(
         ),
     )
 
+    fun loggForenkletTilbakekrevingsvedtakOpprettet(behandlingId: Long) =
+        lagre(
+            Logg(
+                behandlingId = behandlingId,
+                type = LoggType.FORENKLET_TILBAKEKREVINGSVEDTAK_OPPRETTET,
+                rolle =
+                    SikkerhetContext.hentRolletilgangFraSikkerhetscontext(
+                        rolleConfig,
+                        BehandlerRolle.SAKSBEHANDLER,
+                    ),
+            ),
+        )
+
+    fun loggForenkletTilbakekrevingsvedtakOppdatertSamtykke(behandlingId: Long) =
+        lagre(
+            Logg(
+                behandlingId = behandlingId,
+                type = LoggType.FORENKLET_TILBAKEKREVINGSVEDTAK_OPPDATERT_SAMTYKKE,
+                rolle =
+                    SikkerhetContext.hentRolletilgangFraSikkerhetscontext(
+                        rolleConfig,
+                        BehandlerRolle.SAKSBEHANDLER,
+                    ),
+            ),
+        )
+
+    fun loggForenkletTilbakekrevingsvedtakOppdatertFritekst(behandlingId: Long) =
+        lagre(
+            Logg(
+                behandlingId = behandlingId,
+                type = LoggType.FORENKLET_TILBAKEKREVINGSVEDTAK_OPPDATERT_FRITEKST,
+                rolle =
+                    SikkerhetContext.hentRolletilgangFraSikkerhetscontext(
+                        rolleConfig,
+                        BehandlerRolle.SAKSBEHANDLER,
+                    ),
+            ),
+        )
+
+    fun loggForenkletTilbakekrevingsvedtakSlettet(behandlingId: Long) =
+        lagre(
+            Logg(
+                behandlingId = behandlingId,
+                type = LoggType.FORENKLET_TILBAKEKREVINGSVEDTAK_SLETTET,
+                rolle =
+                    SikkerhetContext.hentRolletilgangFraSikkerhetscontext(
+                        rolleConfig,
+                        BehandlerRolle.SAKSBEHANDLER,
+                    ),
+            ),
+        )
+
     fun lagre(logg: Logg): Logg {
         metrikkPerLoggType[logg.type]?.increment()
 
diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtak.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtak.kt
new file mode 100644
index 00000000000..7a773f3e3f4
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtak.kt
@@ -0,0 +1,41 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingsvedtak
+
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.EntityListeners
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.SequenceGenerator
+import jakarta.persistence.Table
+import no.nav.familie.ba.sak.common.BaseEntitet
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingsvedtak
+import no.nav.familie.ba.sak.sikkerhet.RollestyringMotDatabase
+
+@EntityListeners(RollestyringMotDatabase::class)
+@Entity(name = "ForenkletTilbakekrevingsvedtak")
+@Table(name = "forenklet_tilbakekrevingsvedtak")
+data class ForenkletTilbakekrevingsvedtak(
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "forenklet_tilbakekrevingsvedtak_seq_generator")
+    @SequenceGenerator(
+        name = "forenklet_tilbakekrevingsvedtak_seq_generator",
+        sequenceName = "forenklet_tilbakekrevingsvedtak_seq",
+        allocationSize = 50,
+    )
+    val id: Long = 0,
+    @Column(name = "fk_behandling_id", updatable = false, nullable = false)
+    val behandlingId: Long,
+    @Column(name = "samtykke", nullable = false, updatable = true)
+    var samtykke: Boolean,
+    @Column(name = "fritekst", nullable = false, updatable = true)
+    var fritekst: String,
+) : BaseEntitet()
+
+fun ForenkletTilbakekrevingsvedtak.tilRestForenkletTilbakekrevingsvedtak() =
+    RestForenkletTilbakekrevingsvedtak(
+        id = this.id,
+        behandlingId = this.behandlingId,
+        samtykke = this.samtykke,
+        fritekst = this.fritekst,
+    )
diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakController.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakController.kt
new file mode 100644
index 00000000000..5f851741f73
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakController.kt
@@ -0,0 +1,100 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingsvedtak
+
+import no.nav.familie.ba.sak.config.BehandlerRolle
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingsvedtak
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingsvedtakFritekst
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingsvedtakSamtykke
+import no.nav.familie.ba.sak.sikkerhet.TilgangService
+import no.nav.familie.kontrakter.felles.Ressurs
+import no.nav.security.token.support.core.api.ProtectedWithClaims
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.validation.annotation.Validated
+import org.springframework.web.bind.annotation.DeleteMapping
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PatchMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/behandling/{behandlingId}/forenklet-tilbakekrevingsvedtak")
+@ProtectedWithClaims(issuer = "azuread")
+@Validated
+class ForenkletTilbakekrevingsvedtakController(
+    val tilgangService: TilgangService,
+    val forenkletTilbakekrevingsvedtakService: ForenkletTilbakekrevingsvedtakService,
+) {
+    @GetMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+    )
+    fun hentForenkletTilbakekrevingsvedtak(
+        @PathVariable behandlingId: Long,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingsvedtak?>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Hent ForenkletTilbakekrevingsvedtak",
+        )
+        val forenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.finnForenkletTilbakekrevingsvedtak(behandlingId = behandlingId)
+
+        return ResponseEntity.ok(Ressurs.success(forenkletTilbakekrevingsvedtak?.tilRestForenkletTilbakekrevingsvedtak()))
+    }
+
+    @PatchMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+        path = ["/fritekst"],
+    )
+    fun oppdaterFritekstPåForenkletTilbakekrevingsvedtak(
+        @PathVariable behandlingId: Long,
+        @RequestBody restOppdaterForenkletTilbakekrevingsvedtakFritekst: RestOppdaterForenkletTilbakekrevingsvedtakFritekst,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingsvedtak>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Oppdater fritekst på forenklet tilbakekrevingsvedtak",
+        )
+        tilgangService.validerKanRedigereBehandling(behandlingId)
+
+        val oppdatertForenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.oppdaterFritekstPåForenkletTilbakekrevingsvedtak(behandlingId, restOppdaterForenkletTilbakekrevingsvedtakFritekst.fritekst)
+
+        return ResponseEntity.ok(Ressurs.success(oppdatertForenkletTilbakekrevingsvedtak.tilRestForenkletTilbakekrevingsvedtak()))
+    }
+
+    @PatchMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+        path = ["/samtykke"],
+    )
+    fun oppdaterSamtykkePåForenkletTilbakekrevingsvedtak(
+        @PathVariable behandlingId: Long,
+        @RequestBody restOppdaterForenkletTilbakekrevingsvedtakSamtykke: RestOppdaterForenkletTilbakekrevingsvedtakSamtykke,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingsvedtak>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Oppdater samtykke på forenklet tilbakekrevingsvedtak",
+        )
+        tilgangService.validerKanRedigereBehandling(behandlingId)
+
+        val oppdatertForenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.oppdaterSamtykkePåForenkletTilbakekrevingsvedtak(behandlingId, restOppdaterForenkletTilbakekrevingsvedtakSamtykke.samtykke)
+
+        return ResponseEntity.ok(Ressurs.success(oppdatertForenkletTilbakekrevingsvedtak.tilRestForenkletTilbakekrevingsvedtak()))
+    }
+
+    @DeleteMapping(
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+    )
+    fun slettForenkletTilbakekrevingsvedtak(
+        @PathVariable behandlingId: Long,
+    ): ResponseEntity<Ressurs<String>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Slett ForenkletTilbakekrevingsvedtak",
+        )
+        tilgangService.validerKanRedigereBehandling(behandlingId)
+
+        forenkletTilbakekrevingsvedtakService.slettForenkletTilbakekrevingsvedtak(behandlingId)
+
+        return ResponseEntity.ok(Ressurs.success("ForenkletTilbakekrevingsvedtak for behandling=$behandlingId slettet OK."))
+    }
+}
diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakRepository.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakRepository.kt
new file mode 100644
index 00000000000..c104ab0bb66
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakRepository.kt
@@ -0,0 +1,11 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingsvedtak
+
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
+import org.springframework.transaction.annotation.Transactional
+
+interface ForenkletTilbakekrevingsvedtakRepository : JpaRepository<ForenkletTilbakekrevingsvedtak, Long> {
+    @Query(value = "SELECT ftv FROM ForenkletTilbakekrevingsvedtak ftv WHERE ftv.behandlingId = :behandlingId")
+    @Transactional(readOnly = true)
+    fun finnForenkletTilbakekrevingsvedtakForBehandling(behandlingId: Long): ForenkletTilbakekrevingsvedtak?
+}
diff --git a/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakService.kt b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakService.kt
new file mode 100644
index 00000000000..a342d5da93e
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakService.kt
@@ -0,0 +1,73 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingsvedtak
+
+import no.nav.familie.ba.sak.common.FunksjonellFeil
+import no.nav.familie.ba.sak.kjerne.logg.LoggService
+import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
+
+@Service
+class ForenkletTilbakekrevingsvedtakService(
+    private val forenkletTilbakekrevingsvedtakRepository: ForenkletTilbakekrevingsvedtakRepository,
+    private val loggService: LoggService,
+) {
+    fun finnForenkletTilbakekrevingsvedtak(behandlingId: Long) = forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandlingId)
+
+    @Transactional
+    fun opprettForenkletTilbakekrevingsvedtak(behandlingId: Long) =
+        finnForenkletTilbakekrevingsvedtak(behandlingId) ?: run {
+            loggService.loggForenkletTilbakekrevingsvedtakOpprettet(behandlingId)
+            forenkletTilbakekrevingsvedtakRepository.save(
+                ForenkletTilbakekrevingsvedtak(
+                    behandlingId = behandlingId,
+                    samtykke = false,
+                    fritekst = STANDARD_TEKST_FORENKLET_TILBAKEKREVINGSVEDTAK,
+                ),
+            )
+        }
+
+    @Transactional
+    fun oppdaterSamtykkePåForenkletTilbakekrevingsvedtak(
+        behandlingId: Long,
+        samtykke: Boolean,
+    ): ForenkletTilbakekrevingsvedtak {
+        val forenkletTilbakekrevingsvedtak =
+            hentForenkletTilbakekrevingsvedtakEllerKastFunksjonellFeil(behandlingId).apply {
+                this.samtykke = samtykke
+                loggService.loggForenkletTilbakekrevingsvedtakOppdatertSamtykke(behandlingId)
+            }
+
+        return forenkletTilbakekrevingsvedtakRepository.save(forenkletTilbakekrevingsvedtak)
+    }
+
+    @Transactional
+    fun oppdaterFritekstPåForenkletTilbakekrevingsvedtak(
+        behandlingId: Long,
+        fritekst: String,
+    ): ForenkletTilbakekrevingsvedtak {
+        val forenkletTilbakekrevingsvedtak =
+            hentForenkletTilbakekrevingsvedtakEllerKastFunksjonellFeil(behandlingId).apply {
+                this.fritekst = fritekst
+                loggService.loggForenkletTilbakekrevingsvedtakOppdatertFritekst(behandlingId)
+            }
+
+        forenkletTilbakekrevingsvedtakRepository.save(forenkletTilbakekrevingsvedtak)
+
+        return forenkletTilbakekrevingsvedtak
+    }
+
+    @Transactional
+    fun slettForenkletTilbakekrevingsvedtak(behandlingId: Long) =
+        finnForenkletTilbakekrevingsvedtak(behandlingId)?.let {
+            forenkletTilbakekrevingsvedtakRepository.delete(it)
+            loggService.loggForenkletTilbakekrevingsvedtakSlettet(behandlingId)
+        }
+
+    private fun hentForenkletTilbakekrevingsvedtakEllerKastFunksjonellFeil(behandlingId: Long): ForenkletTilbakekrevingsvedtak =
+        finnForenkletTilbakekrevingsvedtak(behandlingId)
+            ?: throw FunksjonellFeil("Forenklet tilbakekrevingsvedtak finnes ikke for behandling $behandlingId. Oppdater fanen og prøv igjen.")
+
+    companion object {
+        // TODO: Denne endres på senere når det er klart hva standard tekst skal være
+        private const val STANDARD_TEKST_FORENKLET_TILBAKEKREVINGSVEDTAK = "TEKST"
+    }
+}
diff --git a/src/main/resources/db/migration/V271__forenklet_tilbakekreving_vedtak.sql b/src/main/resources/db/migration/V271__forenklet_tilbakekreving_vedtak.sql
new file mode 100644
index 00000000000..8b314902cf0
--- /dev/null
+++ b/src/main/resources/db/migration/V271__forenklet_tilbakekreving_vedtak.sql
@@ -0,0 +1,19 @@
+CREATE TABLE forenklet_tilbakekrevingsvedtak
+(
+    id               BIGINT PRIMARY KEY,
+    fk_behandling_id BIGINT                              NOT NULL,
+    samtykke         BOOLEAN,
+    fritekst         VARCHAR      DEFAULT false          NOT NULL,
+    versjon          BIGINT       DEFAULT 0              NOT NULL,
+    opprettet_av     VARCHAR      DEFAULT 'VL'           NOT NULL,
+    opprettet_tid    TIMESTAMP(3) DEFAULT localtimestamp NOT NULL,
+    endret_av        VARCHAR,
+    endret_tid       TIMESTAMP(3),
+
+    CONSTRAINT fk_forenklet_tilbakekreving_behandling
+        FOREIGN KEY (fk_behandling_id) REFERENCES behandling (id) ON DELETE CASCADE,
+    CONSTRAINT unique_fk_behandling_id UNIQUE (fk_behandling_id)
+);
+
+CREATE SEQUENCE forenklet_tilbakekrevingsvedtak_seq INCREMENT BY 50 START WITH 1000000 NO CYCLE;
+
diff --git a/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakServiceTest.kt b/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakServiceTest.kt
new file mode 100644
index 00000000000..4b56531e839
--- /dev/null
+++ b/src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakServiceTest.kt
@@ -0,0 +1,209 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingsvedtak
+
+import io.mockk.every
+import io.mockk.just
+import io.mockk.mockk
+import io.mockk.runs
+import io.mockk.verify
+import no.nav.familie.ba.sak.common.FunksjonellFeil
+import no.nav.familie.ba.sak.datagenerator.lagBehandling
+import no.nav.familie.ba.sak.kjerne.logg.LoggService
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+
+class ForenkletTilbakekrevingsvedtakServiceTest {
+    private val forenkletTilbakekrevingsvedtakRepository = mockk<ForenkletTilbakekrevingsvedtakRepository>()
+    private val loggService = mockk<LoggService>()
+
+    private val forenkletTilbakekrevingsvedtakService =
+        ForenkletTilbakekrevingsvedtakService(
+            forenkletTilbakekrevingsvedtakRepository,
+            loggService,
+        )
+
+    @Nested
+    inner class FinnForenkletTilbakekrevingsvedtakTest {
+        @Test
+        fun `skal returnere null hvis det ikke finnes forenklet tilbakekrevingsvedtak for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns null
+
+            // Act
+            val forenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.finnForenkletTilbakekrevingsvedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingsvedtak).isNull()
+        }
+
+        @Test
+        fun `skal returner forenklet tilbakekrevingsvedtak hvis det finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingsvedtak = ForenkletTilbakekrevingsvedtak(behandlingId = behandling.id, samtykke = false, fritekst = "fritekst")
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingsvedtak
+
+            // Act
+            val forenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.finnForenkletTilbakekrevingsvedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingsvedtak).isEqualTo(eksisterendeForenkletTilbakekrevingsvedtak)
+        }
+    }
+
+    @Nested
+    inner class OpprettForenkletTilbakekrevingsvedtakTest {
+        @Test
+        fun `Skal returnere eksisterende forenklet tilbakekrevingsvedtak dersom det allerede finnes`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingsvedtak = ForenkletTilbakekrevingsvedtak(behandlingId = behandling.id, samtykke = false, fritekst = "fritekst")
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingsvedtak
+
+            // Act
+            val forenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.opprettForenkletTilbakekrevingsvedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingsvedtak).isEqualTo(eksisterendeForenkletTilbakekrevingsvedtak)
+            verify(exactly = 0) { forenkletTilbakekrevingsvedtakRepository.save(any()) }
+        }
+
+        @Test
+        fun `skal opprette forenklet tilbakekrevingsvedtak hvis det ikke finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns null
+            every { forenkletTilbakekrevingsvedtakRepository.save(any()) } returnsArgument (0)
+            every { loggService.loggForenkletTilbakekrevingsvedtakOpprettet(behandling.id) } returns mockk()
+
+            // Act
+            val forenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.opprettForenkletTilbakekrevingsvedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingsvedtak.behandlingId).isEqualTo(behandling.id)
+            assertThat(forenkletTilbakekrevingsvedtak.fritekst).isEqualTo("TEKST")
+            assertThat(forenkletTilbakekrevingsvedtak.samtykke).isFalse()
+
+            verify(exactly = 1) { forenkletTilbakekrevingsvedtakRepository.save(forenkletTilbakekrevingsvedtak) }
+            verify(exactly = 1) { loggService.loggForenkletTilbakekrevingsvedtakOpprettet(behandling.id) }
+        }
+    }
+
+    @Nested
+    inner class OppdaterSamtykkePåForenkletTilbakekrevingsvedtakTest {
+        @Test
+        fun `Skal oppdatere samtykke på eksisterende forenklet tilbakekrevingsvedtak og opprette logg på dette`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingsvedtak = ForenkletTilbakekrevingsvedtak(behandlingId = behandling.id, samtykke = false, fritekst = "fritekst")
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingsvedtak
+            every { loggService.loggForenkletTilbakekrevingsvedtakOppdatertSamtykke(behandling.id) } returns mockk()
+            every { forenkletTilbakekrevingsvedtakRepository.save(any()) } returnsArgument (0)
+
+            // Act
+            val forenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.oppdaterSamtykkePåForenkletTilbakekrevingsvedtak(behandling.id, true)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingsvedtak.samtykke).isEqualTo(true)
+            verify(exactly = 1) { loggService.loggForenkletTilbakekrevingsvedtakOppdatertSamtykke(behandling.id) }
+            verify(exactly = 1) { forenkletTilbakekrevingsvedtakRepository.save(any()) }
+        }
+
+        @Test
+        fun `Skal kaste funksjonell feil hvis forenklet tilbakekrevingsvedtak ikke finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns null
+
+            // Act && Assert
+            val feilmelding =
+                assertThrows<FunksjonellFeil> {
+                    forenkletTilbakekrevingsvedtakService.oppdaterSamtykkePåForenkletTilbakekrevingsvedtak(behandling.id, true)
+                }.melding
+
+            assertThat(feilmelding).isEqualTo("Forenklet tilbakekrevingsvedtak finnes ikke for behandling 1. Oppdater fanen og prøv igjen.")
+        }
+    }
+
+    @Nested
+    inner class OppdaterFritekstPåForenkletTilbakekrevingsvedtakTest {
+        @Test
+        fun `Skal oppdatere fritekst på eksisterende forenklet tilbakekrevingsvedtak og opprette logg på dette`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingsvedtak = ForenkletTilbakekrevingsvedtak(behandlingId = behandling.id, samtykke = false, fritekst = "")
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingsvedtak
+            every { loggService.loggForenkletTilbakekrevingsvedtakOppdatertFritekst(behandling.id) } returns mockk()
+            every { forenkletTilbakekrevingsvedtakRepository.save(any()) } returnsArgument (0)
+
+            // Act
+            val forenkletTilbakekrevingsvedtak = forenkletTilbakekrevingsvedtakService.oppdaterFritekstPåForenkletTilbakekrevingsvedtak(behandling.id, "oppdatert med fritekst")
+
+            // Assert
+            assertThat(forenkletTilbakekrevingsvedtak.fritekst).isEqualTo("oppdatert med fritekst")
+            verify(exactly = 1) { loggService.loggForenkletTilbakekrevingsvedtakOppdatertFritekst(behandling.id) }
+            verify(exactly = 1) { forenkletTilbakekrevingsvedtakRepository.save(any()) }
+        }
+
+        @Test
+        fun `Skal kaste funksjonell feil hvis forenklet tilbakekrevingsvedtak ikke finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns null
+
+            // Act && Assert
+            val feilmelding =
+                assertThrows<FunksjonellFeil> {
+                    forenkletTilbakekrevingsvedtakService.oppdaterFritekstPåForenkletTilbakekrevingsvedtak(behandling.id, "finnes ikke")
+                }.melding
+
+            assertThat(feilmelding).isEqualTo("Forenklet tilbakekrevingsvedtak finnes ikke for behandling 1. Oppdater fanen og prøv igjen.")
+        }
+    }
+
+    @Nested
+    inner class SlettForenkletTilbakekrevingsvedtakTest {
+        @Test
+        fun `Skal slette forenklet tilbakekrevingsvedtak hvis det finnes`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingsvedtak = ForenkletTilbakekrevingsvedtak(behandlingId = behandling.id, samtykke = false, fritekst = "")
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingsvedtak
+            every { loggService.loggForenkletTilbakekrevingsvedtakSlettet(behandling.id) } returns mockk()
+            every { forenkletTilbakekrevingsvedtakRepository.delete(eksisterendeForenkletTilbakekrevingsvedtak) } just runs
+
+            // Act
+            forenkletTilbakekrevingsvedtakService.slettForenkletTilbakekrevingsvedtak(behandling.id)
+
+            // Assert
+            verify(exactly = 1) { loggService.loggForenkletTilbakekrevingsvedtakSlettet(behandling.id) }
+            verify(exactly = 1) { forenkletTilbakekrevingsvedtakRepository.delete(eksisterendeForenkletTilbakekrevingsvedtak) }
+        }
+
+        @Test
+        fun `Dersom det ikke eksisterer noe forenklet tilbakekrevingsvedtak så skal det ikke gjøres noe`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingsvedtakRepository.finnForenkletTilbakekrevingsvedtakForBehandling(behandling.id) } returns null
+
+            // Act
+            forenkletTilbakekrevingsvedtakService.slettForenkletTilbakekrevingsvedtak(behandling.id)
+
+            // Assert
+            verify(exactly = 0) { loggService.loggForenkletTilbakekrevingsvedtakSlettet(any()) }
+            verify(exactly = 0) { forenkletTilbakekrevingsvedtakRepository.delete(any()) }
+        }
+    }
+}
diff --git a/src/test/integrasjonstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakRepositoryTest.kt b/src/test/integrasjonstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakRepositoryTest.kt
new file mode 100644
index 00000000000..39da35a8010
--- /dev/null
+++ b/src/test/integrasjonstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingsvedtak/ForenkletTilbakekrevingsvedtakRepositoryTest.kt
@@ -0,0 +1,42 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingsvedtak
+
+import no.nav.familie.ba.sak.config.AbstractSpringIntegrationTest
+import no.nav.familie.ba.sak.datagenerator.lagBehandlingUtenId
+import no.nav.familie.ba.sak.datagenerator.randomAktør
+import no.nav.familie.ba.sak.kjerne.behandling.domene.BehandlingRepository
+import no.nav.familie.ba.sak.kjerne.fagsak.Fagsak
+import no.nav.familie.ba.sak.kjerne.fagsak.FagsakRepository
+import no.nav.familie.ba.sak.kjerne.personident.AktørIdRepository
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.dao.DataIntegrityViolationException
+
+class ForenkletTilbakekrevingsvedtakRepositoryTest(
+    @Autowired
+    private val aktørIdRepository: AktørIdRepository,
+    @Autowired
+    private val fagsakRepository: FagsakRepository,
+    @Autowired
+    private val behandlingRepository: BehandlingRepository,
+    @Autowired
+    private val forenkletTilbakekrevingsvedtakRepository: ForenkletTilbakekrevingsvedtakRepository,
+) : AbstractSpringIntegrationTest() {
+    @Nested
+    inner class SaveTest {
+        @Test
+        fun `save skal kaste feil dersom det forsøkes å lagre ny ForenkletTilbakekrevingsvedtak når det allerede finnes en for behandlingen`() {
+            // Arrange
+            val søker = aktørIdRepository.save(randomAktør())
+            val fagsak = fagsakRepository.save(Fagsak(aktør = søker))
+            val behandling = behandlingRepository.save(lagBehandlingUtenId(fagsak = fagsak))
+
+            // Act
+            forenkletTilbakekrevingsvedtakRepository.saveAndFlush(ForenkletTilbakekrevingsvedtak(behandlingId = behandling.id, fritekst = "Fritekst", samtykke = false))
+
+            // Assert
+            assertThrows<DataIntegrityViolationException> { forenkletTilbakekrevingsvedtakRepository.saveAndFlush(ForenkletTilbakekrevingsvedtak(behandlingId = behandling.id, fritekst = "Fritekst", samtykke = false)) }
+        }
+    }
+}


Reviews:
user: login: MagnusTonnessen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:11:48Z
user: login: MagnusTonnessen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:13:38Z
user: login: MagnusTonnessen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:16:21Z
user: login: UyQuangNguyen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:23:50Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:26:02Z
user: login: MagnusTonnessen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:30:01Z
user: login: MagnusTonnessen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:31:32Z
user: login: MagnusTonnessen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:33:18Z
user: login: UyQuangNguyen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:35:53Z
user: login: UyQuangNguyen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:36:04Z
user: login: UyQuangNguyen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:53:03Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T07:57:36Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T08:26:24Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:12:24Z
user: login: UyQuangNguyen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:21:38Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:28:12Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:29:44Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:33:04Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:43:24Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:50:34Z
user: login: UyQuangNguyen
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:52:32Z
user: login: stigebil
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:54:14Z
user: login: stigebil
body: Lagt til kommentarer, men synes dette er bra. 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-05T09:56:15Z

Review comments:
diff_hunk: @@ -737,6 +737,58 @@ class LoggService(
         ),
     )
 
+    fun loggForenkletTilbakekrevingVedtakOpprettet(behandlingId: Long) =
+        lagre(
+            Logg(
+                behandlingId = behandlingId,
+                type = LoggType.FORENKLET_TILBAKEKREVING_VEDTAK_OPPRETTET,
+                rolle =
+                    SikkerhetContext.hentRolletilgangFraSikkerhetscontext(
+                        rolleConfig,
+                        BehandlerRolle.SAKSBEHANDLER,
+                    ),
+            ),
+        )
+
+    fun loggForenkletTilbakekrevingVedtakSamtykkeOppdatert(behandlingId: Long) =
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/LoggService.kt
user: login: MagnusTonnessen
body: Pirk, men synes `Oppdatert` skal komme på samme sted i dette funksjonsnavnet og `loggForenkletTilbakekrevingVedtakOppdatertFritekst`, typ enten bytte denne til `OppdatertSamtykke` eller bytte den andre til `FritekstOppdatert`. Samme med `LoggType`
created_at: 2025-03-05T07:11:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -96,4 +96,8 @@ enum class LoggType(
     SAMMENSATT_KONTROLLSAK_LAGT_TIL("Sammensatt kontrollsak lagt til"),
     SAMMENSATT_KONTROLLSAK_ENDRET("Sammensatt kontrollsak endret"),
     SAMMENSATT_KONTROLLSAK_FJERNET("Sammensatt kontrollsak fjernet"),
+    FORENKLET_TILBAKEKREVING_VEDTAK_OPPRETTET("Forenklet tilbakekreving vedtak opprettet"),
+    FORENKLET_TILBAKEKREVING_VEDTAK_OPPDATERT_FRITEKST("Forenklet tilbakekreving vedtak fritekst oppdatert"),
+    FORENKLET_TILBAKEKREVING_VEDTAK_SAMTYKKE_OPPDATERT("Forenklet tilbakekreving vedtak samtykke oppdatert"),
+    FORENKLET_TILBAKEKREVING_VEDTAK_SLETTET("Forenklet tilbakekreving vedtak fjernet"),
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/Logg.kt
user: login: MagnusTonnessen
body: `tilbakekrevingvedtak` i ett ord?
created_at: 2025-03-05T07:13:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,41 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.EntityListeners
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.SequenceGenerator
+import jakarta.persistence.Table
+import no.nav.familie.ba.sak.common.BaseEntitet
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.sikkerhet.RollestyringMotDatabase
+
+@EntityListeners(RollestyringMotDatabase::class)
+@Entity(name = "ForenkletTilbakekrevingVedtak")
+@Table(name = "forenklet_tilbakekreving_vedtak")
+data class ForenkletTilbakekrevingVedtak(
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "forenklet_tilbakekreving_vedtak_seq_generator")
+    @SequenceGenerator(
+        name = "forenklet_tilbakekreving_vedtak_seq_generator",
+        sequenceName = "forenklet_tilbakekreving_vedtak_seq",
+        allocationSize = 50,
+    )
+    val id: Long = 0,
+    @Column(name = "fk_behandling_id", updatable = false, nullable = false)
+    val behandlingId: Long,
+    @Column(name = "samtykke", nullable = true, updatable = true)
+    var samtykke: Boolean?,
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtak.kt
user: login: MagnusTonnessen
body: Trenger `samtykke` å være nullable, hvis vi uansett skal slette dette objektet når saksbehandler bekrefter at samtykke ikke er gitt fra brukeren?
created_at: 2025-03-05T07:16:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,41 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.EntityListeners
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.SequenceGenerator
+import jakarta.persistence.Table
+import no.nav.familie.ba.sak.common.BaseEntitet
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.sikkerhet.RollestyringMotDatabase
+
+@EntityListeners(RollestyringMotDatabase::class)
+@Entity(name = "ForenkletTilbakekrevingVedtak")
+@Table(name = "forenklet_tilbakekreving_vedtak")
+data class ForenkletTilbakekrevingVedtak(
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "forenklet_tilbakekreving_vedtak_seq_generator")
+    @SequenceGenerator(
+        name = "forenklet_tilbakekreving_vedtak_seq_generator",
+        sequenceName = "forenklet_tilbakekreving_vedtak_seq",
+        allocationSize = 50,
+    )
+    val id: Long = 0,
+    @Column(name = "fk_behandling_id", updatable = false, nullable = false)
+    val behandlingId: Long,
+    @Column(name = "samtykke", nullable = true, updatable = true)
+    var samtykke: Boolean?,
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtak.kt
user: login: UyQuangNguyen
body: Det spørs litt. Jeg synes egentlig en nullable samtykke representerer virkeligheten mer, da man ikke har fått svar om samtykke enda. 
created_at: 2025-03-05T07:23:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,100 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import no.nav.familie.ba.sak.config.BehandlerRolle
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakFritekst
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakSamtykke
+import no.nav.familie.ba.sak.sikkerhet.TilgangService
+import no.nav.familie.kontrakter.felles.Ressurs
+import no.nav.security.token.support.core.api.ProtectedWithClaims
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.validation.annotation.Validated
+import org.springframework.web.bind.annotation.DeleteMapping
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PatchMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak")
+@ProtectedWithClaims(issuer = "azuread")
+@Validated
+class ForenkletTilbakekrevingVedtakController(
+    val tilgangService: TilgangService,
+    val forenkletTilbakekrevingVedtakService: ForenkletTilbakekrevingVedtakService,
+) {
+    @GetMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+    )
+    fun hentForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak?>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Hent ForenkletTilbakekrevingVedtak",
+        )
+        val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandlingId = behandlingId)
+
+        return ResponseEntity.ok(Ressurs.success(forenkletTilbakekrevingVedtak?.tilRestForenkletTilbakekrevingVedtak()))
+    }
+
+    @PatchMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+        path = ["/fritekst"],
+    )
+    fun oppdaterFritekstPåForenkletTilbakekrevingVedtak(
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakController.kt
user: login: stigebil
body: Hvis oppdater samtykke og fritekst er operasjoner som typisk vil skje samtidig, så ville jeg kombinert endepunktene. Hvis det er naturlig å separere de, så er det fint som det er
created_at: 2025-03-05T07:26:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,206 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import io.mockk.every
+import io.mockk.just
+import io.mockk.mockk
+import io.mockk.runs
+import io.mockk.verify
+import no.nav.familie.ba.sak.common.FunksjonellFeil
+import no.nav.familie.ba.sak.datagenerator.lagBehandling
+import no.nav.familie.ba.sak.kjerne.logg.LoggService
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+
+class ForenkletTilbakekrevingVedtakServiceTest {
+    private val forenkletTilbakekrevingVedtakRepository = mockk<ForenkletTilbakekrevingVedtakRepository>()
+    private val loggService = mockk<LoggService>()
+
+    private val forenkletTilbakekrevingVedtakService =
+        ForenkletTilbakekrevingVedtakService(
+            forenkletTilbakekrevingVedtakRepository,
+            loggService,
+        )
+
+    @Nested
+    inner class FinnForenkletTilbakekrevingVedtakTest {
+        @Test
+        fun `skal returnere null hvis det ikke finnes forenklet tilbakekreving vedtak for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns null
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak).isNull()
+        }
+
+        @Test
+        fun `skal returner forenklet tilbakekreving vedtak hvis det finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingVedtak = ForenkletTilbakekrevingVedtak(behandlingId = behandling.id, samtykke = null, fritekst = "fritekst")
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingVedtak
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak).isEqualTo(eksisterendeForenkletTilbakekrevingVedtak)
+        }
+    }
+
+    @Nested
+    inner class OpprettForenkletTilbakekrevingVedtakTest {
+        @Test
+        fun `Skal returnere eksisterende forenklet tilbakekreving vedtak dersom det allerede finnes`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingVedtak = ForenkletTilbakekrevingVedtak(behandlingId = behandling.id, samtykke = null, fritekst = "fritekst")
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingVedtak
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.opprettForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak).isEqualTo(eksisterendeForenkletTilbakekrevingVedtak)
+            verify(exactly = 0) { forenkletTilbakekrevingVedtakRepository.save(any()) }
+        }
+
+        @Test
+        fun `skal opprette forenklet tilbakekreving vedtak hvis det ikke finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns null
+            every { forenkletTilbakekrevingVedtakRepository.save(any()) } returnsArgument (0)
+            every { loggService.loggForenkletTilbakekrevingVedtakOpprettet(behandling.id) } returns mockk()
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.opprettForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak.behandlingId).isEqualTo(behandling.id)
path: src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakServiceTest.kt
user: login: MagnusTonnessen
body: Her kunne man også sjekket at `samtykke` og `fritekst` har forventede verdier
created_at: 2025-03-05T07:30:01Z
author_association: CONTRIBUTOR
path: src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakServiceTest.kt
user: login: MagnusTonnessen
body: Nice med nøstede klasser 🤩 
created_at: 2025-03-05T07:31:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,41 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.EntityListeners
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.SequenceGenerator
+import jakarta.persistence.Table
+import no.nav.familie.ba.sak.common.BaseEntitet
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.sikkerhet.RollestyringMotDatabase
+
+@EntityListeners(RollestyringMotDatabase::class)
+@Entity(name = "ForenkletTilbakekrevingVedtak")
+@Table(name = "forenklet_tilbakekreving_vedtak")
+data class ForenkletTilbakekrevingVedtak(
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "forenklet_tilbakekreving_vedtak_seq_generator")
+    @SequenceGenerator(
+        name = "forenklet_tilbakekreving_vedtak_seq_generator",
+        sequenceName = "forenklet_tilbakekreving_vedtak_seq",
+        allocationSize = 50,
+    )
+    val id: Long = 0,
+    @Column(name = "fk_behandling_id", updatable = false, nullable = false)
+    val behandlingId: Long,
+    @Column(name = "samtykke", nullable = true, updatable = true)
+    var samtykke: Boolean?,
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtak.kt
user: login: MagnusTonnessen
body: Ja, det er sant, tror bare den da aldri vil ha verdien `false` 😅 
created_at: 2025-03-05T07:33:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,100 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import no.nav.familie.ba.sak.config.BehandlerRolle
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakFritekst
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakSamtykke
+import no.nav.familie.ba.sak.sikkerhet.TilgangService
+import no.nav.familie.kontrakter.felles.Ressurs
+import no.nav.security.token.support.core.api.ProtectedWithClaims
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.validation.annotation.Validated
+import org.springframework.web.bind.annotation.DeleteMapping
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PatchMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak")
+@ProtectedWithClaims(issuer = "azuread")
+@Validated
+class ForenkletTilbakekrevingVedtakController(
+    val tilgangService: TilgangService,
+    val forenkletTilbakekrevingVedtakService: ForenkletTilbakekrevingVedtakService,
+) {
+    @GetMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+    )
+    fun hentForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak?>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Hent ForenkletTilbakekrevingVedtak",
+        )
+        val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandlingId = behandlingId)
+
+        return ResponseEntity.ok(Ressurs.success(forenkletTilbakekrevingVedtak?.tilRestForenkletTilbakekrevingVedtak()))
+    }
+
+    @PatchMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+        path = ["/fritekst"],
+    )
+    fun oppdaterFritekstPåForenkletTilbakekrevingVedtak(
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakController.kt
user: login: UyQuangNguyen
body: Stemmer, det er to operasjoner som ikke kommer til å skje samtidig :D 
created_at: 2025-03-05T07:35:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,206 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import io.mockk.every
+import io.mockk.just
+import io.mockk.mockk
+import io.mockk.runs
+import io.mockk.verify
+import no.nav.familie.ba.sak.common.FunksjonellFeil
+import no.nav.familie.ba.sak.datagenerator.lagBehandling
+import no.nav.familie.ba.sak.kjerne.logg.LoggService
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.jupiter.api.Nested
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+
+class ForenkletTilbakekrevingVedtakServiceTest {
+    private val forenkletTilbakekrevingVedtakRepository = mockk<ForenkletTilbakekrevingVedtakRepository>()
+    private val loggService = mockk<LoggService>()
+
+    private val forenkletTilbakekrevingVedtakService =
+        ForenkletTilbakekrevingVedtakService(
+            forenkletTilbakekrevingVedtakRepository,
+            loggService,
+        )
+
+    @Nested
+    inner class FinnForenkletTilbakekrevingVedtakTest {
+        @Test
+        fun `skal returnere null hvis det ikke finnes forenklet tilbakekreving vedtak for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns null
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak).isNull()
+        }
+
+        @Test
+        fun `skal returner forenklet tilbakekreving vedtak hvis det finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingVedtak = ForenkletTilbakekrevingVedtak(behandlingId = behandling.id, samtykke = null, fritekst = "fritekst")
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingVedtak
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak).isEqualTo(eksisterendeForenkletTilbakekrevingVedtak)
+        }
+    }
+
+    @Nested
+    inner class OpprettForenkletTilbakekrevingVedtakTest {
+        @Test
+        fun `Skal returnere eksisterende forenklet tilbakekreving vedtak dersom det allerede finnes`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+            val eksisterendeForenkletTilbakekrevingVedtak = ForenkletTilbakekrevingVedtak(behandlingId = behandling.id, samtykke = null, fritekst = "fritekst")
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns eksisterendeForenkletTilbakekrevingVedtak
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.opprettForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak).isEqualTo(eksisterendeForenkletTilbakekrevingVedtak)
+            verify(exactly = 0) { forenkletTilbakekrevingVedtakRepository.save(any()) }
+        }
+
+        @Test
+        fun `skal opprette forenklet tilbakekreving vedtak hvis det ikke finnes for behandling`() {
+            // Arrange
+            val behandling = lagBehandling(id = 1)
+
+            every { forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandling.id) } returns null
+            every { forenkletTilbakekrevingVedtakRepository.save(any()) } returnsArgument (0)
+            every { loggService.loggForenkletTilbakekrevingVedtakOpprettet(behandling.id) } returns mockk()
+
+            // Act
+            val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.opprettForenkletTilbakekrevingVedtak(behandling.id)
+
+            // Assert
+            assertThat(forenkletTilbakekrevingVedtak.behandlingId).isEqualTo(behandling.id)
path: src/test/enhetstester/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakServiceTest.kt
user: login: UyQuangNguyen
body: Godt poeng! 🤩 
created_at: 2025-03-05T07:36:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,41 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.EntityListeners
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.SequenceGenerator
+import jakarta.persistence.Table
+import no.nav.familie.ba.sak.common.BaseEntitet
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.sikkerhet.RollestyringMotDatabase
+
+@EntityListeners(RollestyringMotDatabase::class)
+@Entity(name = "ForenkletTilbakekrevingVedtak")
+@Table(name = "forenklet_tilbakekreving_vedtak")
+data class ForenkletTilbakekrevingVedtak(
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "forenklet_tilbakekreving_vedtak_seq_generator")
+    @SequenceGenerator(
+        name = "forenklet_tilbakekreving_vedtak_seq_generator",
+        sequenceName = "forenklet_tilbakekreving_vedtak_seq",
+        allocationSize = 50,
+    )
+    val id: Long = 0,
+    @Column(name = "fk_behandling_id", updatable = false, nullable = false)
+    val behandlingId: Long,
+    @Column(name = "samtykke", nullable = true, updatable = true)
+    var samtykke: Boolean?,
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtak.kt
user: login: UyQuangNguyen
body: Du har helt rett, jeg tror det blir mye cleanere å bare defaulte til false.
Bra innspill 🤩 
created_at: 2025-03-05T07:53:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,75 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import no.nav.familie.ba.sak.common.FunksjonellFeil
+import no.nav.familie.ba.sak.kjerne.logg.LoggService
+import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
+
+@Service
+class ForenkletTilbakekrevingVedtakService(
+    private val forenkletTilbakekrevingVedtakRepository: ForenkletTilbakekrevingVedtakRepository,
+    private val loggService: LoggService,
+) {
+    @Transactional(readOnly = true)
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakService.kt
user: login: stigebil
body: Ingenting å si akkurat her, men det kan være ok å være bevist på bruken av Transactional(readOnly = true)

Denne beskriver det veldig bra.
https://medium.com/@jkha7371/is-transactional-readonly-true-a-silver-bullet-1dbf130c97f8
TLDR: 
Fordel: raskere
Ulempe: Holder en connection og større fare for dead lock.

Hadde vi brukt findById, så hadde man fått readOnly gratis i repolaget, men siden vi ikke liker Optional og skriver vår egen getById så går vi glipp av den. Siden denne klassen bare kaller repometoden, så ville jeg flyttet ned Transactional(readOnly = true)
created_at: 2025-03-05T07:57:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -96,4 +96,8 @@ enum class LoggType(
     SAMMENSATT_KONTROLLSAK_LAGT_TIL("Sammensatt kontrollsak lagt til"),
     SAMMENSATT_KONTROLLSAK_ENDRET("Sammensatt kontrollsak endret"),
     SAMMENSATT_KONTROLLSAK_FJERNET("Sammensatt kontrollsak fjernet"),
+    FORENKLET_TILBAKEKREVING_VEDTAK_OPPRETTET("Forenklet tilbakekreving vedtak opprettet"),
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/logg/Logg.kt
user: login: stigebil
body: For alle disse tekstene:
tilbakekreving vedtak -> tilbakekrevingsvedtak
created_at: 2025-03-05T08:26:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,16 @@
+package no.nav.familie.ba.sak.ekstern.restDomene
+
+data class RestForenkletTilbakekrevingVedtak(
path: src/main/kotlin/no/nav/familie/ba/sak/ekstern/restDomene/RestForenkletTilbakekrevingVedtak.kt
user: login: stigebil
body: Generell kommentar. Heter det TilbakekrevingVedtak eller Tilbakekrevingsvedtak. Jeg mener Tilbakekrevingsvedtak er mest korrekt språklig. Samtidig synes jeg det er letter å finne klassen TilbakekrevingVedtak
created_at: 2025-03-05T09:12:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,16 @@
+package no.nav.familie.ba.sak.ekstern.restDomene
+
+data class RestForenkletTilbakekrevingVedtak(
path: src/main/kotlin/no/nav/familie/ba/sak/ekstern/restDomene/RestForenkletTilbakekrevingVedtak.kt
user: login: UyQuangNguyen
body: Jeg tror jeg endrer alt til Tilbakekrevingsvedtak 😋 
created_at: 2025-03-05T09:21:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,19 @@
+CREATE TABLE forenklet_tilbakekreving_vedtak
+(
+    id               BIGINT PRIMARY KEY,
+    fk_behandling_id BIGINT NOT NULL,
+    samtykke         BOOLEAN,
+    fritekst         VARCHAR,
+    versjon          BIGINT       DEFAULT 0              NOT NULL,
+    opprettet_av     VARCHAR      DEFAULT 'VL'           NOT NULL,
+    opprettet_tid    TIMESTAMP(3) DEFAULT localtimestamp NOT NULL,
+    endret_av        VARCHAR,
+    endret_tid       TIMESTAMP(3),
+
+    CONSTRAINT fk_forenklet_tilbakekreving_behandling
+        FOREIGN KEY (fk_behandling_id) REFERENCES behandling (id) ON DELETE CASCADE,
path: src/main/resources/db/migration/V271__forenklet_tilbakekreving_vedtak.sql
user: login: stigebil
body: supert å huske on delete cascade
created_at: 2025-03-05T09:28:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,41 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.EntityListeners
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.SequenceGenerator
+import jakarta.persistence.Table
+import no.nav.familie.ba.sak.common.BaseEntitet
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.sikkerhet.RollestyringMotDatabase
+
+@EntityListeners(RollestyringMotDatabase::class)
+@Entity(name = "ForenkletTilbakekrevingVedtak")
+@Table(name = "forenklet_tilbakekreving_vedtak")
+data class ForenkletTilbakekrevingVedtak(
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "forenklet_tilbakekreving_vedtak_seq_generator")
+    @SequenceGenerator(
+        name = "forenklet_tilbakekreving_vedtak_seq_generator",
+        sequenceName = "forenklet_tilbakekreving_vedtak_seq",
+        allocationSize = 50,
+    )
+    val id: Long = 0,
+    @Column(name = "fk_behandling_id", updatable = false, nullable = false)
+    val behandlingId: Long,
+    @Column(name = "samtykke", nullable = true, updatable = true)
+    var samtykke: Boolean?,
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtak.kt
user: login: stigebil
body: jeg synes det er cleanest å ha default to false på booleans
created_at: 2025-03-05T09:29:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,75 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import no.nav.familie.ba.sak.common.FunksjonellFeil
+import no.nav.familie.ba.sak.kjerne.logg.LoggService
+import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
+
+@Service
+class ForenkletTilbakekrevingVedtakService(
+    private val forenkletTilbakekrevingVedtakRepository: ForenkletTilbakekrevingVedtakRepository,
+    private val loggService: LoggService,
+) {
+    @Transactional(readOnly = true)
+    fun finnForenkletTilbakekrevingVedtak(behandlingId: Long) = forenkletTilbakekrevingVedtakRepository.finnForenkletTilbakekrevingVedtakForBehandling(behandlingId)
+
+    @Transactional
+    fun opprettForenkletTilbakekrevingVedtak(behandlingId: Long) =
+        finnForenkletTilbakekrevingVedtak(behandlingId) ?: run {
+            loggService.loggForenkletTilbakekrevingVedtakOpprettet(behandlingId)
+            forenkletTilbakekrevingVedtakRepository.save(
+                ForenkletTilbakekrevingVedtak(
+                    behandlingId = behandlingId,
+                    samtykke = null,
+                    fritekst = STANDARD_TEKST_FORENKLET_TILBAKEKREVING_VEDTAK,
+                ),
+            )
+        }
+
+    @Transactional
+    fun oppdaterSamtykkePåForenkletTilbakekrevingVedtak(
+        behandlingId: Long,
+        samtykke: Boolean,
+    ): ForenkletTilbakekrevingVedtak {
+        val forenkletTilbakekrevingVedtak =
+            hentForenkletTilbakekrevingVedtakEllerKastFunksjonellFeil(behandlingId).apply {
+                this.samtykke = samtykke
+                loggService.loggForenkletTilbakekrevingVedtakSamtykkeOppdatert(behandlingId)
+            }
+
+        return forenkletTilbakekrevingVedtakRepository.save(forenkletTilbakekrevingVedtak)
+    }
+
+    @Transactional
+    fun oppdaterFritekstPåForenkletTilbakekrevingVedtak(
+        behandlingId: Long,
+        fritekst: String,
+    ): ForenkletTilbakekrevingVedtak {
+        val forenkletTilbakekrevingVedtak =
+            hentForenkletTilbakekrevingVedtakEllerKastFunksjonellFeil(behandlingId).apply {
+                this.fritekst = fritekst
+                loggService.loggForenkletTilbakekrevingVedtakOppdatertFritekst(behandlingId)
+            }
+
+        forenkletTilbakekrevingVedtakRepository.save(forenkletTilbakekrevingVedtak)
+
+        return forenkletTilbakekrevingVedtak
+    }
+
+    @Transactional
+    fun slettForenkletTilbakekrevingVedtak(behandlingId: Long) =
+        finnForenkletTilbakekrevingVedtak(behandlingId)?.let {
+            forenkletTilbakekrevingVedtakRepository.delete(it)
+            loggService.loggForenkletTilbakekrevingVedtakSlettet(behandlingId)
+        }
+
+    private fun hentForenkletTilbakekrevingVedtakEllerKastFunksjonellFeil(behandlingId: Long): ForenkletTilbakekrevingVedtak =
+        finnForenkletTilbakekrevingVedtak(behandlingId)
+            ?: throw FunksjonellFeil("Forenklet tilbakekreving vedtak finnes ikke for behandling $behandlingId. Oppdater fanen og prøv igjen.")
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakService.kt
user: login: stigebil
body: tilbakekrevingsvedtak
created_at: 2025-03-05T09:33:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,100 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import no.nav.familie.ba.sak.config.BehandlerRolle
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakFritekst
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakSamtykke
+import no.nav.familie.ba.sak.sikkerhet.TilgangService
+import no.nav.familie.kontrakter.felles.Ressurs
+import no.nav.security.token.support.core.api.ProtectedWithClaims
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.validation.annotation.Validated
+import org.springframework.web.bind.annotation.DeleteMapping
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PatchMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak")
+@ProtectedWithClaims(issuer = "azuread")
+@Validated
+class ForenkletTilbakekrevingVedtakController(
+    val tilgangService: TilgangService,
+    val forenkletTilbakekrevingVedtakService: ForenkletTilbakekrevingVedtakService,
+) {
+    @GetMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+    )
+    fun hentForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak?>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Hent ForenkletTilbakekrevingVedtak",
+        )
+        val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandlingId = behandlingId)
+
+        return ResponseEntity.ok(Ressurs.success(forenkletTilbakekrevingVedtak?.tilRestForenkletTilbakekrevingVedtak()))
+    }
+
+    @PatchMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+        path = ["/fritekst"],
+    )
+    fun oppdaterFritekstPåForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+        @RequestBody restOppdaterForenkletTilbakekrevingVedtakFritekst: RestOppdaterForenkletTilbakekrevingVedtakFritekst,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Oppdater fritekst på forenklet tilbakekreving vedtak",
+        )
+        tilgangService.validerKanRedigereBehandling(behandlingId)
+
+        val oppdatertForenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.oppdaterFritekstPåForenkletTilbakekrevingVedtak(behandlingId, restOppdaterForenkletTilbakekrevingVedtakFritekst.fritekst)
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakController.kt
user: login: stigebil
body: Fritekst anbefales egentlig ikke å brukes, siden man ikke har noen kontroll på hva slags sensitiv informasjon som legges i disse feltene, som andre senere med saksbehandlertilgang egentlig ikke burde ha fått sett. Har man gjort noen tanker rundt dette her?

Et eksempel på hvor galt det kan gå når fritekstfelt blir misbrukt: https://www.nrk.no/norge/omfattende-personvernbrudd-i-nav-1.16611483


created_at: 2025-03-05T09:43:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,16 @@
+package no.nav.familie.ba.sak.ekstern.restDomene
+
+data class RestForenkletTilbakekrevingVedtak(
path: src/main/kotlin/no/nav/familie/ba/sak/ekstern/restDomene/RestForenkletTilbakekrevingVedtak.kt
user: login: stigebil
body: For eksempel så kan:
- inputvalidering og feltbegrensning redusere risikoen. Bør også gjøres på backend-siden. 
- Informasjonsbokser i UI om hva som er lov å bruke feltet til og hva som ikke er lov. 
- Kun vise fritekst ved behov og at det da auditlogges.

created_at: 2025-03-05T09:50:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,100 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import no.nav.familie.ba.sak.config.BehandlerRolle
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakFritekst
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakSamtykke
+import no.nav.familie.ba.sak.sikkerhet.TilgangService
+import no.nav.familie.kontrakter.felles.Ressurs
+import no.nav.security.token.support.core.api.ProtectedWithClaims
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.validation.annotation.Validated
+import org.springframework.web.bind.annotation.DeleteMapping
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PatchMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak")
+@ProtectedWithClaims(issuer = "azuread")
+@Validated
+class ForenkletTilbakekrevingVedtakController(
+    val tilgangService: TilgangService,
+    val forenkletTilbakekrevingVedtakService: ForenkletTilbakekrevingVedtakService,
+) {
+    @GetMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+    )
+    fun hentForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak?>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Hent ForenkletTilbakekrevingVedtak",
+        )
+        val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandlingId = behandlingId)
+
+        return ResponseEntity.ok(Ressurs.success(forenkletTilbakekrevingVedtak?.tilRestForenkletTilbakekrevingVedtak()))
+    }
+
+    @PatchMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+        path = ["/fritekst"],
+    )
+    fun oppdaterFritekstPåForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+        @RequestBody restOppdaterForenkletTilbakekrevingVedtakFritekst: RestOppdaterForenkletTilbakekrevingVedtakFritekst,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Oppdater fritekst på forenklet tilbakekreving vedtak",
+        )
+        tilgangService.validerKanRedigereBehandling(behandlingId)
+
+        val oppdatertForenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.oppdaterFritekstPåForenkletTilbakekrevingVedtak(behandlingId, restOppdaterForenkletTilbakekrevingVedtakFritekst.fritekst)
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakController.kt
user: login: UyQuangNguyen
body: Tanken er at det skal fungere på samme måte som sammensatt kontrollsak der vi også har et fritekst felt som senere blir vist i vedtaket. Skal sjekke opp med Miriam angående risiko, men det var foreslått av Anna og Miriam.
created_at: 2025-03-05T09:52:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,100 @@
+package no.nav.familie.ba.sak.kjerne.vedtak.forenklettilbakekrevingvedtak
+
+import no.nav.familie.ba.sak.config.BehandlerRolle
+import no.nav.familie.ba.sak.ekstern.restDomene.RestForenkletTilbakekrevingVedtak
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakFritekst
+import no.nav.familie.ba.sak.ekstern.restDomene.RestOppdaterForenkletTilbakekrevingVedtakSamtykke
+import no.nav.familie.ba.sak.sikkerhet.TilgangService
+import no.nav.familie.kontrakter.felles.Ressurs
+import no.nav.security.token.support.core.api.ProtectedWithClaims
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.validation.annotation.Validated
+import org.springframework.web.bind.annotation.DeleteMapping
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PatchMapping
+import org.springframework.web.bind.annotation.PathVariable
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/behandling/{behandlingId}/forenklet-tilbakekreving-vedtak")
+@ProtectedWithClaims(issuer = "azuread")
+@Validated
+class ForenkletTilbakekrevingVedtakController(
+    val tilgangService: TilgangService,
+    val forenkletTilbakekrevingVedtakService: ForenkletTilbakekrevingVedtakService,
+) {
+    @GetMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+    )
+    fun hentForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak?>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Hent ForenkletTilbakekrevingVedtak",
+        )
+        val forenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.finnForenkletTilbakekrevingVedtak(behandlingId = behandlingId)
+
+        return ResponseEntity.ok(Ressurs.success(forenkletTilbakekrevingVedtak?.tilRestForenkletTilbakekrevingVedtak()))
+    }
+
+    @PatchMapping(
+        produces = [MediaType.APPLICATION_JSON_VALUE],
+        consumes = [MediaType.APPLICATION_JSON_VALUE],
+        path = ["/fritekst"],
+    )
+    fun oppdaterFritekstPåForenkletTilbakekrevingVedtak(
+        @PathVariable behandlingId: Long,
+        @RequestBody restOppdaterForenkletTilbakekrevingVedtakFritekst: RestOppdaterForenkletTilbakekrevingVedtakFritekst,
+    ): ResponseEntity<Ressurs<RestForenkletTilbakekrevingVedtak>> {
+        tilgangService.verifiserHarTilgangTilHandling(
+            minimumBehandlerRolle = BehandlerRolle.SAKSBEHANDLER,
+            handling = "Oppdater fritekst på forenklet tilbakekreving vedtak",
+        )
+        tilgangService.validerKanRedigereBehandling(behandlingId)
+
+        val oppdatertForenkletTilbakekrevingVedtak = forenkletTilbakekrevingVedtakService.oppdaterFritekstPåForenkletTilbakekrevingVedtak(behandlingId, restOppdaterForenkletTilbakekrevingVedtakFritekst.fritekst)
path: src/main/kotlin/no/nav/familie/ba/sak/kjerne/vedtak/forenklettilbakekrevingvedtak/ForenkletTilbakekrevingVedtakController.kt
user: login: stigebil
body: Jeg har samme bekymring for alle eksisterende fritekstfelt også.
created_at: 2025-03-05T09:54:14Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-03-05T18:41:36Z
body: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=navikt_familie-ba-sak&pullRequest=5140) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [42.9% Coverage on New Code](https://sonarcloud.io/component_measures?id=navikt_familie-ba-sak&pullRequest=5140&metric=new_coverage&view=list) (required ≥ 70%)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [E Reliability Rating on New Code](https://sonarcloud.io/dashboard?id=navikt_familie-ba-sak&pullRequest=5140) (required ≥ A)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=navikt_familie-ba-sak&pullRequest=5140)

##   
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png '') Catch issues before they fail your Quality Gate with our IDE extension ![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png '') [SonarQube for IDE](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)


author_association: NONE