Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoftDelete hendelse sletter notifikasjon og sak fra produsent databasen #812

Merged
merged 2 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface ProdusentRepository {
SAK,
BESKJED,
OPPGAVE,
KALENDERAVTALE
}

suspend fun hentNotifikasjon(id: UUID): ProdusentModel.Notifikasjon?
Expand Down Expand Up @@ -324,8 +325,8 @@ class ProdusentRepositoryImpl(
is OppgaveUtgått -> oppdaterModellEtterOppgaveUtgått(hendelse)
is PåminnelseOpprettet -> /* Ignorer */ Unit
is BrukerKlikket -> /* Ignorer */ Unit
is SoftDelete -> oppdaterModellEtterSoftDelete(hendelse)
is HardDelete -> oppdaterModellEtterHardDelete(hendelse)
is SoftDelete -> oppdaterModellEtterDelete(aggregateId = hendelse.aggregateId, merkelapp = hendelse.merkelapp, grupperingsid = hendelse.grupperingsid)
is HardDelete -> oppdaterModellEtterDelete(aggregateId = hendelse.aggregateId, merkelapp = hendelse.merkelapp, grupperingsid = hendelse.grupperingsid)
is EksterntVarselVellykket -> oppdaterModellEtterEksterntVarselVellykket(hendelse)
is EksterntVarselFeilet -> oppdaterModellEtterEksterntVarselFeilet(hendelse)
is EksterntVarselKansellert -> oppdaterModellEtterEksterntVarselKansellert(hendelse)
Expand Down Expand Up @@ -460,7 +461,7 @@ class ProdusentRepositoryImpl(
}
}

