Skip to content

Commit

Permalink
TB-71 Legg til mulighet for å legge ved hvem som er eier på en egenre…
Browse files Browse the repository at this point in the history
…gistrering (#107)

* TB-71 WIP

* add Eier/RegistrertAv from registrering all the way to bygning out, wip

* more consistent test naming

* simplify registrant on egenregistrering in/out, fix bruksenhetregistreringer to also have metadata

* don't use single line return this for ease of reading

* use norwegian commons fodselsnummer validator instead of our own

* fix formatting

* create sealed class for registreringsaktoer for allowing registrertAv to be both a fødselsnummer and signature from matrikkelen

* formatting and member import for readability

* do not allow nullability for registrertAv response, it is never null

---------

Co-authored-by: Henrik Wingerei <henrik.wingerei@kartverket.no>
  • Loading branch information
anderssonw and henriwi authored Oct 9, 2024
1 parent 644044a commit d7bd1c5
Show file tree
Hide file tree
Showing 20 changed files with 223 additions and 96 deletions.
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ dependencies {

// OpenAPI
implementation(libs.kompendium.core)

// Norwegian Commons
implementation(libs.norwegian.commons)
}

tasks {
Expand Down
5 changes: 3 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ logbackVersion = "1.5.9"
logstashVersion = "8.0"
prometheusVersion = "1.13.5"
flywayVersion = "10.19.0"
jacksonVersion = "2.18.0"
postgresVersion = "42.7.4"
shadowVersion = "8.1.1"
kompendiumVersion = "3.14.4"
Expand All @@ -14,6 +13,7 @@ hikariVersion = "6.0.0"
testcontainersVersion = "1.20.2"
mockkVersion = "1.13.12"
assertkVersion = "0.28.1"
norwegianCommonsVersion = "0.16.0"

[libraries]
ktor-server-core = { group = "io.ktor", name = "ktor-server-core-jvm", version.ref = "ktorVersion" }
Expand All @@ -36,7 +36,6 @@ flyway-database-postgresql = { group = "org.flywaydb", name = "flyway-database-p
micrometer-prometheus = { group = "io.micrometer", name = "micrometer-registry-prometheus", version.ref = "prometheusVersion" }
logstash-encoder = { group = "net.logstash.logback", name = "logstash-logback-encoder", version.ref = "logstashVersion" }
logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "logbackVersion" }
jackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind", version.ref = "jacksonVersion" }
postgres = { group = "org.postgresql", name = "postgresql", version.ref = "postgresVersion" }
kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit5", version.ref = "kotlinVersion" }
kompendium-core = { group = "io.bkbn", name = "kompendium-core", version.ref = "kompendiumVersion" }
Expand All @@ -49,6 +48,8 @@ mockk = { group = "io.mockk", name = "mockk", version.ref = "mockkVersion" }
mockk-dsl = { group = "io.mockk", name = "mockk-dsl", version.ref = "mockkVersion" }
assertk = { group = "com.willowtreeapps.assertk", name = "assertk", version.ref = "assertkVersion" }

norwegian-commons = { group = "no.bekk.bekkopen", name = "nocommons", version.ref = "norwegianCommonsVersion" }

[plugins]
kotlin-jvm = { id = "jvm", version.ref = "kotlinVersion" }
kotlin-serialization = { id = "plugin.serialization", version.ref = "kotlinVersion" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import assertk.assertions.single
import no.kartverket.matrikkel.bygning.models.BruksarealRegistrering
import no.kartverket.matrikkel.bygning.models.BygningRegistrering
import no.kartverket.matrikkel.bygning.models.Egenregistrering
import no.kartverket.matrikkel.bygning.models.RegistreringAktoer
import no.kartverket.matrikkel.bygning.models.RegistreringAktoer.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.time.Instant
Expand All @@ -33,6 +35,7 @@ class EgenregistreringRepositoryTest : TestWithDb() {
private val defaultEgenregistrering = Egenregistrering(
id = UUID.randomUUID(),
registreringstidspunkt = Instant.parse("2024-01-01T12:00:00.00Z"),
eier = Foedselsnummer("31129956715"),
bygningRegistrering = defaultBygningRegistrering,
)

Expand All @@ -47,6 +50,7 @@ class EgenregistreringRepositoryTest : TestWithDb() {
assertThat(bygningRegistreringer).single().all {
prop(Egenregistrering::id).isEqualTo(defaultEgenregistrering.id)
prop(Egenregistrering::registreringstidspunkt).isEqualTo(defaultEgenregistrering.registreringstidspunkt)
prop(Egenregistrering::eier).isEqualTo(defaultEgenregistrering.eier)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,41 @@ class EgenregistreringRouteTest : TestApplicationWithDb() {
}
}

@Test
fun `gitt at egenregistrering sender info om hvem har registrert blir dette lagret og sendt ut igjen`() =
testApplication {
val client = mainModuleWithDatabaseEnvironmentAndClient()

val response = client.post("/v1/egenregistreringer") {
contentType(ContentType.Application.Json)
setBody(
EgenregistreringRequest.validEgenregistrering().copy(
eier = "31129956715",
),
)
}

assertThat(response.status).isEqualTo(HttpStatusCode.Created)

val bygningResponse = client.get("/v1/bygninger/1")

assertThat(bygningResponse.status).isEqualTo(HttpStatusCode.OK)
val bygning = bygningResponse.body<BygningResponse>()

assertThat(bygning).all {
prop(BygningResponse::bruksareal).isNotNull().all {
prop(MultikildeResponse<BruksarealResponse>::egenregistrert).isNotNull().all {
prop(BruksarealResponse::metadata).all {
prop(RegisterMetadataResponse::registrertAv).isEqualTo("31129956715")
}
}
}
}
}

private fun EgenregistreringRequest.Companion.validEgenregistrering() = EgenregistreringRequest(
bygningId = 1L,
eier = "31129956715",
bygningRegistrering = BygningRegistreringRequest(
bruksarealRegistrering = BruksarealRegistreringRequest(125.0),
byggeaarRegistrering = ByggeaarRegistreringRequest(2010),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package no.kartverket.matrikkel.bygning.matrikkel.adapters

import no.kartverket.matrikkel.bygning.matrikkel.BygningClient
import no.kartverket.matrikkel.bygning.models.Bruksareal
import no.kartverket.matrikkel.bygning.models.Bruksenhet
import no.kartverket.matrikkel.bygning.models.Bygning
import no.kartverket.matrikkel.bygning.models.Multikilde
import no.kartverket.matrikkel.bygning.models.RegisterMetadata
import no.kartverket.matrikkel.bygning.models.RegistreringAktoer.*
import java.time.Instant

internal class LocalBygningClient : BygningClient {
private val bruksenheter: List<Bruksenhet> = listOf(
Expand All @@ -29,6 +34,15 @@ internal class LocalBygningClient : BygningClient {
bygningId = 1L,
bygningsnummer = 100L,
bruksenheter = bruksenheter.subList(0, 2),
bruksareal = Multikilde(
autoritativ = Bruksareal(
data = 150.0,
metadata = RegisterMetadata(
registreringstidspunkt = Instant.parse("2024-01-01T12:00:00.00Z"),
registrertAv = Signatur("norola"),
),
),
),
),
Bygning(
bygningId = 2L,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import no.kartverket.matrikkel.bygning.models.Energikilde
import no.kartverket.matrikkel.bygning.models.Multikilde
import no.kartverket.matrikkel.bygning.models.Oppvarming
import no.kartverket.matrikkel.bygning.models.RegisterMetadata
import no.kartverket.matrikkel.bygning.models.RegistreringAktoer.*
import no.kartverket.matrikkel.bygning.models.Vannforsyning
import no.statkart.matrikkel.matrikkelapi.wsapi.v1.domain.bygning.BygningId
import no.statkart.matrikkel.matrikkelapi.wsapi.v1.service.store.ServiceException
Expand All @@ -37,7 +38,9 @@ internal class MatrikkelBygningClient(

val bygningsmetadata = RegisterMetadata(
bygning.oppdateringsdato.toInstant(),
Signatur(bygning.oppdatertAv),
)

return Bygning(
bygningId = bygning.id.value,
bygningsnummer = bygning.bygningsnummer,
Expand Down Expand Up @@ -96,7 +99,9 @@ internal class MatrikkelBygningClient(
bruksenheter = bruksenheter.map {
val bruksenhetsmetadata = RegisterMetadata(
it.oppdateringsdato.toInstant(),
Signatur(it.oppdatertAv),
)

Bruksenhet(
bruksenhetId = it.id.value,
bygningId = it.byggId.value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@ data class Bygning(
val oppvarminger: Multikilde<List<Oppvarming>> = Multikilde(),
val vannforsyning: Multikilde<Vannforsyning> = Multikilde(),
val avlop: Multikilde<Avlop> = Multikilde(),
) {
fun withBruksenheter(bruksenheter: List<Bruksenhet>): Bygning {
return this.copy(
bruksenheter = bruksenheter,
)
}
}
)

data class Multikilde<T : Any>(val autoritativ: T? = null, val egenregistrert: T? = null) {
fun withEgenregistrert(verdi: T?): Multikilde<T> = copy(egenregistrert = verdi)
}

data class RegisterMetadata(val registreringstidspunkt: Instant)
data class RegisterMetadata(
val registreringstidspunkt: Instant,
val registrertAv: RegistreringAktoer
)

data class Bruksareal(val data: Double?, val metadata: RegisterMetadata)
data class Byggeaar(val data: Int?, val metadata: RegisterMetadata)
data class Vannforsyning(val data: VannforsyningKode?, val metadata: RegisterMetadata)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,105 +7,99 @@ package no.kartverket.matrikkel.bygning.models

fun Bygning.withEgenregistrertData(egenregistreringer: List<Egenregistrering>): Bygning {
return egenregistreringer.fold(this) { bygningAggregate, egenregistrering ->
val metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.registreringstidspunkt,
registrertAv = egenregistrering.eier,
)

bygningAggregate.copy(
byggeaar = bygningAggregate.byggeaar.aggregate {
egenregistrering.bygningRegistrering.byggeaarRegistrering?.let {
Byggeaar(
data = it.byggeaar,
metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.registreringstidspunkt,
),
metadata = metadata,
)
}
},
bruksareal = bygningAggregate.bruksareal.aggregate {
egenregistrering.bygningRegistrering.bruksarealRegistrering?.let {
Bruksareal(
data = it.bruksareal,
metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.registreringstidspunkt,
),
metadata = metadata,
)
}
},
vannforsyning = bygningAggregate.vannforsyning.aggregate {
egenregistrering.bygningRegistrering.vannforsyningRegistrering?.let {
Vannforsyning(
data = it.vannforsyning,
metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.registreringstidspunkt,
),
metadata = metadata,
)
}
},
avlop = bygningAggregate.avlop.aggregate {
egenregistrering.bygningRegistrering.avlopRegistrering?.let {
Avlop(
data = it.avlop,
metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.registreringstidspunkt,
),
metadata = metadata,
)
}
},
bruksenheter = bygningAggregate.bruksenheter.map {
it.applyEgenregistrering(egenregistrering)
},
)
}
}


fun Bruksenhet.withEgenregistrertData(egenregistreringer: List<Egenregistrering>): Bruksenhet {
// Her så antar jeg at man bare har registrert bruksenheten én gang per registrering, som gir mening
// Likevel har vi ikke noen logisk sjekk på dette ved registrering, så det bør vi nok ha
val bruksenhetRegistreringer = egenregistreringer.mapNotNull { egenregistrering ->
val bruksenhetRegistrering =
egenregistrering.bygningRegistrering.bruksenhetRegistreringer.firstOrNull { it.bruksenhetId == this.bruksenhetId }

if (bruksenhetRegistrering != null) {
egenregistrering.registreringstidspunkt to bruksenhetRegistrering
} else {
null
}
private fun Bruksenhet.applyEgenregistrering(egenregistrering: Egenregistrering): Bruksenhet {
val bruksenhetRegistrering =
egenregistrering.bygningRegistrering.bruksenhetRegistreringer.firstOrNull { it.bruksenhetId == this.bruksenhetId }
if (bruksenhetRegistrering == null) {
return this
}

// Jeg er litt usikker på om det er nødvendig å filtrere ut og lage et Pair, så folde på bare bruksenhetregistreringene
// fremfor å gjøre det på hele bygningregistreringen dersom vi legger til logikk for å kun godkjenne én registrering
return bruksenhetRegistreringer.fold(this) { bruksenhetAggregate, egenregistrering ->
bruksenhetAggregate.copy(
bruksareal = bruksenhetAggregate.bruksareal.aggregate {
egenregistrering.second.bruksarealRegistrering?.let {
Bruksareal(
data = it.bruksareal,
metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.first,
),
val metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.registreringstidspunkt,
registrertAv = egenregistrering.eier,
)

return this.copy(
bruksareal = this.bruksareal.aggregate {
bruksenhetRegistrering.bruksarealRegistrering?.let {
Bruksareal(
data = it.bruksareal,
metadata = metadata,
)
}
},
energikilder = this.energikilder.aggregate {
bruksenhetRegistrering.energikildeRegistrering?.let {
it.energikilder?.map { registrertKilde ->
Energikilde(
data = registrertKilde,
metadata = metadata,
)
}
},
energikilder = bruksenhetAggregate.energikilder.aggregate {
egenregistrering.second.energikildeRegistrering?.let {
it.energikilder?.map { registrertKilde ->
Energikilde(
data = registrertKilde,
metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.first,
),
)
}
}
},
oppvarminger = bruksenhetAggregate.oppvarminger.aggregate {
egenregistrering.second.oppvarmingRegistrering?.let {
it.oppvarminger?.map { registrertOppvarming ->
Oppvarming(
data = registrertOppvarming,
metadata = RegisterMetadata(
registreringstidspunkt = egenregistrering.first,
),
)
}
}
},
oppvarminger = this.oppvarminger.aggregate {
bruksenhetRegistrering.oppvarmingRegistrering?.let {
it.oppvarminger?.map { registrertOppvarming ->
Oppvarming(
data = registrertOppvarming,
metadata = metadata,
)
}
},
)
}
},
)
}


fun Bruksenhet.withEgenregistrertData(egenregistreringer: List<Egenregistrering>): Bruksenhet {
return egenregistreringer.fold(this) { bruksenhetAggregate, egenregistrering ->
bruksenhetAggregate.applyEgenregistrering(egenregistrering)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package no.kartverket.matrikkel.bygning.models

import kotlinx.serialization.Serializable
import no.kartverket.matrikkel.bygning.models.RegistreringAktoer.*
import no.kartverket.matrikkel.bygning.models.kodelister.AvlopKode
import no.kartverket.matrikkel.bygning.models.kodelister.EnergikildeKode
import no.kartverket.matrikkel.bygning.models.kodelister.OppvarmingKode
Expand Down Expand Up @@ -57,9 +58,9 @@ data class BruksenhetRegistrering(
val oppvarmingRegistrering: OppvarmingRegistrering?,
)


data class Egenregistrering(
val id: UUID,
val eier: Foedselsnummer,
val registreringstidspunkt: Instant,
val bygningRegistrering: BygningRegistrering,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.kartverket.matrikkel.bygning.models

import no.bekk.bekkopen.person.FodselsnummerValidator

sealed class RegistreringAktoer {
abstract val value: String

data class Foedselsnummer(override val value: String) : RegistreringAktoer() {
init {
if (!FodselsnummerValidator.isValid(value)) {
throw IllegalArgumentException("Fødselsnummer er ikke gyldig")
}
}

fun getMaskedValue(): String = value.replace(Regex("\\d"), "*")
}

data class Signatur(override val value: String) : RegistreringAktoer()
}
Loading

0 comments on commit d7bd1c5

Please sign in to comment.