diff --git a/build.gradle.kts b/build.gradle.kts index 0045aa6e..dc472a88 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -55,6 +55,9 @@ dependencies { // OpenAPI implementation(libs.kompendium.core) + + // Norwegian Commons + implementation(libs.norwegian.commons) } tasks { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e4d32588..bace5479 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" @@ -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" } @@ -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" } @@ -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" } diff --git a/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepositoryTest.kt b/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepositoryTest.kt index 1b75ece6..3a2d002c 100644 --- a/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepositoryTest.kt +++ b/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepositoryTest.kt @@ -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 @@ -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, ) @@ -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) } } diff --git a/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/v1/egenregistrering/EgenregistreringRouteTest.kt b/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/v1/egenregistrering/EgenregistreringRouteTest.kt index de807052..47f88682 100644 --- a/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/v1/egenregistrering/EgenregistreringRouteTest.kt +++ b/src/integrationTest/kotlin/no/kartverket/matrikkel/bygning/v1/egenregistrering/EgenregistreringRouteTest.kt @@ -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() + + assertThat(bygning).all { + prop(BygningResponse::bruksareal).isNotNull().all { + prop(MultikildeResponse::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), diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/LocalBygningClient.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/LocalBygningClient.kt index 3fd1d887..b82f72fd 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/LocalBygningClient.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/LocalBygningClient.kt @@ -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 = listOf( @@ -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, diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClient.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClient.kt index a5bc774d..bdd80843 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClient.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClient.kt @@ -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 @@ -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, @@ -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, diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Bygning.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Bygning.kt index ad184da9..f86f47b9 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Bygning.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Bygning.kt @@ -16,19 +16,17 @@ data class Bygning( val oppvarminger: Multikilde> = Multikilde(), val vannforsyning: Multikilde = Multikilde(), val avlop: Multikilde = Multikilde(), -) { - fun withBruksenheter(bruksenheter: List): Bygning { - return this.copy( - bruksenheter = bruksenheter, - ) - } -} +) data class Multikilde(val autoritativ: T? = null, val egenregistrert: T? = null) { fun withEgenregistrert(verdi: T?): Multikilde = 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) diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensions.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensions.kt index 252b058d..6a7df072 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensions.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensions.kt @@ -7,14 +7,17 @@ package no.kartverket.matrikkel.bygning.models fun Bygning.withEgenregistrertData(egenregistreringer: List): 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, ) } }, @@ -22,9 +25,7 @@ fun Bygning.withEgenregistrertData(egenregistreringer: List): egenregistrering.bygningRegistrering.bruksarealRegistrering?.let { Bruksareal( data = it.bruksareal, - metadata = RegisterMetadata( - registreringstidspunkt = egenregistrering.registreringstidspunkt, - ), + metadata = metadata, ) } }, @@ -32,9 +33,7 @@ fun Bygning.withEgenregistrertData(egenregistreringer: List): egenregistrering.bygningRegistrering.vannforsyningRegistrering?.let { Vannforsyning( data = it.vannforsyning, - metadata = RegisterMetadata( - registreringstidspunkt = egenregistrering.registreringstidspunkt, - ), + metadata = metadata, ) } }, @@ -42,70 +41,65 @@ fun Bygning.withEgenregistrertData(egenregistreringer: List): 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): 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): Bruksenhet { + return egenregistreringer.fold(this) { bruksenhetAggregate, egenregistrering -> + bruksenhetAggregate.applyEgenregistrering(egenregistrering) } } diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Egenregistrering.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Egenregistrering.kt index 999be85b..53d5b369 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Egenregistrering.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/Egenregistrering.kt @@ -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 @@ -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, ) diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/models/RegistreringAktoer.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/RegistreringAktoer.kt new file mode 100644 index 00000000..32ea3d50 --- /dev/null +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/models/RegistreringAktoer.kt @@ -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() +} diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepository.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepository.kt index f7cead0d..c8c64b07 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepository.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/repositories/EgenregistreringRepository.kt @@ -6,6 +6,7 @@ import no.kartverket.matrikkel.bygning.db.prepareAndExecuteUpdate import no.kartverket.matrikkel.bygning.db.withTransaction 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.Result import org.postgresql.util.PGobject import java.sql.Timestamp @@ -16,10 +17,13 @@ class EgenregistreringRepository(private val dataSource: DataSource) { fun getAllEgenregistreringerForBygning(bygningId: Long): List { return dataSource.executeQueryAndMapPreparedStatement( """ - select er.id, er.registreringstidspunkt, er.registrering as bygningregistrering - from bygning.egenregistrering er - where er.registrering ->> 'bygningId' = ? - order by er.registreringstidspunkt DESC; + SELECT er.id AS id, + er.eier AS eier, + er.registreringstidspunkt AS registreringstidspunkt, + er.registrering AS bygningregistrering + FROM bygning.egenregistrering er + WHERE er.registrering ->> 'bygningId' = ? + ORDER BY er.registreringstidspunkt DESC; """.trimIndent(), { it.setString(1, bygningId.toString()) @@ -27,6 +31,7 @@ class EgenregistreringRepository(private val dataSource: DataSource) { ) { Egenregistrering( id = UUID.fromString(it.getString("id")), + eier = Foedselsnummer(it.getString("eier")), registreringstidspunkt = it.getTimestamp("registreringstidspunkt").toInstant(), bygningRegistrering = Json.decodeFromString(it.getString("bygningregistrering")), ) @@ -36,16 +41,23 @@ class EgenregistreringRepository(private val dataSource: DataSource) { fun saveEgenregistrering(egenregistrering: Egenregistrering): Result { return dataSource.withTransaction { connection -> connection.prepareAndExecuteUpdate( - "INSERT INTO bygning.egenregistrering values (?, ?, ?)", + """ + INSERT INTO bygning.egenregistrering + (id, registreringstidspunkt, eier, registrering) + VALUES (?, ?, ?, ?) + """.trimIndent(), ) { it.setObject(1, egenregistrering.id) it.setTimestamp(2, Timestamp.from(egenregistrering.registreringstidspunkt)) - it.setObject(3, PGobject().apply { - this.type = "jsonb" - // Av en eller annen grunn må jeg eksplisitt nevne serializer typen her - this.value = - Json.encodeToString(BygningRegistrering.serializer(), egenregistrering.bygningRegistrering) - }) + it.setString(3, egenregistrering.eier.value) + it.setObject( + 4, + PGobject().apply { + this.type = "jsonb" + // Av en eller annen grunn må jeg eksplisitt nevne serializer typen her + this.value = Json.encodeToString(BygningRegistrering.serializer(), egenregistrering.bygningRegistrering) + }, + ) } } } diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/bygning/BygningResponse.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/bygning/BygningResponse.kt index 6140f4bc..03800ba1 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/bygning/BygningResponse.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/bygning/BygningResponse.kt @@ -46,7 +46,11 @@ data class BruksenhetResponse( ) @Serializable -data class RegisterMetadataResponse(@Serializable(with = InstantSerializer::class) val registreringstidspunkt: Instant) +data class RegisterMetadataResponse( + @Serializable(with = InstantSerializer::class) + val registreringstidspunkt: Instant, + val registrertAv: String, +) @Serializable data class ByggeaarResponse(val data: Int?, val metadata: RegisterMetadataResponse) @@ -69,8 +73,10 @@ data class OppvarmingResponse(val data: OppvarmingKode?, val metadata: RegisterM fun RegisterMetadata.toRegisterMetadataResponse() = RegisterMetadataResponse( registreringstidspunkt = this.registreringstidspunkt, + registrertAv = this.registrertAv.value, ) + fun Multikilde.toMultikildeResponse(mapper: T.() -> R): MultikildeResponse? { return MultikildeResponse( autoritativ?.mapper(), diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregisteringRoutes.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregisteringRoutes.kt index c900a85a..00c5642d 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregisteringRoutes.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregisteringRoutes.kt @@ -47,6 +47,7 @@ private fun Route.egenregistreringDoc() { examples( "Bygning Id 1" to EgenregistreringRequest( bygningId = 1, + eier = "31129956715", bygningRegistrering = BygningRegistreringRequest( bruksarealRegistrering = BruksarealRegistreringRequest( bruksareal = 125.0, diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregistreringRequest.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregistreringRequest.kt index bed453d5..c0cf1677 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregistreringRequest.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/routes/v1/egenregistrering/EgenregistreringRequest.kt @@ -9,6 +9,7 @@ import no.kartverket.matrikkel.bygning.models.BygningRegistrering import no.kartverket.matrikkel.bygning.models.Egenregistrering import no.kartverket.matrikkel.bygning.models.EnergikildeRegistrering import no.kartverket.matrikkel.bygning.models.OppvarmingRegistrering +import no.kartverket.matrikkel.bygning.models.RegistreringAktoer.* import no.kartverket.matrikkel.bygning.models.VannforsyningRegistrering import no.kartverket.matrikkel.bygning.models.kodelister.AvlopKode import no.kartverket.matrikkel.bygning.models.kodelister.EnergikildeKode @@ -37,6 +38,7 @@ data class BruksenhetRegistreringRequest( @Serializable data class EgenregistreringRequest( val bygningId: Long, + val eier: String, val bygningRegistrering: BygningRegistreringRequest?, val bruksenhetRegistreringer: List? ) @@ -75,6 +77,7 @@ fun EgenregistreringRequest.toEgenregistrering(): Egenregistrering { val registreringstidspunkt = Instant.now() return Egenregistrering( id = UUID.randomUUID(), + eier = Foedselsnummer(this.eier), registreringstidspunkt = registreringstidspunkt, bygningRegistrering = BygningRegistrering( bygningId = this.bygningId, diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/services/BygningService.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/services/BygningService.kt index d498fd99..4e25ce5b 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/services/BygningService.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/services/BygningService.kt @@ -22,11 +22,7 @@ class BygningService( val bygningWithEgenregistrertData = bygning.withEgenregistrertData(egenregistreringerForBygning) - val aggregatedBygningWithAggregatedBruksenheter = bygningWithEgenregistrertData.withBruksenheter( - bygningWithEgenregistrertData.bruksenheter.map { it.withEgenregistrertData(egenregistreringerForBygning) }, - ) - - return Result.Success(aggregatedBygningWithAggregatedBruksenheter) + return Result.Success(bygningWithEgenregistrertData) } diff --git a/src/main/kotlin/no/kartverket/matrikkel/bygning/services/EgenregistreringService.kt b/src/main/kotlin/no/kartverket/matrikkel/bygning/services/EgenregistreringService.kt index 67a436f9..5be44914 100644 --- a/src/main/kotlin/no/kartverket/matrikkel/bygning/services/EgenregistreringService.kt +++ b/src/main/kotlin/no/kartverket/matrikkel/bygning/services/EgenregistreringService.kt @@ -26,7 +26,7 @@ class EgenregistreringService( ) } - return egenregistreringRepository.saveEgenregistrering(egenregistrering); + return egenregistreringRepository.saveEgenregistrering(egenregistrering) } private fun findBruksenheterNotRegisteredOnCorrectBygning( diff --git a/src/main/resources/db/migration/V1__init_db.sql b/src/main/resources/db/migration/V1__init_db.sql index c5272760..e7e62ee2 100644 --- a/src/main/resources/db/migration/V1__init_db.sql +++ b/src/main/resources/db/migration/V1__init_db.sql @@ -4,5 +4,6 @@ CREATE TABLE egenregistrering ( id UUID PRIMARY KEY, registreringstidspunkt TIMESTAMP WITH TIME ZONE NOT NULL, + eier VARCHAR(32) NOT NULL, registrering JSONB NOT NULL ); diff --git a/src/test/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClientTest.kt b/src/test/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClientTest.kt index 175b0288..ef89e76c 100644 --- a/src/test/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClientTest.kt +++ b/src/test/kotlin/no/kartverket/matrikkel/bygning/matrikkel/adapters/MatrikkelBygningClientTest.kt @@ -14,12 +14,6 @@ import io.mockk.checkUnnecessaryStub import io.mockk.every import io.mockk.mockk import no.kartverket.matrikkel.bygning.matrikkelapi.MatrikkelApi -import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelAvlopKode -import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelEnergikildeKode -import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelEtasjeplanKode -import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelOppvarmingKode -import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelVannforsyningKode -import no.kartverket.matrikkel.bygning.matrikkelapi.id.bruksenhetId import no.kartverket.matrikkel.bygning.matrikkelapi.builders.bruksenhet import no.kartverket.matrikkel.bygning.matrikkelapi.builders.bruksenhetIds import no.kartverket.matrikkel.bygning.matrikkelapi.builders.bygning @@ -29,6 +23,12 @@ import no.kartverket.matrikkel.bygning.matrikkelapi.builders.etasjer import no.kartverket.matrikkel.bygning.matrikkelapi.builders.matrikkelBubbleObjectList import no.kartverket.matrikkel.bygning.matrikkelapi.builders.oppvarmingsKodeIdList import no.kartverket.matrikkel.bygning.matrikkelapi.builders.timestampUtc +import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelAvlopKode +import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelEnergikildeKode +import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelEtasjeplanKode +import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelOppvarmingKode +import no.kartverket.matrikkel.bygning.matrikkelapi.id.MatrikkelVannforsyningKode +import no.kartverket.matrikkel.bygning.matrikkelapi.id.bruksenhetId import no.kartverket.matrikkel.bygning.matrikkelapi.id.bygningId import no.kartverket.matrikkel.bygning.matrikkelapi.matchers.matchId import no.kartverket.matrikkel.bygning.matrikkelapi.matchers.matchIds @@ -61,6 +61,7 @@ class MatrikkelBygningClientTest { id = bygningId bygningsnummer = 1000L oppdateringsdato = timestampUtc(2024, 9, 13) + oppdatertAv = "TestAnsatt" bruksenhetIds(bruksenhetId) } every { getObjects(matchIds(bruksenhetId), any()) } returns matrikkelBubbleObjectList( @@ -68,6 +69,7 @@ class MatrikkelBygningClientTest { id = bruksenhetId byggId = bygningId oppdateringsdato = timestampUtc(2024, 9, 12) + oppdatertAv = "TestAnsatt" }, ) } @@ -118,6 +120,7 @@ class MatrikkelBygningClientTest { id = bygningId bygningsnummer = 1000L oppdateringsdato = timestampUtc(2024, 9, 12) + oppdatertAv = "TestAnsatt" vannforsyningsKodeId = MatrikkelVannforsyningKode.TilknyttetOffVannverk() avlopsKodeId = MatrikkelAvlopKode.OffentligKloakk() energikildeKodeIds = energikildeKodeIdList( @@ -142,6 +145,7 @@ class MatrikkelBygningClientTest { id = bruksenhetId byggId = bygningId oppdateringsdato = timestampUtc(2024, 9, 13) + oppdatertAv = "TestAnsatt" bruksareal = 140.0 }, ) diff --git a/src/test/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensionsTest.kt b/src/test/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensionsTest.kt index b861c616..e38f82d8 100644 --- a/src/test/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensionsTest.kt +++ b/src/test/kotlin/no/kartverket/matrikkel/bygning/models/BygningExtensionsTest.kt @@ -2,6 +2,7 @@ package no.kartverket.matrikkel.bygning.models import assertk.assertThat import assertk.assertions.isEqualTo +import no.kartverket.matrikkel.bygning.models.RegistreringAktoer.* import java.time.Instant import java.util.UUID import kotlin.test.Test @@ -49,6 +50,7 @@ class BygningExtensionsTest { private val defaultEgenregistrering = Egenregistrering( id = UUID.randomUUID(), registreringstidspunkt = Instant.parse("2024-01-01T12:00:00.00Z"), + eier = Foedselsnummer("31129956715"), bygningRegistrering = defaultBygningRegistrering ) diff --git a/src/test/kotlin/no/kartverket/matrikkel/bygning/models/RegistreringAktoerTest.kt b/src/test/kotlin/no/kartverket/matrikkel/bygning/models/RegistreringAktoerTest.kt new file mode 100644 index 00000000..ca3f8a5e --- /dev/null +++ b/src/test/kotlin/no/kartverket/matrikkel/bygning/models/RegistreringAktoerTest.kt @@ -0,0 +1,30 @@ +package no.kartverket.matrikkel.bygning.models + +import assertk.assertFailure +import assertk.assertThat +import assertk.assertions.isEqualTo +import assertk.assertions.messageContains +import no.kartverket.matrikkel.bygning.models.RegistreringAktoer.* +import kotlin.test.Test + +class RegistreringAktoerTest { + @Test + fun `fnr som er for kort skal feile validering`() { + assertFailure { Foedselsnummer("123") }.messageContains("er ikke gyldig") + } + + @Test + fun `fnr med tekst men riktig lengde skal feile validering`() { + assertFailure { Foedselsnummer("1234567890a") }.messageContains("er ikke gyldig") + } + + @Test + fun `fnr med riktig lengde men ikke riktig oppbyggning skal feile validering`() { + assertFailure { Foedselsnummer("12345678901") }.messageContains("er ikke gyldig") + } + + @Test + fun `fnr med riktig lengde og oppbyggning skal valideres`() { + assertThat(Foedselsnummer("31129956715").value).isEqualTo("31129956715") + } +}