private suspend fun oppdaterModellEtterNesteStegSak(nesteStegSak: HendelseModel.NesteStegSak) {
private suspend fun oppdaterModellEtterNesteStegSak(nesteStegSak: NesteStegSak) {
database.transaction {
executeUpdate(
"""
Expand Down Expand Up @@ -491,21 +492,24 @@ class ProdusentRepositoryImpl(
}
}

private suspend fun oppdaterModellEtterHardDelete(hardDelete: HardDelete) {
private suspend fun oppdaterModellEtterDelete(aggregateId: UUID, merkelapp: String?, grupperingsid: String?) {
database.transaction {
registrerDelete(this, hardDelete.aggregateId)
registrerDelete(this, aggregateId)
executeQuery("""
select aggregate_type from (
select 'SAK' as aggregate_type from sak where id = ?
union
select 'BESKJED' as aggregate_type from notifikasjon where id = ?
union
select 'OPPGAVE' as aggregate_type from notifikasjon where id = ?
union
select 'KALENDERAVTALE' as aggregate_type from notifikasjon where id = ?
anderslysne marked this conversation as resolved.
Show resolved Hide resolved
) as aggregate_type
""", setup = {
uuid(hardDelete.aggregateId)
uuid(hardDelete.aggregateId)
uuid(hardDelete.aggregateId)
uuid(aggregateId)
uuid(aggregateId)
uuid(aggregateId)
uuid(aggregateId)
}, transform = {
AggregateType.valueOf(getString("aggregate_type"))
}).firstOrNull()?.let {
Expand All @@ -517,18 +521,18 @@ class ProdusentRepositoryImpl(
values (?, ?, ?, ?);
"""
) {
uuid(hardDelete.aggregateId)
uuid(aggregateId)
text(it.name)
nullableText(hardDelete.merkelapp)
nullableText(hardDelete.grupperingsid)
nullableText(merkelapp)
nullableText(grupperingsid)
}
}

if (hardDelete.grupperingsid != null && hardDelete.merkelapp != null) {
if (grupperingsid != null && merkelapp != null) {
// cascade hard delete av sak med grupperingsid og merkelapp
executeUpdate("""delete from notifikasjon n where n.grupperingsid = ? and merkelapp = ?;""") {
text(hardDelete.grupperingsid)
text(hardDelete.merkelapp)
text(grupperingsid)
text(merkelapp)
}
}
executeUpdate(
Expand All @@ -537,69 +541,31 @@ class ProdusentRepositoryImpl(
where id = ?
"""
) {
uuid(hardDelete.aggregateId)
uuid(aggregateId)
}
executeUpdate(
"""
delete from sak
where id = ?
"""
) {
uuid(hardDelete.aggregateId)
uuid(aggregateId)
}
executeUpdate(
"""
delete from eksternt_varsel
where notifikasjon_id = ?
"""
) {
uuid(hardDelete.aggregateId)
uuid(aggregateId)
}
executeUpdate(
"""
delete from paaminnelse_eksternt_varsel
where notifikasjon_id = ?
"""
) {
uuid(hardDelete.aggregateId)
}
}
}

private suspend fun oppdaterModellEtterSoftDelete(softDelete: SoftDelete) {
database.transaction {
executeUpdate(
"""
UPDATE notifikasjon
SET deleted_at = ?
WHERE id = ?
"""
) {
timestamp_with_timezone(softDelete.deletedAt)
uuid(softDelete.aggregateId)
}
if (softDelete.grupperingsid !== null && softDelete.merkelapp !== null) {
executeUpdate(
"""
update notifikasjon
SET deleted_at = ?
WHERE grupperingsid = ? AND merkelapp = ?
""".trimIndent()
) {
timestamp_with_timezone(softDelete.deletedAt)
text(softDelete.grupperingsid)
text(softDelete.merkelapp)
}
}
executeUpdate(
"""
UPDATE sak
SET deleted_at = ?
WHERE id = ?
"""
) {
timestamp_with_timezone(softDelete.deletedAt)
uuid(softDelete.aggregateId)
uuid(aggregateId)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package no.nav.arbeidsgiver.notifikasjon.produsent.api

import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.types.instanceOf
import io.ktor.server.testing.*
import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.AltinnMottaker
Expand Down Expand Up @@ -63,7 +62,7 @@ class SoftDeleteNotifikasjonTests : DescribeSpec({
describe("SoftDelete-oppførsel") {


context("Eksisterende oppgave blir markert som slettet") {
context("Eksisterende oppgave blir slettet") {
val (produsentModel, kafkaProducer, engine) = setupEngine()


Expand Down Expand Up @@ -98,17 +97,17 @@ class SoftDeleteNotifikasjonTests : DescribeSpec({
}
}

it("har slettet-status i modellen") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid)!!
notifikasjon.deletedAt shouldNotBe null
it("har blitt slettet i modellen") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid)
notifikasjon shouldBe null
}
it("notifikasjon2 har ikke slettet-status i modellen") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid2)!!
notifikasjon.deletedAt shouldBe null
}


it("mineNotifikasjoner rapporterer som softDeleted") {
it("mineNotifikasjoner rapporterer ikke lenger notifikasjon") {
val response = engine.produsentApi(
"""
query {
Expand Down Expand Up @@ -226,10 +225,9 @@ class SoftDeleteNotifikasjonTests : DescribeSpec({
response.getTypedContent<QueryNotifikasjoner.NotifikasjonConnection>("mineNotifikasjoner")
.edges
.map { it.node }
.find { it.id == uuid }!!
.find { it.id == uuid }

slettetNotifikasjon.metadata.softDeleted shouldBe true
slettetNotifikasjon.metadata.softDeletedAt shouldNotBe null
slettetNotifikasjon shouldBe null
}
}

Expand Down Expand Up @@ -287,7 +285,7 @@ class SoftDeleteNotifikasjonTests : DescribeSpec({
val response = engine.produsentApi(
"""
mutation {
softDeleteNotifikasjonByEksternId(eksternId: "$eksternId", merkelapp: "$merkelapp") {
softDeleteNotifikasjonByEksternId_V2(eksternId: "$eksternId", merkelapp: "$merkelapp") {
__typename
... on SoftDeleteNotifikasjonVellykket {
id
Expand All @@ -302,7 +300,7 @@ class SoftDeleteNotifikasjonTests : DescribeSpec({

it("returnerer tilbake id-en") {
val vellykket =
response.getTypedContent<MutationSoftDeleteNotifikasjon.SoftDeleteNotifikasjonVellykket>("softDeleteNotifikasjonByEksternId")
response.getTypedContent<MutationSoftDeleteNotifikasjon.SoftDeleteNotifikasjonVellykket>("softDeleteNotifikasjonByEksternId_V2")
vellykket.id shouldBe uuid
}

Expand All @@ -312,9 +310,9 @@ class SoftDeleteNotifikasjonTests : DescribeSpec({
}
}

it("har fått slettet tidspunkt") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid)!!
notifikasjon.deletedAt shouldNotBe null
it("har blitt slettet i modellen") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid)
notifikasjon shouldBe null
}
it("oppgave 2 har ikke fått slettet tidspunkt") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid2)!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package no.nav.arbeidsgiver.notifikasjon.produsent.api

import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.types.instanceOf
import io.ktor.server.testing.*
import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel
Expand Down Expand Up @@ -140,9 +139,9 @@ class SoftDeleteSakTests : DescribeSpec({
}
}

it("har slettet-status i modellen") {
val notifikasjon = produsentModel.hentSak(uuid)!!
notifikasjon.deletedAt shouldNotBe null
it("har blitt slettet i modellen") {
val notifikasjon = produsentModel.hentSak(uuid)
notifikasjon shouldBe null
}
it("notifikasjon2 har ikke slettet-status i modellen") {
val notifikasjon = produsentModel.hentSak(uuid2)!!
Expand Down Expand Up @@ -193,7 +192,7 @@ class SoftDeleteSakTests : DescribeSpec({
}

context("SoftDelete cascader fra sak til notifikasjoner"){
val (produsentModel, kafkaProducer, engine) = setupEngine()
val (produsentModel, _, engine) = setupEngine()
produsentModel.oppdaterModellEtterHendelse(sakOpprettet)
produsentModel.oppdaterModellEtterHendelse(sakOpprettet2)
produsentModel.oppdaterModellEtterHendelse(oppgaveOpprettet)
Expand Down Expand Up @@ -224,8 +223,8 @@ class SoftDeleteSakTests : DescribeSpec({
}

it ("oppgave er slettet") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid3)!!
notifikasjon.deletedAt shouldNotBe null
val notifikasjon = produsentModel.hentNotifikasjon(uuid3)
notifikasjon shouldBe null
}

it ("oppgave 2 er ikke slettet") {
Expand All @@ -234,8 +233,8 @@ class SoftDeleteSakTests : DescribeSpec({
}

it ("beskjed er slettet") {
val notifikasjon = produsentModel.hentNotifikasjon(uuid5)!!
notifikasjon.deletedAt shouldNotBe null
val notifikasjon = produsentModel.hentNotifikasjon(uuid5)
notifikasjon shouldBe null
}
}
}
Expand Down Expand Up @@ -276,9 +275,9 @@ class SoftDeleteSakTests : DescribeSpec({
}
}

it("har fått slettet tidspunkt") {
val notifikasjon = produsentModel.hentSak(uuid)!!
notifikasjon.deletedAt shouldNotBe null
it("har blitt slettet i modellen") {
val notifikasjon = produsentModel.hentSak(uuid)
notifikasjon shouldBe null
}
it("oppgave 2 har ikke fått slettet tidspunkt") {
val notifikasjon = produsentModel.hentSak(uuid2)!!
Expand Down
60 changes: 57 additions & 3 deletions test-produsent/src/Komponenter/AdHoc.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import { Button, Textarea } from "@navikt/ds-react";
import {gql, useLazyQuery} from "@apollo/client";
import { gql, useLazyQuery, useMutation } from '@apollo/client';

const defaultQueryString = `query init {whoami}`
const initQuery = gql`${defaultQueryString}`

export const AdHoc: React.FunctionComponent = () => {
export const AdHocQuery: React.FunctionComponent = () => {
const [executeQuery, { loading, error: apolloError, data }] = useLazyQuery(initQuery);

const [variables, setVariables] = React.useState("");
Expand All @@ -23,7 +23,7 @@ export const AdHoc: React.FunctionComponent = () => {
});
setError(null)
} catch (error) {
setError(`Feilet parsing. Skriv i JSON-format {"{\"key\":\"value\"}"} ${error}`)
setError(`Feilet parsing. Skriv i JSON-format {"key":"value"} ${error}`)
}
};

Expand Down Expand Up @@ -57,4 +57,58 @@ export const AdHoc: React.FunctionComponent = () => {
</div>
</>
);
};

export const AdHocMutation: React.FunctionComponent = () => {
const [executeMutation, { loading, error: apolloError, data }] = useMutation(gql("mutation {whoami}"));

const [variables, setVariables] = React.useState("");
const [mutation, setMutation] = React.useState("");
const [error, setError] = React.useState<string | null>(null);
const handleRunMutation = async () => {
try {
const parsedVariables = variables !== "" ? JSON.parse(variables) : {};
if (mutation === "") {
setError("Skriv inn en mutation ")
}
await executeMutation({
variables: parsedVariables,
mutation: gql`${mutation}`,
});
setError(null)
} catch (error) {
setError(`Feilet parsing. Skriv i JSON-format {"key":"value"} ${error}`)
}
};

return (
<>
<div style={{
display: "flex",
flexDirection: "column",
gap: "16px"

}}>
<Textarea
value={mutation}
onChange={(e) => setMutation(e.target.value)}
label="Skriv inn GraphQL-query her"
/>
<Textarea
value={variables}
onChange={(e) => setVariables(e.target.value)}
label="Fyll inn variablene her (JSON-format)"
/>
<Button onClick={handleRunMutation} disabled={loading}>
Kjør Query
</Button>
</div>
<div>
{loading && <p>Laster...</p>}
{apolloError && <p>Error: {apolloError.message}</p>}
{error && <p>{error}</p>}
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
</div>
</>
);
};
Loading
Loading