diff --git a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/Feilretting.kt b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/Feilretting.kt new file mode 100644 index 00000000..26e4b66f --- /dev/null +++ b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/Feilretting.kt @@ -0,0 +1,66 @@ +package no.nav.paw.arbeidssokerregisteret.application + +import no.nav.paw.arbeidssoekerregisteret.api.startstopp.models.Feilretting.FeilType +import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.AvviksType +import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.TidspunktFraKilde +import no.nav.paw.arbeidssoekerregisteret.api.startstopp.models.Feilretting as ApiFeilretting +import java.time.Instant + +sealed interface Feilretting + +data class Feilregistrering( + val melding: String? = null +): Feilretting + +data class FeilTidspunkt( + val melding: String?, + val tidspunkt: Instant +): Feilretting + +data class UgyldigFeilretting(val grunn: String) : Feilretting + +val Feilretting?.tidspunkt: Instant? get() = when (this) { + is FeilTidspunkt -> tidspunkt + else -> null +} + +val Feilretting?.aarsak get() = when (this) { + is Feilregistrering -> "Feilregistrering${this.melding?.let { ": $it" } ?: ""}" + is FeilTidspunkt -> "FeilTidspunkt${this.melding?.let { ": $it" } ?: ""}" + else -> null +} + +val Feilretting?.tidspunktFraKilde get() = when (this) { + is FeilTidspunkt -> TidspunktFraKilde( + tidspunkt = tidspunkt, + avviksType = AvviksType.RETTING + ) + is Feilregistrering -> TidspunktFraKilde( + tidspunkt = Instant.now(), + avviksType = AvviksType.RETTING + ) + else -> null +} + +fun feilretting(apiObj: ApiFeilretting?): Feilretting? { + if (apiObj == null) return null + when (apiObj.feilType) { + FeilType.FeilTidspunkt -> { + if (apiObj.tidspunkt == null) { + return UgyldigFeilretting("FeilTidspunkt må ha tidspunkt") + } + return FeilTidspunkt(apiObj.melding, apiObj.tidspunkt) + } + FeilType.Feilregistrering -> { + when { + apiObj.tidspunkt != null -> { + return UgyldigFeilretting("Feilregistrering kan ikke ha tidspunkt") + } + else -> { + return Feilregistrering(apiObj.melding) + } + } + } + } +} + diff --git a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RequestValidator.kt b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RequestValidator.kt index 031efb00..14549d38 100644 --- a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RequestValidator.kt +++ b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RequestValidator.kt @@ -30,15 +30,15 @@ class RequestValidator( fun validerTilgang( requestScope: RequestScope, identitetsnummer: Identitetsnummer, - erForhaandsGodkjentAvVeileder: Boolean = false + erForhaandsGodkjentAvVeileder: Boolean = false, + feilretting: Feilretting? = null ): Either, GrunnlagForGodkjenning> { val autentiseringsFakta = requestScope.tokenXPidFakta(identitetsnummer) + sjekkOmNavAnsattHarTilgang(requestScope, identitetsnummer) + - if (erForhaandsGodkjentAvVeileder) { - setOf(DomeneOpplysning.ErForhaandsgodkjent) - } else { - emptySet() - } + listOfNotNull( + if (erForhaandsGodkjentAvVeileder) DomeneOpplysning.ErForhaandsgodkjent else null, + feilretting?.let { DomeneOpplysning.ErFeilretting } + ) return TilgangsRegler.evaluer(autentiseringsFakta) } diff --git a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/ResultatTilHendelse.kt b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/ResultatTilHendelse.kt index 8acff077..9a0b552c 100644 --- a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/ResultatTilHendelse.kt +++ b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/ResultatTilHendelse.kt @@ -20,7 +20,13 @@ import java.util.* import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.Opplysning as HendelseOpplysning -fun stoppResultatSomHendelse(requestScope: RequestScope, id: Long, identitetsnummer: Identitetsnummer, resultat: Either, GrunnlagForGodkjenning>): Hendelse = +fun stoppResultatSomHendelse( + requestScope: RequestScope, + id: Long, + identitetsnummer: Identitetsnummer, + resultat: Either, GrunnlagForGodkjenning>, + feilretting: Feilretting? +): Hendelse = when (resultat) { is Either.Left -> AvvistStoppAvPeriode( id = id, @@ -39,7 +45,8 @@ fun stoppResultatSomHendelse(requestScope: RequestScope, id: Long, identitetsnum identitetsnummer = identitetsnummer.verdi, metadata = hendelseMetadata( requestScope = requestScope, - aarsak = "Stopp av periode" + aarsak = feilretting.aarsak ?: "Stopp av periode", + tidspunktFraKilde = feilretting.tidspunktFraKilde ), opplysninger = resultat.value.opplysning.map(::mapToHendelseOpplysning).toSet(), ) @@ -100,11 +107,16 @@ fun opplysningerHendelse( ) ) -fun hendelseMetadata(requestScope: RequestScope, aarsak: String): Metadata = Metadata( +fun hendelseMetadata( + requestScope: RequestScope, + aarsak: String, + tidspunktFraKilde: TidspunktFraKilde? = null +): Metadata = Metadata( tidspunkt = Instant.now(), utfoertAv = requestScope.brukerFraClaims(), kilde = ApplicationInfo.id, - aarsak = aarsak + aarsak = aarsak, + tidspunktFraKilde = tidspunktFraKilde ) fun RequestScope.brukerFraClaims(): Bruker { diff --git a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/StartStoppRequestHandler.kt b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/StartStoppRequestHandler.kt index 65b0fa7f..a2f8c6c7 100644 --- a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/StartStoppRequestHandler.kt +++ b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/StartStoppRequestHandler.kt @@ -2,7 +2,6 @@ package no.nav.paw.arbeidssokerregisteret.application import arrow.core.Either import arrow.core.NonEmptyList -import io.micrometer.prometheusmetrics.PrometheusMeterRegistry import io.opentelemetry.instrumentation.annotations.WithSpan import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope @@ -40,10 +39,24 @@ class StartStoppRequestHandler( } @WithSpan - suspend fun avsluttArbeidssokerperiode(requestScope: RequestScope, identitetsnummer: Identitetsnummer): Either, GrunnlagForGodkjenning> { + suspend fun avsluttArbeidssokerperiode( + requestScope: RequestScope, + identitetsnummer: Identitetsnummer, + feilretting: Feilretting? + ): Either, GrunnlagForGodkjenning> { val (id, key) = kafkaKeysClient.getIdAndKey(identitetsnummer.verdi) - val tilgangskontrollResultat = requestValidator.validerTilgang(requestScope, identitetsnummer) - val hendelse = stoppResultatSomHendelse(requestScope, id, identitetsnummer, tilgangskontrollResultat) + val tilgangskontrollResultat = requestValidator.validerTilgang( + requestScope = requestScope, + identitetsnummer = identitetsnummer, + feilretting = feilretting + ) + val hendelse = stoppResultatSomHendelse( + requestScope = requestScope, + id = id, + identitetsnummer = identitetsnummer, + resultat = tilgangskontrollResultat, + feilretting = feilretting + ) val record = ProducerRecord( hendelseTopic, key, diff --git a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/regler/TilgangsRegler.kt b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/regler/TilgangsRegler.kt index 084f9dbb..a4267e62 100644 --- a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/regler/TilgangsRegler.kt +++ b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/regler/TilgangsRegler.kt @@ -15,6 +15,11 @@ object TilgangsRegler: Regler { AuthOpplysning.IkkeAnsatt, vedTreff = ::skalAvises ), + IkkeAnsattOgFeilretting( + DomeneOpplysning.ErFeilretting, + AuthOpplysning.IkkeAnsatt, + vedTreff = ::skalAvises + ), EndreEgenBruker( AuthOpplysning.SammeSomInnloggetBruker, AuthOpplysning.IkkeAnsatt, @@ -58,6 +63,10 @@ data object IkkeAnsattOgForhaandsgodkjentAvAnsatt : AuthRegelId { override val beskrivelse: String = "Ikke ansatt har satt forhaandsgodkjenningAvVeileder" } +data object IkkeAnsattOgFeilretting : AuthRegelId { + override val beskrivelse: String = "Ikke ansatt har satt feilretting" +} + data object AnsattHarTilgangTilBruker : AuthRegelId { override val beskrivelse: String = "Ansatt har tilgang til bruker" } diff --git a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/ArbeidssokerRoutesv2.kt b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/ArbeidssokerRoutesv2.kt index 76024b6a..221e5637 100644 --- a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/ArbeidssokerRoutesv2.kt +++ b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/ArbeidssokerRoutesv2.kt @@ -6,7 +6,7 @@ import no.nav.paw.arbeidssoekerregisteret.api.startstopp.models.ApiV2Arbeidssoke import no.nav.paw.arbeidssoekerregisteret.api.startstopp.models.ApiV2ArbeidssokerPeriodePutRequest.PeriodeTilstand import no.nav.paw.arbeidssokerregisteret.api.extensions.getId import no.nav.paw.arbeidssokerregisteret.application.StartStoppRequestHandler -import no.nav.paw.arbeidssokerregisteret.requestHandlers +import no.nav.paw.arbeidssokerregisteret.application.feilretting import no.nav.paw.arbeidssokerregisteret.requestScope import no.nav.paw.arbeidssokerregisteret.utils.logger @@ -42,7 +42,8 @@ fun Route.arbeidssokerRoutesV2( PeriodeTilstand.STOPPET -> startStoppRequestHandler.avsluttArbeidssokerperiode( requestScope = requestScope(), - identitetsnummer = startStoppRequest.getId() + identitetsnummer = startStoppRequest.getId(), + feilretting = feilretting(startStoppRequest.feilretting) ) } logger.debug("Registreringsresultat: {}", resultat) diff --git a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/StartStoppResultatMapping.kt b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/StartStoppResultatMapping.kt index 912fb1ef..e460ce2f 100644 --- a/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/StartStoppResultatMapping.kt +++ b/apps/api-start-stopp-perioder/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/routes/StartStoppResultatMapping.kt @@ -79,6 +79,7 @@ fun opplysningTilApiOpplysning(opplysning: Opplysning): ApiOpplysning = DomeneOpplysning.UkjentStatusForOppholdstillatelse -> ApiOpplysning.UKJENT_STATUS_FOR_OPPHOLDSTILLATELSE DomeneOpplysning.ErNorskStatsborger -> ApiOpplysning.ER_NORSK_STATSBORGER DomeneOpplysning.HarRegistrertAdresseIEuEoes -> ApiOpplysning.HAR_REGISTRERT_ADRESSE_I_EU_EOES + DomeneOpplysning.ErFeilretting -> ApiOpplysning.ER_FEILRETTING } is AuthOpplysning -> when (opplysning) { @@ -128,6 +129,7 @@ fun AuthRegelId.httpCode(): HttpStatusCode = when (this) { EndreForAnnenBruker -> HttpStatusCode.Forbidden IkkeAnsattOgForhaandsgodkjentAvAnsatt -> HttpStatusCode.BadRequest IkkeTilgang -> HttpStatusCode.Forbidden + IkkeAnsattOgFeilretting -> HttpStatusCode.Forbidden } fun DomeneRegelId.httpCode(): HttpStatusCode = when (this) { diff --git a/apps/api-start-stopp-perioder/src/main/resources/openapi/startstopp.yaml b/apps/api-start-stopp-perioder/src/main/resources/openapi/startstopp.yaml index 86b19af6..55b0550f 100644 --- a/apps/api-start-stopp-perioder/src/main/resources/openapi/startstopp.yaml +++ b/apps/api-start-stopp-perioder/src/main/resources/openapi/startstopp.yaml @@ -113,6 +113,9 @@ paths: enum: - "STARTET" - "STOPPET" + feilretting: + description: "Feilretting kan kun benyttes når innloget bruker er ansatt" + $ref: "#/components/schemas/Feilretting" required: - "identitetsnummer" - "periodeTilstand" @@ -150,6 +153,23 @@ paths: type: "object" components: schemas: + Feilretting: + type: "object" + required: + - "feilType" + properties: + feilType: + type: "string" + enum: + - "FeilTidspunkt" + - "Feilregistrering" + melding: + description: "Valgfri kommentar til feilretting" + type: "string" + tidspunkt: + description: "Tidspunkt som må brukes ved feilType=FeilTidspunkt" + type: "string" + format: "date-time" identitetsnummer: type: "string" pattern: "^[0-9]{11}$" @@ -233,6 +253,7 @@ components: - "ER_NORSK_STATSBORGER" - "HAR_REGISTRERT_ADRESSE_I_EU_EOES" - "UKJENT_OPPLYSNING" + - "ER_FEILRETTING" ApiRegelId: type: "string" enum: diff --git a/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RegelExtensions.kt b/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RegelExtensions.kt index bb320528..0892c7f6 100644 --- a/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RegelExtensions.kt +++ b/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/RegelExtensions.kt @@ -83,6 +83,7 @@ fun domeneOpplysningTilHendelseOpplysning(opplysning: DomeneOpplysning): Hendels DomeneOpplysning.UkjentStatusForOppholdstillatelse -> HendelseOpplysning.UKJENT_STATUS_FOR_OPPHOLDSTILLATELSE DomeneOpplysning.ErNorskStatsborger -> HendelseOpplysning.ER_NORSK_STATSBORGER DomeneOpplysning.HarRegistrertAdresseIEuEoes -> HendelseOpplysning.HAR_REGISTRERT_ADRESSE_I_EU_EOES + DomeneOpplysning.ErFeilretting -> HendelseOpplysning.ER_FEILRETTING } fun hendelseOpplysningTilDomeneOpplysninger(opplysning: HendelseOpplysning): DomeneOpplysning? = @@ -117,6 +118,7 @@ fun hendelseOpplysningTilDomeneOpplysninger(opplysning: HendelseOpplysning): Dom HendelseOpplysning.UKJENT_STATUS_FOR_OPPHOLDSTILLATELSE -> DomeneOpplysning.UkjentStatusForOppholdstillatelse HendelseOpplysning.ER_NORSK_STATSBORGER -> DomeneOpplysning.ErNorskStatsborger HendelseOpplysning.HAR_REGISTRERT_ADRESSE_I_EU_EOES -> DomeneOpplysning.HarRegistrertAdresseIEuEoes + no.nav.paw.arbeidssokerregisteret.intern.v1.vo.Opplysning.ER_FEILRETTING -> DomeneOpplysning.ErFeilretting HendelseOpplysning.SAMME_SOM_INNLOGGET_BRUKER -> null HendelseOpplysning.IKKE_SAMME_SOM_INNLOGGER_BRUKER -> null HendelseOpplysning.ANSATT_IKKE_TILGANG -> null diff --git a/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/opplysninger/Opplysninger.kt b/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/opplysninger/Opplysninger.kt index 70d099ee..b53fb2f1 100644 --- a/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/opplysninger/Opplysninger.kt +++ b/domain/arbeidssoeker-regler/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/application/opplysninger/Opplysninger.kt @@ -16,6 +16,11 @@ sealed interface DomeneOpplysning: Opplysning { override val beskrivelse = "Registrering er forhåndsgodkjent av NAV-ansatt" } + data object ErFeilretting: DomeneOpplysning, Effect.Neutral { + override val id = "FEILRETTING" + override val beskrivelse = "Operasjonen er en feilretting" + } + data object ErOver18Aar : DomeneOpplysning, Effect.Positive { override val id = "ER_OVER_18_AAR" override val beskrivelse = "Personen start/stopp av periode utføres på er over 18 år" diff --git a/domain/interne-hendelser/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/intern/v1/vo/Opplysning.kt b/domain/interne-hendelser/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/intern/v1/vo/Opplysning.kt index 04678ac7..de99e22b 100644 --- a/domain/interne-hendelser/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/intern/v1/vo/Opplysning.kt +++ b/domain/interne-hendelser/src/main/kotlin/no/nav/paw/arbeidssokerregisteret/intern/v1/vo/Opplysning.kt @@ -38,6 +38,7 @@ enum class Opplysning { ER_EU_EOES_STATSBORGER, ER_GBR_STATSBORGER, ER_NORSK_STATSBORGER, + ER_FEILRETTING, @JsonEnumDefaultValue UKJENT_OPPLYSNING } \ No newline at end of file