Skip to content

Commit

Permalink
Merge pull request #812 from navikt/soft-delete-permanent
Browse files Browse the repository at this point in the history
SoftDelete hendelse sletter notifikasjon og sak fra produsent databasen
  • Loading branch information
anderslysne authored Jan 3, 2025
2 parents 9be3dc0 + 677d262 commit 188d8fe
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 87 deletions.
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 = ?
) 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

0 comments on commit 188d8fe

Please sign in to comment.