diff --git a/migrations/.snapshot-dbildungs-iam-server.json b/migrations/.snapshot-dbildungs-iam-server.json index 5c5a38239..37e07a13d 100644 --- a/migrations/.snapshot-dbildungs-iam-server.json +++ b/migrations/.snapshot-dbildungs-iam-server.json @@ -70,7 +70,148 @@ ], "checks": [], "foreignKeys": {}, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -120,7 +261,148 @@ ], "checks": [], "foreignKeys": {}, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -192,7 +474,148 @@ "updateRule": "cascade" } }, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -207,11 +630,12 @@ }, "status": { "name": "status", - "type": "text", + "type": "db_seed_status_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, + "nativeEnumName": "db_seed_status_enum", "enumItems": [ "STARTED", "DONE", @@ -255,122 +679,196 @@ ], "checks": [], "foreignKeys": {}, - "nativeEnums": {} - }, - { - "columns": { - "virtual_id": { - "name": "virtual_id", - "type": "int", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "integer" - }, - "uuid": { - "name": "uuid", - "type": "varchar(255)", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "string" + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] }, - "referenced_entity_type": { - "name": "referenced_entity_type", - "type": "text", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "enumItems": [ + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ "PERSON", "ORGANISATION", "ROLLE", "SERVICE_PROVIDER" - ], - "mappedType": "enum" - } - }, - "name": "seeding_reference", - "schema": "public", - "indexes": [ - { - "keyName": "seeding_reference_pkey", - "columnNames": [ - "virtual_id", - "uuid" - ], - "composite": true, - "constraint": true, - "primary": true, - "unique": true + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] } - ], - "checks": [], - "foreignKeys": {}, - "nativeEnums": {} + } }, { "columns": { - "id": { - "name": "id", - "type": "uuid", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "uuid" - }, - "created_at": { - "name": "created_at", - "type": "timestamptz", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "length": 6, - "mappedType": "datetime" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamptz", + "virtual_id": { + "name": "virtual_id", + "type": "int", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, - "length": 6, - "mappedType": "datetime" + "mappedType": "integer" }, - "source": { - "name": "source", - "type": "uuid", + "uuid": { + "name": "uuid", + "type": "varchar(255)", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, - "mappedType": "uuid" + "mappedType": "string" }, - "target": { - "name": "target", - "type": "uuid", + "referenced_entity_type": { + "name": "referenced_entity_type", + "type": "referenced_entity_type_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, - "mappedType": "uuid" + "nativeEnumName": "referenced_entity_type_enum", + "enumItems": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ], + "mappedType": "enum" } }, - "name": "fake", + "name": "seeding_reference", "schema": "public", "indexes": [ { - "keyName": "fake_pkey", + "keyName": "seeding_reference_pkey", "columnNames": [ - "id" + "virtual_id", + "uuid" ], - "composite": false, + "composite": true, "constraint": true, "primary": true, "unique": true @@ -378,7 +876,148 @@ ], "checks": [], "foreignKeys": {}, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -467,11 +1106,12 @@ }, "typ": { "name": "typ", - "type": "text", + "type": "organisations_typ_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": true, + "nativeEnumName": "organisations_typ_enum", "enumItems": [ "ROOT", "LAND", @@ -486,11 +1126,12 @@ }, "traegerschaft": { "name": "traegerschaft", - "type": "text", + "type": "traegerschaft_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": true, + "nativeEnumName": "traegerschaft_enum", "enumItems": [ "01", "02", @@ -518,51 +1159,192 @@ ], "checks": [], "foreignKeys": {}, - "nativeEnums": {} - }, - { - "columns": { - "id": { - "name": "id", - "type": "uuid", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "uuid" - }, - "created_at": { - "name": "created_at", - "type": "timestamptz", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "length": 6, - "mappedType": "datetime" + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] }, - "updated_at": { - "name": "updated_at", - "type": "timestamptz", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "length": 6, - "mappedType": "datetime" + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] }, - "keycloak_user_id": { - "name": "keycloak_user_id", - "type": "varchar(255)", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "string" + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] }, - "referrer": { - "name": "referrer", - "type": "varchar(255)", + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } + }, + { + "columns": { + "id": { + "name": "id", + "type": "uuid", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "uuid" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + }, + "keycloak_user_id": { + "name": "keycloak_user_id", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "string" + }, + "referrer": { + "name": "referrer", + "type": "varchar(255)", "unsigned": false, "autoincrement": false, "primary": false, @@ -698,11 +1480,12 @@ }, "geschlecht": { "name": "geschlecht", - "type": "text", + "type": "geschlecht_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": true, + "nativeEnumName": "geschlecht_enum", "enumItems": [ "m", "w", @@ -722,11 +1505,12 @@ }, "vertrauensstufe": { "name": "vertrauensstufe", - "type": "text", + "type": "vertrauensstufe_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": true, + "nativeEnumName": "vertrauensstufe_enum", "enumItems": [ "KEIN", "UNBE", @@ -803,7 +1587,148 @@ "updateRule": "cascade" } }, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -836,58 +1761,32 @@ "length": 6, "mappedType": "datetime" }, - "person_id_id": { - "name": "person_id_id", - "type": "uuid", + "name": { + "name": "name", + "type": "varchar(255)", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, - "mappedType": "uuid" - }, - "organisation_id": { - "name": "organisation_id", - "type": "uuid", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": true, - "mappedType": "uuid" + "mappedType": "string" }, - "rolle_id": { - "name": "rolle_id", + "administered_by_schulstrukturknoten": { + "name": "administered_by_schulstrukturknoten", "type": "uuid", "unsigned": false, "autoincrement": false, "primary": false, - "nullable": true, + "nullable": false, "mappedType": "uuid" }, - "referrer": { - "name": "referrer", - "type": "varchar(255)", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": true, - "mappedType": "string" - }, - "mandant": { - "name": "mandant", - "type": "varchar(255)", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": true, - "mappedType": "string" - }, - "rolle": { - "name": "rolle", - "type": "text", + "rollenart": { + "name": "rollenart", + "type": "rollen_art_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, + "nativeEnumName": "rollen_art_enum", "enumItems": [ "LERN", "LEHR", @@ -897,30 +1796,285 @@ "SYSADMIN" ], "mappedType": "enum" - }, - "personenstatus": { - "name": "personenstatus", - "type": "text", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": true, - "enumItems": [ - "AKTIV" + } + }, + "name": "rolle", + "schema": "public", + "indexes": [ + { + "keyName": "rolle_pkey", + "columnNames": [ + "id" ], - "mappedType": "enum" + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": {}, + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] }, - "jahrgangsstufe": { - "name": "jahrgangsstufe", - "type": "text", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": true, - "enumItems": [ - "01", - "02", - "03", + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } + }, + { + "columns": { + "id": { + "name": "id", + "type": "uuid", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "uuid" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + }, + "person_id": { + "name": "person_id", + "type": "uuid", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "uuid" + }, + "organisation_id": { + "name": "organisation_id", + "type": "uuid", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "uuid" + }, + "rolle_id": { + "name": "rolle_id", + "type": "uuid", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "uuid" + }, + "referrer": { + "name": "referrer", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "string" + }, + "mandant": { + "name": "mandant", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "string" + }, + "rolle": { + "name": "rolle", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "enumItems": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ], + "mappedType": "enum" + }, + "personenstatus": { + "name": "personenstatus", + "type": "personenstatus_enum", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "nativeEnumName": "personenstatus_enum", + "enumItems": [ + "AKTIV" + ], + "mappedType": "enum" + }, + "jahrgangsstufe": { + "name": "jahrgangsstufe", + "type": "jahrgangsstufe_enum", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "nativeEnumName": "jahrgangsstufe_enum", + "enumItems": [ + "01", + "02", + "03", "04", "05", "06", @@ -966,9 +2120,9 @@ "schema": "public", "indexes": [ { - "keyName": "personenkontext_person_id_id_organisation_id_rolle_id_unique", + "keyName": "personenkontext_person_id_organisation_id_rolle_id_unique", "columnNames": [ - "person_id_id", + "person_id", "organisation_id", "rolle_id" ], @@ -990,104 +2144,173 @@ ], "checks": [], "foreignKeys": { - "personenkontext_person_id_id_foreign": { - "constraintName": "personenkontext_person_id_id_foreign", + "personenkontext_person_id_foreign": { + "constraintName": "personenkontext_person_id_foreign", "columnNames": [ - "person_id_id" + "person_id" ], "localTableName": "public.personenkontext", "referencedColumnNames": [ "id" ], - "referencedTableName": "public.person" + "referencedTableName": "public.person", + "deleteRule": "cascade" + }, + "personenkontext_rolle_id_foreign": { + "constraintName": "personenkontext_rolle_id_foreign", + "columnNames": [ + "rolle_id" + ], + "localTableName": "public.personenkontext", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.rolle", + "updateRule": "cascade" } }, - "nativeEnums": {} - }, - { - "columns": { - "id": { - "name": "id", - "type": "uuid", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "uuid" + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] }, - "created_at": { - "name": "created_at", - "type": "timestamptz", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "length": 6, - "mappedType": "datetime" + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] }, - "updated_at": { - "name": "updated_at", - "type": "timestamptz", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "length": 6, - "mappedType": "datetime" + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] }, - "name": { - "name": "name", - "type": "varchar(255)", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "string" + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] }, - "administered_by_schulstrukturknoten": { - "name": "administered_by_schulstrukturknoten", - "type": "uuid", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "mappedType": "uuid" + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] }, - "rollenart": { - "name": "rollenart", - "type": "text", - "unsigned": false, - "autoincrement": false, - "primary": false, - "nullable": false, - "enumItems": [ + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ "LERN", "LEHR", "EXTERN", "ORGADMIN", "LEIT", "SYSADMIN" - ], - "mappedType": "enum" - } - }, - "name": "rolle", - "schema": "public", - "indexes": [ - { - "keyName": "rolle_pkey", - "columnNames": [ - "id" - ], - "composite": false, - "constraint": true, - "primary": true, - "unique": true + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] } - ], - "checks": [], - "foreignKeys": {}, - "nativeEnums": {} + } }, { "columns": { @@ -1102,11 +2325,12 @@ }, "merkmal": { "name": "merkmal", - "type": "text", + "type": "rollen_merkmal_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, + "nativeEnumName": "rollen_merkmal_enum", "enumItems": [ "BEFRISTUNG_PFLICHT", "KOPERS_PFLICHT" @@ -1144,7 +2368,148 @@ "updateRule": "cascade" } }, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -1159,17 +2524,20 @@ }, "systemrecht": { "name": "systemrecht", - "type": "text", + "type": "rollen_system_recht_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, + "nativeEnumName": "rollen_system_recht_enum", "enumItems": [ "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", "PERSONEN_VERWALTEN", "SCHULEN_VERWALTEN", "KLASSEN_VERWALTEN", - "SCHULTRAEGER_VERWALTEN" + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" ], "mappedType": "enum" } @@ -1203,8 +2571,149 @@ "referencedTableName": "public.rolle", "updateRule": "cascade" } - }, - "nativeEnums": {} + }, + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -1350,7 +2859,148 @@ "updateRule": "cascade" } }, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -1394,11 +3044,12 @@ }, "target": { "name": "target", - "type": "text", + "type": "service_provider_target_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, + "nativeEnumName": "service_provider_target_enum", "enumItems": [ "URL", "SCHULPORTAL_ADMINISTRATION" @@ -1425,11 +3076,12 @@ }, "kategorie": { "name": "kategorie", - "type": "text", + "type": "service_provider_kategorie_enum", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, + "nativeEnumName": "service_provider_kategorie_enum", "enumItems": [ "EMAIL", "UNTERRICHT", @@ -1456,6 +3108,24 @@ "primary": false, "nullable": true, "mappedType": "string" + }, + "keycloak_group": { + "name": "keycloak_group", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "string" + }, + "keycloak_role": { + "name": "keycloak_role", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "string" } }, "name": "service_provider", @@ -1474,7 +3144,148 @@ ], "checks": [], "foreignKeys": {}, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } }, { "columns": { @@ -1539,8 +3350,290 @@ "updateRule": "cascade" } }, - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } } ], - "nativeEnums": {} + "nativeEnums": { + "db_seed_status_enum": { + "name": "db_seed_status_enum", + "schema": "public", + "items": [ + "STARTED", + "DONE", + "FAILED" + ] + }, + "referenced_entity_type_enum": { + "name": "referenced_entity_type_enum", + "schema": "public", + "items": [ + "PERSON", + "ORGANISATION", + "ROLLE", + "SERVICE_PROVIDER" + ] + }, + "organisations_typ_enum": { + "name": "organisations_typ_enum", + "schema": "public", + "items": [ + "ROOT", + "LAND", + "TRAEGER", + "SCHULE", + "KLASSE", + "ANBIETER", + "SONSTIGE ORGANISATION / EINRICHTUNG", + "UNBESTAETIGT" + ] + }, + "traegerschaft_enum": { + "name": "traegerschaft_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06" + ] + }, + "geschlecht_enum": { + "name": "geschlecht_enum", + "schema": "public", + "items": [ + "m", + "w", + "d", + "x" + ] + }, + "vertrauensstufe_enum": { + "name": "vertrauensstufe_enum", + "schema": "public", + "items": [ + "KEIN", + "UNBE", + "TEIL", + "VOLL" + ] + }, + "rollen_art_enum": { + "name": "rollen_art_enum", + "schema": "public", + "items": [ + "LERN", + "LEHR", + "EXTERN", + "ORGADMIN", + "LEIT", + "SYSADMIN" + ] + }, + "personenstatus_enum": { + "name": "personenstatus_enum", + "schema": "public", + "items": [ + "AKTIV" + ] + }, + "jahrgangsstufe_enum": { + "name": "jahrgangsstufe_enum", + "schema": "public", + "items": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10" + ] + }, + "rollen_merkmal_enum": { + "name": "rollen_merkmal_enum", + "schema": "public", + "items": [ + "BEFRISTUNG_PFLICHT", + "KOPERS_PFLICHT" + ] + }, + "rollen_system_recht_enum": { + "name": "rollen_system_recht_enum", + "schema": "public", + "items": [ + "ROLLEN_VERWALTEN", + "PERSONEN_SOFORT_LOESCHEN", + "PERSONEN_VERWALTEN", + "SCHULEN_VERWALTEN", + "KLASSEN_VERWALTEN", + "SCHULTRAEGER_VERWALTEN", + "MIGRATION_DURCHFUEHREN" + ] + }, + "service_provider_target_enum": { + "name": "service_provider_target_enum", + "schema": "public", + "items": [ + "URL", + "SCHULPORTAL_ADMINISTRATION" + ] + }, + "service_provider_kategorie_enum": { + "name": "service_provider_kategorie_enum", + "schema": "public", + "items": [ + "EMAIL", + "UNTERRICHT", + "VERWALTUNG", + "HINWEISE", + "ANGEBOTE" + ] + } + } } diff --git a/migrations/Migration20240620082431.ts b/migrations/Migration20240620082431.ts new file mode 100644 index 000000000..93b1e7337 --- /dev/null +++ b/migrations/Migration20240620082431.ts @@ -0,0 +1,146 @@ +/* eslint-disable @typescript-eslint/require-await */ +/* eslint-disable @typescript-eslint/explicit-member-accessibility */ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20240620082431 extends Migration { + + async up(): Promise { + this.addSql('create type "db_seed_status_enum" as enum (\'STARTED\', \'DONE\', \'FAILED\');'); + this.addSql('create type "referenced_entity_type_enum" as enum (\'PERSON\', \'ORGANISATION\', \'ROLLE\', \'SERVICE_PROVIDER\');'); + this.addSql('create type "organisations_typ_enum" as enum (\'ROOT\', \'LAND\', \'TRAEGER\', \'SCHULE\', \'KLASSE\', \'ANBIETER\', \'SONSTIGE ORGANISATION / EINRICHTUNG\', \'UNBESTAETIGT\');'); + this.addSql('create type "traegerschaft_enum" as enum (\'01\', \'02\', \'03\', \'04\', \'05\', \'06\');'); + this.addSql('create type "geschlecht_enum" as enum (\'m\', \'w\', \'d\', \'x\');'); + this.addSql('create type "vertrauensstufe_enum" as enum (\'KEIN\', \'UNBE\', \'TEIL\', \'VOLL\');'); + this.addSql('create type "rollen_art_enum" as enum (\'LERN\', \'LEHR\', \'EXTERN\', \'ORGADMIN\', \'LEIT\', \'SYSADMIN\');'); + this.addSql('create type "personenstatus_enum" as enum (\'AKTIV\');'); + this.addSql('create type "jahrgangsstufe_enum" as enum (\'01\', \'02\', \'03\', \'04\', \'05\', \'06\', \'07\', \'08\', \'09\', \'10\');'); + this.addSql('create type "rollen_merkmal_enum" as enum (\'BEFRISTUNG_PFLICHT\', \'KOPERS_PFLICHT\');'); + this.addSql('create type "rollen_system_recht_enum" as enum (\'ROLLEN_VERWALTEN\', \'PERSONEN_SOFORT_LOESCHEN\', \'PERSONEN_VERWALTEN\', \'SCHULEN_VERWALTEN\', \'KLASSEN_VERWALTEN\', \'SCHULTRAEGER_VERWALTEN\', \'MIGRATION_DURCHFUEHREN\');'); + this.addSql('create type "service_provider_target_enum" as enum (\'URL\', \'SCHULPORTAL_ADMINISTRATION\');'); + this.addSql('create type "service_provider_kategorie_enum" as enum (\'EMAIL\', \'UNTERRICHT\', \'VERWALTUNG\', \'HINWEISE\', \'ANGEBOTE\');'); + this.addSql('drop table if exists "fake" cascade;'); + + this.addSql('alter table "seeding" drop constraint if exists "seeding_status_check";'); + + this.addSql('alter table "seeding_reference" drop constraint if exists "seeding_reference_referenced_entity_type_check";'); + + this.addSql('alter table "organisation" drop constraint if exists "organisation_typ_check";'); + this.addSql('alter table "organisation" drop constraint if exists "organisation_traegerschaft_check";'); + + this.addSql('alter table "person" drop constraint if exists "person_geschlecht_check";'); + this.addSql('alter table "person" drop constraint if exists "person_vertrauensstufe_check";'); + + this.addSql('alter table "rolle" drop constraint if exists "rolle_rollenart_check";'); + + this.addSql('alter table "personenkontext" drop constraint if exists "personenkontext_personenstatus_check";'); + this.addSql('alter table "personenkontext" drop constraint if exists "personenkontext_jahrgangsstufe_check";'); + + this.addSql('alter table "personenkontext" drop constraint "personenkontext_person_id_id_foreign";'); + + this.addSql('alter table "rolle_merkmal" drop constraint if exists "rolle_merkmal_merkmal_check";'); + + this.addSql('alter table "rolle_systemrecht" drop constraint if exists "rolle_systemrecht_systemrecht_check";'); + + this.addSql('alter table "service_provider" drop constraint if exists "service_provider_target_check";'); + this.addSql('alter table "service_provider" drop constraint if exists "service_provider_kategorie_check";'); + + this.addSql('alter table "seeding" alter column "status" type "db_seed_status_enum" using ("status"::"db_seed_status_enum");'); + + this.addSql('alter table "seeding_reference" alter column "referenced_entity_type" type "referenced_entity_type_enum" using ("referenced_entity_type"::"referenced_entity_type_enum");'); + + this.addSql('alter table "organisation" alter column "typ" type "organisations_typ_enum" using ("typ"::"organisations_typ_enum");'); + this.addSql('alter table "organisation" alter column "traegerschaft" type "traegerschaft_enum" using ("traegerschaft"::"traegerschaft_enum");'); + + this.addSql('alter table "person" alter column "geschlecht" type "geschlecht_enum" using ("geschlecht"::"geschlecht_enum");'); + this.addSql('alter table "person" alter column "vertrauensstufe" type "vertrauensstufe_enum" using ("vertrauensstufe"::"vertrauensstufe_enum");'); + + this.addSql('alter table "rolle" alter column "rollenart" type "rollen_art_enum" using ("rollenart"::"rollen_art_enum");'); + + this.addSql('alter table "personenkontext" drop constraint "personenkontext_person_id_id_organisation_id_rolle_id_unique";'); + + this.addSql('alter table "personenkontext" alter column "rolle_id" drop default;'); + this.addSql('alter table "personenkontext" alter column "rolle_id" type uuid using ("rolle_id"::text::uuid);'); + this.addSql('alter table "personenkontext" alter column "rolle_id" set not null;'); + this.addSql('alter table "personenkontext" alter column "personenstatus" type "personenstatus_enum" using ("personenstatus"::"personenstatus_enum");'); + this.addSql('alter table "personenkontext" alter column "jahrgangsstufe" type "jahrgangsstufe_enum" using ("jahrgangsstufe"::"jahrgangsstufe_enum");'); + this.addSql('alter table "personenkontext" rename column "person_id_id" to "person_id";'); + this.addSql('alter table "personenkontext" add constraint "personenkontext_person_id_foreign" foreign key ("person_id") references "person" ("id") on delete cascade;'); + this.addSql('alter table "personenkontext" add constraint "personenkontext_rolle_id_foreign" foreign key ("rolle_id") references "rolle" ("id") on update cascade;'); + this.addSql('alter table "personenkontext" add constraint "personenkontext_person_id_organisation_id_rolle_id_unique" unique ("person_id", "organisation_id", "rolle_id");'); + + this.addSql('alter table "rolle_merkmal" alter column "merkmal" type "rollen_merkmal_enum" using ("merkmal"::"rollen_merkmal_enum");'); + + this.addSql('alter table "rolle_systemrecht" alter column "systemrecht" type "rollen_system_recht_enum" using ("systemrecht"::"rollen_system_recht_enum");'); + + this.addSql('alter table "service_provider" add column "keycloak_group" varchar(255) null, add column "keycloak_role" varchar(255) null;'); + this.addSql('alter table "service_provider" alter column "target" type "service_provider_target_enum" using ("target"::"service_provider_target_enum");'); + this.addSql('alter table "service_provider" alter column "kategorie" type "service_provider_kategorie_enum" using ("kategorie"::"service_provider_kategorie_enum");'); + } + + override async down(): Promise { + this.addSql('create table "fake" ("id" uuid not null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "source" uuid not null, "target" uuid not null, constraint "fake_pkey" primary key ("id"));'); + + this.addSql('alter table "personenkontext" drop constraint "personenkontext_person_id_foreign";'); + this.addSql('alter table "personenkontext" drop constraint "personenkontext_rolle_id_foreign";'); + + this.addSql('alter table "seeding" alter column "status" type text using ("status"::text);'); + this.addSql('alter table "seeding" add constraint "seeding_status_check" check("status" in (\'STARTED\', \'DONE\', \'FAILED\'));'); + + this.addSql('alter table "seeding_reference" alter column "referenced_entity_type" type text using ("referenced_entity_type"::text);'); + this.addSql('alter table "seeding_reference" add constraint "seeding_reference_referenced_entity_type_check" check("referenced_entity_type" in (\'PERSON\', \'ORGANISATION\', \'ROLLE\', \'SERVICE_PROVIDER\'));'); + + this.addSql('alter table "organisation" alter column "typ" type text using ("typ"::text);'); + this.addSql('alter table "organisation" alter column "traegerschaft" type text using ("traegerschaft"::text);'); + this.addSql('alter table "organisation" add constraint "organisation_typ_check" check("typ" in (\'ROOT\', \'LAND\', \'TRAEGER\', \'SCHULE\', \'KLASSE\', \'ANBIETER\', \'SONSTIGE ORGANISATION / EINRICHTUNG\', \'UNBESTAETIGT\'));'); + this.addSql('alter table "organisation" add constraint "organisation_traegerschaft_check" check("traegerschaft" in (\'01\', \'02\', \'03\', \'04\', \'05\', \'06\'));'); + + this.addSql('alter table "person" alter column "geschlecht" type text using ("geschlecht"::text);'); + this.addSql('alter table "person" alter column "vertrauensstufe" type text using ("vertrauensstufe"::text);'); + this.addSql('alter table "person" add constraint "person_geschlecht_check" check("geschlecht" in (\'m\', \'w\', \'d\', \'x\'));'); + this.addSql('alter table "person" add constraint "person_vertrauensstufe_check" check("vertrauensstufe" in (\'KEIN\', \'UNBE\', \'TEIL\', \'VOLL\'));'); + + this.addSql('alter table "personenkontext" drop constraint "personenkontext_person_id_organisation_id_rolle_id_unique";'); + + this.addSql('alter table "personenkontext" alter column "rolle_id" drop default;'); + this.addSql('alter table "personenkontext" alter column "rolle_id" type uuid using ("rolle_id"::text::uuid);'); + this.addSql('alter table "personenkontext" alter column "rolle_id" drop not null;'); + this.addSql('alter table "personenkontext" alter column "personenstatus" type text using ("personenstatus"::text);'); + this.addSql('alter table "personenkontext" alter column "jahrgangsstufe" type text using ("jahrgangsstufe"::text);'); + this.addSql('alter table "personenkontext" add constraint "personenkontext_personenstatus_check" check("personenstatus" in (\'AKTIV\'));'); + this.addSql('alter table "personenkontext" add constraint "personenkontext_jahrgangsstufe_check" check("jahrgangsstufe" in (\'01\', \'02\', \'03\', \'04\', \'05\', \'06\', \'07\', \'08\', \'09\', \'10\'));'); + this.addSql('alter table "personenkontext" rename column "person_id" to "person_id_id";'); + this.addSql('alter table "personenkontext" add constraint "personenkontext_person_id_id_foreign" foreign key ("person_id_id") references "person" ("id");'); + this.addSql('alter table "personenkontext" add constraint "personenkontext_person_id_id_organisation_id_rolle_id_unique" unique ("person_id_id", "organisation_id", "rolle_id");'); + + this.addSql('alter table "rolle" alter column "rollenart" type text using ("rollenart"::text);'); + this.addSql('alter table "rolle" add constraint "rolle_rollenart_check" check("rollenart" in (\'LERN\', \'LEHR\', \'EXTERN\', \'ORGADMIN\', \'LEIT\', \'SYSADMIN\'));'); + + this.addSql('alter table "rolle_merkmal" alter column "merkmal" type text using ("merkmal"::text);'); + this.addSql('alter table "rolle_merkmal" add constraint "rolle_merkmal_merkmal_check" check("merkmal" in (\'BEFRISTUNG_PFLICHT\', \'KOPERS_PFLICHT\'));'); + + this.addSql('alter table "rolle_systemrecht" alter column "systemrecht" type text using ("systemrecht"::text);'); + this.addSql('alter table "rolle_systemrecht" add constraint "rolle_systemrecht_systemrecht_check" check("systemrecht" in (\'ROLLEN_VERWALTEN\', \'PERSONEN_VERWALTEN\', \'SCHULEN_VERWALTEN\', \'KLASSEN_VERWALTEN\', \'SCHULTRAEGER_VERWALTEN\'));'); + + this.addSql('alter table "service_provider" drop column "keycloak_group", drop column "keycloak_role";'); + + this.addSql('alter table "service_provider" alter column "target" type text using ("target"::text);'); + this.addSql('alter table "service_provider" alter column "kategorie" type text using ("kategorie"::text);'); + this.addSql('alter table "service_provider" add constraint "service_provider_target_check" check("target" in (\'URL\', \'SCHULPORTAL_ADMINISTRATION\'));'); + this.addSql('alter table "service_provider" add constraint "service_provider_kategorie_check" check("kategorie" in (\'EMAIL\', \'UNTERRICHT\', \'VERWALTUNG\', \'HINWEISE\', \'ANGEBOTE\'));'); + + this.addSql('drop type "db_seed_status_enum";'); + this.addSql('drop type "referenced_entity_type_enum";'); + this.addSql('drop type "organisations_typ_enum";'); + this.addSql('drop type "traegerschaft_enum";'); + this.addSql('drop type "geschlecht_enum";'); + this.addSql('drop type "vertrauensstufe_enum";'); + this.addSql('drop type "rollen_art_enum";'); + this.addSql('drop type "personenstatus_enum";'); + this.addSql('drop type "jahrgangsstufe_enum";'); + this.addSql('drop type "rollen_merkmal_enum";'); + this.addSql('drop type "rollen_system_recht_enum";'); + this.addSql('drop type "service_provider_target_enum";'); + this.addSql('drop type "service_provider_kategorie_enum";'); + } + +} diff --git a/src/modules/keycloak-administration/keycloak-administration.module.spec.ts b/src/modules/keycloak-administration/keycloak-administration.module.spec.ts index 60facfb2d..72a62288a 100644 --- a/src/modules/keycloak-administration/keycloak-administration.module.spec.ts +++ b/src/modules/keycloak-administration/keycloak-administration.module.spec.ts @@ -10,8 +10,10 @@ import { KeycloakAdministrationModule } from './keycloak-administration.module.j import { UserMapperProfile } from './domain/keycloak-client/user.mapper.profile.js'; import { KeycloakAdminClient } from '@s3pweb/keycloak-admin-client-cjs'; import { KeycloakAdministrationService } from './domain/keycloak-admin-client.service.js'; -import { PersonService } from '../person/domain/person.service.js'; -import { PersonRepo } from '../person/persistence/person.repo.js'; +import { PersonenkontextFactory } from '../personenkontext/domain/personenkontext.factory.js'; +import { RolleModule } from '../rolle/rolle.module.js'; +import { PersonModule } from '../person/person.module.js'; +import { OrganisationRepository } from '../organisation/persistence/organisation.repository.js'; describe('KeycloakAdministrationModule', () => { let module: TestingModule; @@ -24,8 +26,10 @@ describe('KeycloakAdministrationModule', () => { KeycloakAdministrationModule, DatabaseTestModule.forRoot(), KeycloakConfigTestModule.forRoot(), + RolleModule, + PersonModule, ], - providers: [PersonService, PersonRepo], + providers: [PersonenkontextFactory, OrganisationRepository], }).compile(); }); diff --git a/src/modules/person/api/dbiam-create-person-with-context.body.params.ts b/src/modules/person/api/dbiam-create-person-with-context.body.params.ts new file mode 100644 index 000000000..2574ebe60 --- /dev/null +++ b/src/modules/person/api/dbiam-create-person-with-context.body.params.ts @@ -0,0 +1,28 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsNotEmpty, IsString, MinLength } from 'class-validator'; +import { OrganisationID, RolleID } from '../../../shared/types/aggregate-ids.types.js'; +import { IsDIN91379A } from '../../../shared/util/din-91379-validation.js'; + +export class DbiamCreatePersonWithContextBodyParams { + @IsDIN91379A() + @IsNotEmpty() + @MinLength(2) + @ApiProperty({ required: true }) + public readonly familienname!: string; + + @IsDIN91379A() + @IsNotEmpty() + @MinLength(2) + @ApiProperty({ required: true }) + public readonly vorname!: string; + + @IsString() + @IsNotEmpty() + @ApiProperty({ type: String }) + public readonly organisationId!: OrganisationID; + + @IsString() + @IsNotEmpty() + @ApiProperty({ type: String }) + public readonly rolleId!: RolleID; +} diff --git a/src/modules/person/api/dbiam-person.controller.integration-spec.ts b/src/modules/person/api/dbiam-person.controller.integration-spec.ts new file mode 100644 index 000000000..b636f14cd --- /dev/null +++ b/src/modules/person/api/dbiam-person.controller.integration-spec.ts @@ -0,0 +1,214 @@ +import { faker } from '@faker-js/faker'; +import { DeepMocked, createMock } from '@golevelup/ts-jest'; +import { MikroORM } from '@mikro-orm/core'; +import { CallHandler, ExecutionContext, INestApplication } from '@nestjs/common'; +import { APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'; +import { Test, TestingModule } from '@nestjs/testing'; +import { Request } from 'express'; +import { Observable } from 'rxjs'; +import request, { Response } from 'supertest'; +import { App } from 'supertest/types.js'; +import { + ConfigTestModule, + DatabaseTestModule, + DoFactory, + KeycloakConfigTestModule, + MapperTestModule, +} from '../../../../test/utils/index.js'; +import { GlobalValidationPipe } from '../../../shared/validation/index.js'; +import { PersonPermissionsRepo } from '../../authentication/domain/person-permission.repo.js'; +import { PersonPermissions } from '../../authentication/domain/person-permissions.js'; +import { PassportUser } from '../../authentication/types/user.js'; +import { OrganisationDo } from '../../organisation/domain/organisation.do.js'; +import { OrganisationsTyp } from '../../organisation/domain/organisation.enums.js'; +import { OrganisationRepo } from '../../organisation/persistence/organisation.repo.js'; +import { RollenArt } from '../../rolle/domain/rolle.enums.js'; +import { Rolle } from '../../rolle/domain/rolle.js'; +import { RolleRepo } from '../../rolle/repo/rolle.repo.js'; +import { PersonApiModule } from '../person-api.module.js'; +import { KeycloakConfigModule } from '../../keycloak-administration/keycloak-config.module.js'; +import { KeycloakAdministrationModule } from '../../keycloak-administration/keycloak-administration.module.js'; + +describe('dbiam Person API', () => { + let app: INestApplication; + let orm: MikroORM; + + let organisationRepo: OrganisationRepo; + let rolleRepo: RolleRepo; + let personpermissionsRepoMock: DeepMocked; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [ + MapperTestModule, + ConfigTestModule, + DatabaseTestModule.forRoot({ isDatabaseRequired: true }), + KeycloakAdministrationModule, + PersonApiModule, + ], + providers: [ + { + provide: APP_PIPE, + useClass: GlobalValidationPipe, + }, + { + provide: PersonPermissionsRepo, + useValue: createMock(), + }, + { + provide: APP_INTERCEPTOR, + useValue: { + intercept(context: ExecutionContext, next: CallHandler): Observable { + const req: Request = context.switchToHttp().getRequest(); + req.passportUser = createMock({ + async personPermissions() { + return personpermissionsRepoMock.loadPersonPermissions(''); + }, + }); + return next.handle(); + }, + }, + }, + ], + }) + .overrideModule(KeycloakConfigModule) + .useModule(KeycloakConfigTestModule.forRoot({ isKeycloakRequired: true })) + .compile(); + + orm = module.get(MikroORM); + organisationRepo = module.get(OrganisationRepo); + rolleRepo = module.get(RolleRepo); + personpermissionsRepoMock = module.get(PersonPermissionsRepo); + + await DatabaseTestModule.setupDatabase(orm); + app = module.createNestApplication(); + await app.init(); + }, 10000000); + + afterAll(async () => { + await orm.close(); + await app.close(); + }); + + beforeEach(async () => { + await DatabaseTestModule.clearDatabase(orm); + }); + + describe('/POST create person with personenkontext', () => { + it('should return created person and personenkontext', async () => { + const organisation: OrganisationDo = await organisationRepo.save( + DoFactory.createOrganisation(false, { typ: OrganisationsTyp.SCHULE }), + ); + const rolle: Rolle = await rolleRepo.save( + DoFactory.createRolle(false, { + administeredBySchulstrukturknoten: organisation.id, + rollenart: RollenArt.LEHR, + }), + ); + + const personpermissions: DeepMocked = createMock(); + personpermissionsRepoMock.loadPersonPermissions.mockResolvedValue(personpermissions); + personpermissions.getOrgIdsWithSystemrecht.mockResolvedValueOnce([organisation.id]); + personpermissions.hasSystemrechtAtOrganisation.mockResolvedValueOnce(true); + + const response: Response = await request(app.getHttpServer() as App) + .post('/dbiam/personen') + .send({ + familienname: faker.person.lastName(), + vorname: faker.person.firstName(), + organisationId: organisation.id, + rolleId: rolle.id, + }); + + expect(response.status).toBe(201); + }); + + it('should return error with status-code=404 if organisation does NOT exist', async () => { + const rolle: Rolle = await rolleRepo.save( + DoFactory.createRolle(false, { + administeredBySchulstrukturknoten: faker.string.uuid(), + rollenart: RollenArt.LEHR, + }), + ); + const permissions: DeepMocked = createMock(); + personpermissionsRepoMock.loadPersonPermissions.mockResolvedValueOnce(permissions); + permissions.hasSystemrechtAtOrganisation.mockResolvedValueOnce(true); + permissions.canModifyPerson.mockResolvedValueOnce(true); + + const response: Response = await request(app.getHttpServer() as App) + .post('/dbiam/personen') + .send({ + familienname: faker.person.lastName(), + vorname: faker.person.firstName(), + organisationId: faker.string.uuid(), + rolleId: rolle.id, + }); + + expect(response.status).toBe(404); + }); + + it('should return error with status-code 400 if specification ROLLE_NUR_AN_PASSENDE_ORGANISATION is NOT satisfied', async () => { + const organisation: OrganisationDo = await organisationRepo.save( + DoFactory.createOrganisation(false, { typ: OrganisationsTyp.SCHULE }), + ); + const rolle: Rolle = await rolleRepo.save( + DoFactory.createRolle(false, { + administeredBySchulstrukturknoten: organisation.id, + rollenart: RollenArt.SYSADMIN, + }), + ); + + const personpermissions: DeepMocked = createMock(); + personpermissions.hasSystemrechtAtOrganisation.mockResolvedValueOnce(true); + personpermissionsRepoMock.loadPersonPermissions.mockResolvedValue(personpermissions); + personpermissions.getOrgIdsWithSystemrecht.mockResolvedValueOnce([organisation.id]); + + const response: Response = await request(app.getHttpServer() as App) + .post('/dbiam/personen') + .send({ + familienname: faker.person.lastName(), + vorname: faker.person.firstName(), + organisationId: organisation.id, + rolleId: rolle.id, + }); + + expect(response.status).toBe(400); + expect(response.body).toEqual({ + code: 400, + i18nKey: 'ROLLE_NUR_AN_PASSENDE_ORGANISATION', + }); + }); + + it('should return error with status-code 404 if user does NOT have permissions', async () => { + const organisation: OrganisationDo = await organisationRepo.save( + DoFactory.createOrganisation(false, { typ: OrganisationsTyp.SCHULE }), + ); + const rolle: Rolle = await rolleRepo.save( + DoFactory.createRolle(false, { + administeredBySchulstrukturknoten: organisation.id, + rollenart: RollenArt.LEHR, + }), + ); + + const personpermissions: DeepMocked = createMock(); + personpermissions.hasSystemrechtAtOrganisation.mockResolvedValueOnce(false); + personpermissionsRepoMock.loadPersonPermissions.mockResolvedValue(personpermissions); + + const response: Response = await request(app.getHttpServer() as App) + .post('/dbiam/personen') + .send({ + familienname: faker.person.lastName(), + vorname: faker.person.firstName(), + organisationId: organisation.id, + rolleId: rolle.id, + }); + expect(response.status).toBe(404); + expect(response.body).toEqual({ + code: 404, + subcode: '01', + titel: 'Angefragte Entität existiert nicht', + beschreibung: 'Die angeforderte Entität existiert nicht', + }); + }); + }); +}); diff --git a/src/modules/person/api/dbiam-person.controller.ts b/src/modules/person/api/dbiam-person.controller.ts new file mode 100644 index 000000000..5d0d29af1 --- /dev/null +++ b/src/modules/person/api/dbiam-person.controller.ts @@ -0,0 +1,91 @@ +import { Body, Controller, HttpCode, HttpStatus, Post, UseFilters } from '@nestjs/common'; +import { + ApiBadRequestResponse, + ApiBearerAuth, + ApiCreatedResponse, + ApiForbiddenResponse, + ApiInternalServerErrorResponse, + ApiOAuth2, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger'; +import { DomainError } from '../../../shared/error/index.js'; +import { SchulConnexErrorMapper } from '../../../shared/error/schul-connex-error.mapper.js'; +import { SchulConnexValidationErrorFilter } from '../../../shared/error/schulconnex-validation-error.filter.js'; +import { Permissions } from '../../authentication/api/permissions.decorator.js'; +import { PersonPermissions } from '../../authentication/domain/person-permissions.js'; +import { EventService } from '../../../core/eventbus/index.js'; +import { PersonenkontextCreatedEvent } from '../../../shared/events/personenkontext-created.event.js'; +import { PersonPersonenkontext, PersonService } from '../domain/person.service.js'; +import { DbiamCreatePersonWithContextBodyParams } from './dbiam-create-person-with-context.body.params.js'; +import { DBiamPersonResponse } from './dbiam-person.response.js'; +import { DbiamPersonenkontextError } from '../../personenkontext/api/dbiam-personenkontext.error.js'; +import { PersonenkontextExceptionFilter } from '../../personenkontext/api/personenkontext-exception-filter.js'; +import { PersonenkontextSpecificationError } from '../../personenkontext/specification/error/personenkontext-specification.error.js'; + +@UseFilters(new SchulConnexValidationErrorFilter(), new PersonenkontextExceptionFilter()) +@ApiTags('dbiam-personen') +@ApiBearerAuth() +@ApiOAuth2(['openid']) +@Controller({ path: 'dbiam/personen' }) +export class DBiamPersonController { + public constructor( + private readonly personService: PersonService, + private readonly eventService: EventService, + ) {} + + @Post() + @HttpCode(HttpStatus.CREATED) + @ApiCreatedResponse({ + description: 'Person with Personenkontext was successfully created.', + type: DBiamPersonResponse, + }) + @ApiBadRequestResponse({ + description: 'The person and the personenkontext could not be created, may due to unsatisfied specifications.', + type: DbiamPersonenkontextError, + }) + @ApiUnauthorizedResponse({ description: 'Not authorized to create person with personenkontext.' }) + @ApiForbiddenResponse({ description: 'Insufficient permission to create person with personenkontext.' }) + @ApiForbiddenResponse({ description: 'Insufficient permissions to create the person with personenkontext.' }) + @ApiBadRequestResponse({ description: 'Request has wrong format.', type: DbiamPersonenkontextError }) + @ApiInternalServerErrorResponse({ + description: 'Internal server error while creating person with personenkontext.', + }) + public async createPersonWithKontext( + @Body() params: DbiamCreatePersonWithContextBodyParams, + @Permissions() permissions: PersonPermissions, + ): Promise { + //Check all references & permissions then save person + const savedPersonWithPersonenkontext: DomainError | PersonPersonenkontext = + await this.personService.createPersonWithPersonenkontext( + permissions, + params.vorname, + params.familienname, + params.organisationId, + params.rolleId, + ); + + if (savedPersonWithPersonenkontext instanceof PersonenkontextSpecificationError) { + throw savedPersonWithPersonenkontext; + } + + if (savedPersonWithPersonenkontext instanceof DomainError) { + throw SchulConnexErrorMapper.mapSchulConnexErrorToHttpException( + SchulConnexErrorMapper.mapDomainErrorToSchulConnexError(savedPersonWithPersonenkontext), + ); + } + + this.eventService.publish( + new PersonenkontextCreatedEvent( + savedPersonWithPersonenkontext.personenkontext.personId, + savedPersonWithPersonenkontext.personenkontext.organisationId, + savedPersonWithPersonenkontext.personenkontext.rolleId, + ), + ); + + return new DBiamPersonResponse( + savedPersonWithPersonenkontext.person, + savedPersonWithPersonenkontext.personenkontext, + ); + } +} diff --git a/src/modules/person/api/dbiam-person.response.ts b/src/modules/person/api/dbiam-person.response.ts new file mode 100644 index 000000000..01fb95f4b --- /dev/null +++ b/src/modules/person/api/dbiam-person.response.ts @@ -0,0 +1,20 @@ +import { ApiProperty } from '@nestjs/swagger'; + +import { PersonResponse } from './person.response.js'; +import { Personenkontext } from '../../personenkontext/domain/personenkontext.js'; +import { Person } from '../domain/person.js'; +import { PersonendatensatzResponse } from './personendatensatz.response.js'; +import { DBiamPersonenkontextResponse } from '../../personenkontext/api/response/dbiam-personenkontext.response.js'; + +export class DBiamPersonResponse { + @ApiProperty() + public person!: PersonResponse; + + @ApiProperty() + public DBiamPersonenkontextResponse!: DBiamPersonenkontextResponse; + + public constructor(person: Person, personenkontext: Personenkontext) { + this.person = new PersonendatensatzResponse(person, true).person; + this.DBiamPersonenkontextResponse = new DBiamPersonenkontextResponse(personenkontext); + } +} diff --git a/src/modules/person/domain/person.service.spec.ts b/src/modules/person/domain/person.service.spec.ts index e5818f3fe..8050a693b 100644 --- a/src/modules/person/domain/person.service.spec.ts +++ b/src/modules/person/domain/person.service.spec.ts @@ -2,18 +2,43 @@ import { Dictionary, Mapper } from '@automapper/core'; import { getMapperToken } from '@automapper/nestjs'; import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { Test, TestingModule } from '@nestjs/testing'; -import { EntityNotFoundError } from '../../../shared/error/index.js'; +import { + DomainError, + EntityNotFoundError, + InvalidAttributeLengthError, + KeycloakClientError, + MissingPermissionsError, +} from '../../../shared/error/index.js'; import { DoFactory } from '../../../../test/utils/do-factory.js'; import { PersonRepo } from '../persistence/person.repo.js'; import { PersonDo } from './person.do.js'; -import { PersonService } from './person.service.js'; +import { PersonPersonenkontext, PersonService } from './person.service.js'; import { Paged } from '../../../shared/paging/index.js'; +import { PersonFactory } from './person.factory.js'; +import { RolleRepo } from '../../rolle/repo/rolle.repo.js'; +import { PersonPermissions } from '../../authentication/domain/person-permissions.js'; +import { OrganisationRepository } from '../../organisation/persistence/organisation.repository.js'; +import { faker } from '@faker-js/faker'; +import { Organisation } from '../../organisation/domain/organisation.js'; +import { PersonRepository } from '../persistence/person.repository.js'; +import { DBiamPersonenkontextRepo } from '../../personenkontext/persistence/dbiam-personenkontext.repo.js'; +import { PersonenkontextFactory } from '../../personenkontext/domain/personenkontext.factory.js'; +import { Person } from './person.js'; +import { Rolle } from '../../rolle/domain/rolle.js'; +import { RollenArt } from '../../rolle/domain/rolle.enums.js'; +import { OrganisationsTyp } from '../../organisation/domain/organisation.enums.js'; +import { RolleNurAnPassendeOrganisationError } from '../../personenkontext/specification/error/rolle-nur-an-passende-organisation.js'; -describe('PersonService', () => { +describe('sut', () => { let module: TestingModule; - let personService: PersonService; + let sut: PersonService; let personRepoMock: DeepMocked; let mapperMock: DeepMocked; + let rolleRepoMock: DeepMocked; + let organisationRepositoryMock: DeepMocked; + let personRepositoryMock: DeepMocked; + let personpermissionsMock: DeepMocked; + let personFactoryMock: DeepMocked; beforeAll(async () => { module = await Test.createTestingModule({ @@ -27,11 +52,44 @@ describe('PersonService', () => { provide: getMapperToken(), useValue: createMock(), }, + { + provide: RolleRepo, + useValue: createMock(), + }, + { + provide: OrganisationRepository, + useValue: createMock(), + }, + { + provide: PersonRepository, + useValue: createMock(), + }, + { + provide: DBiamPersonenkontextRepo, + useValue: createMock(), + }, + { + provide: PersonFactory, + useValue: createMock(), + }, + { + provide: PersonenkontextFactory, + useValue: createMock(), + }, + { + provide: PersonPermissions, + useValue: createMock(), + }, ], }).compile(); - personService = module.get(PersonService); + sut = module.get(PersonService); personRepoMock = module.get(PersonRepo); mapperMock = module.get(getMapperToken()); + rolleRepoMock = module.get(RolleRepo); + organisationRepositoryMock = module.get(OrganisationRepository); + personRepositoryMock = module.get(PersonRepository); + personpermissionsMock = module.get(PersonPermissions); + personFactoryMock = module.get(PersonFactory); }); afterAll(async () => { @@ -43,7 +101,7 @@ describe('PersonService', () => { }); it('should be defined', () => { - expect(personService).toBeDefined(); + expect(sut).toBeDefined(); }); describe('findPersonById', () => { @@ -52,7 +110,7 @@ describe('PersonService', () => { const person: PersonDo = DoFactory.createPerson(true); personRepoMock.findById.mockResolvedValue(person); mapperMock.map.mockReturnValue(person as unknown as Dictionary); - const result: Result> | Error = await personService.findPersonById(person.id); + const result: Result> | Error = await sut.findPersonById(person.id); expect(result).toEqual>>({ ok: true, value: person, @@ -65,7 +123,7 @@ describe('PersonService', () => { const person: PersonDo = DoFactory.createPerson(true); personRepoMock.findById.mockResolvedValue(null); mapperMock.map.mockReturnValue(person as unknown as Dictionary); - const result: Result> | Error = await personService.findPersonById(person.id); + const result: Result> | Error = await sut.findPersonById(person.id); expect(result).toEqual>>({ ok: false, error: new EntityNotFoundError('Person', person.id), @@ -84,7 +142,7 @@ describe('PersonService', () => { mapperMock.map.mockReturnValue(persons as unknown as Dictionary); const personDoWithQueryParam: PersonDo = DoFactory.createPerson(false); - const result: Paged> = await personService.findAllPersons(personDoWithQueryParam, 0, 10); + const result: Paged> = await sut.findAllPersons(personDoWithQueryParam, 0, 10); expect(result.items).toHaveLength(2); }); @@ -95,10 +153,136 @@ describe('PersonService', () => { personRepoMock.findBy.mockResolvedValue([[], 0]); mapperMock.map.mockReturnValue(person as unknown as Dictionary); - const result: Paged> = await personService.findAllPersons(person); + const result: Paged> = await sut.findAllPersons(person); expect(result.items).toBeInstanceOf(Array); expect(result.items).toHaveLength(0); }); }); + + describe('createPersonWithPersonenkontext', () => { + it('should return DomainError if Person Aggregate ist invalid ', async () => { + personFactoryMock.createNew.mockResolvedValueOnce(new InvalidAttributeLengthError('name.vorname')); + rolleRepoMock.findById.mockResolvedValueOnce(DoFactory.createRolle(true)); + organisationRepositoryMock.findById.mockResolvedValueOnce(createMock>()); + + const result: PersonPersonenkontext | DomainError = await sut.createPersonWithPersonenkontext( + personpermissionsMock, + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + ); + expect(result).toBeInstanceOf(DomainError); + }); + + it('should return EntityNotFoundError if Organisation is not found', async () => { + personFactoryMock.createNew.mockResolvedValueOnce(createMock>()); + rolleRepoMock.findById.mockResolvedValueOnce(DoFactory.createRolle(true)); + organisationRepositoryMock.findById.mockResolvedValueOnce(undefined); + + const result: PersonPersonenkontext | DomainError = await sut.createPersonWithPersonenkontext( + personpermissionsMock, + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + ); + expect(result).toBeInstanceOf(EntityNotFoundError); + }); + + it('should return EntityNotFoundError if Rolle is not found', async () => { + personFactoryMock.createNew.mockResolvedValueOnce(createMock>()); + rolleRepoMock.findById.mockResolvedValueOnce(undefined); + organisationRepositoryMock.findById.mockResolvedValueOnce(createMock>()); + + const result: PersonPersonenkontext | DomainError = await sut.createPersonWithPersonenkontext( + personpermissionsMock, + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + ); + expect(result).toBeInstanceOf(EntityNotFoundError); + }); + + it('should return EntityNotFoundError if Rolle can NOT be assigned to organisation', async () => { + personFactoryMock.createNew.mockResolvedValueOnce(createMock>()); + const rolleMock: DeepMocked> = createMock>(); + rolleMock.canBeAssignedToOrga.mockResolvedValueOnce(false); + rolleRepoMock.findById.mockResolvedValueOnce(rolleMock); + organisationRepositoryMock.findById.mockResolvedValueOnce(createMock>()); + + const result: PersonPersonenkontext | DomainError = await sut.createPersonWithPersonenkontext( + personpermissionsMock, + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + ); + expect(result).toBeInstanceOf(EntityNotFoundError); + }); + + it('should return RolleNurAnPassendeOrganisationError if Rolle does NOT match organisation', async () => { + personFactoryMock.createNew.mockResolvedValueOnce(createMock>()); + const rolleMock: DeepMocked> = createMock>({ rollenart: RollenArt.SYSADMIN }); + rolleMock.canBeAssignedToOrga.mockResolvedValueOnce(true); + rolleRepoMock.findById.mockResolvedValueOnce(rolleMock); + organisationRepositoryMock.findById.mockResolvedValueOnce( + createMock>({ typ: OrganisationsTyp.SCHULE }), + ); + + const result: PersonPersonenkontext | DomainError = await sut.createPersonWithPersonenkontext( + personpermissionsMock, + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + ); + expect(result).toBeInstanceOf(RolleNurAnPassendeOrganisationError); + }); + + it('should return MissingPermissionsError if user does NOT have permissions', async () => { + personFactoryMock.createNew.mockResolvedValueOnce(createMock>()); + const rolleMock: DeepMocked> = createMock>({ rollenart: RollenArt.SYSADMIN }); + rolleMock.canBeAssignedToOrga.mockResolvedValueOnce(true); + rolleRepoMock.findById.mockResolvedValueOnce(rolleMock); + organisationRepositoryMock.findById.mockResolvedValueOnce( + createMock>({ typ: OrganisationsTyp.LAND }), + ); + personpermissionsMock.hasSystemrechtAtOrganisation.mockResolvedValueOnce(false); + + const result: PersonPersonenkontext | DomainError = await sut.createPersonWithPersonenkontext( + personpermissionsMock, + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + ); + expect(result).toBeInstanceOf(MissingPermissionsError); + }); + + it('should return DomainError if Person can be saved in the DB', async () => { + personFactoryMock.createNew.mockResolvedValueOnce(createMock>()); + const rolleMock: DeepMocked> = createMock>({ rollenart: RollenArt.SYSADMIN }); + rolleMock.canBeAssignedToOrga.mockResolvedValueOnce(true); + rolleRepoMock.findById.mockResolvedValueOnce(rolleMock); + organisationRepositoryMock.findById.mockResolvedValueOnce( + createMock>({ typ: OrganisationsTyp.LAND }), + ); + personpermissionsMock.hasSystemrechtAtOrganisation.mockResolvedValueOnce(true); + personRepositoryMock.create.mockResolvedValueOnce( + new KeycloakClientError('Username or email already exists'), + ); + + const result: PersonPersonenkontext | DomainError = await sut.createPersonWithPersonenkontext( + personpermissionsMock, + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + faker.string.uuid(), + ); + expect(result).toBeInstanceOf(DomainError); + }); + }); }); diff --git a/src/modules/person/domain/person.service.ts b/src/modules/person/domain/person.service.ts index d3a2faa96..92697a7df 100644 --- a/src/modules/person/domain/person.service.ts +++ b/src/modules/person/domain/person.service.ts @@ -1,14 +1,41 @@ import { Injectable } from '@nestjs/common'; -import { DomainError, EntityNotFoundError } from '../../../shared/error/index.js'; +import { DomainError, EntityNotFoundError, MissingPermissionsError } from '../../../shared/error/index.js'; import { PersonDo } from '../domain/person.do.js'; import { PersonRepo } from '../persistence/person.repo.js'; import { PersonScope } from '../persistence/person.scope.js'; import { Paged } from '../../../shared/paging/paged.js'; import { ScopeOrder } from '../../../shared/persistence/scope.enums.js'; +import { PersonFactory } from './person.factory.js'; +import { Person } from './person.js'; +import { OrganisationRepository } from '../../organisation/persistence/organisation.repository.js'; +import { RolleRepo } from '../../rolle/repo/rolle.repo.js'; +import { Organisation } from '../../organisation/domain/organisation.js'; +import { Rolle } from '../../rolle/domain/rolle.js'; +import { OrganisationMatchesRollenart } from '../../personenkontext/specification/organisation-matches-rollenart.js'; +import { PersonPermissions } from '../../authentication/domain/person-permissions.js'; +import { RollenSystemRecht } from '../../rolle/domain/rolle.enums.js'; +import { PersonRepository } from '../persistence/person.repository.js'; +import { RolleNurAnPassendeOrganisationError } from '../../personenkontext/specification/error/rolle-nur-an-passende-organisation.js'; +import { DBiamPersonenkontextRepo } from '../../personenkontext/persistence/dbiam-personenkontext.repo.js'; +import { PersonenkontextFactory } from '../../personenkontext/domain/personenkontext.factory.js'; +import { Personenkontext } from '../../personenkontext/domain/personenkontext.js'; + +export type PersonPersonenkontext = { + person: Person; + personenkontext: Personenkontext; +}; @Injectable() export class PersonService { - public constructor(private readonly personRepo: PersonRepo) {} + public constructor( + private readonly personRepo: PersonRepo, + private readonly organisationRepo: OrganisationRepository, + private readonly rolleRepo: RolleRepo, + private readonly personRepository: PersonRepository, + private readonly personenkontextRepo: DBiamPersonenkontextRepo, + private readonly personFactory: PersonFactory, + private readonly personenkontextFactory: PersonenkontextFactory, + ) {} public async findPersonById(id: string): Promise, DomainError>> { const person: Option> = await this.personRepo.findById(id); @@ -40,4 +67,93 @@ export class PersonService { items: persons, }; } + + public async createPersonWithPersonenkontext( + permissions: PersonPermissions, + vorname: string, + familienname: string, + organisationId: string, + rolleId: string, + ): Promise { + const person: Person | DomainError = await this.personFactory.createNew({ + vorname: vorname, + familienname: familienname, + }); + if (person instanceof DomainError) { + return person; + } + //Check references & ob der Admin berechtigt ist + const referenceError: Option = await this.checkReferences(organisationId, rolleId); + if (referenceError) { + return referenceError; + } + //Check Permissions für Personenkontext + const permissionsError: Option = await this.checkPermissions(permissions, organisationId); + if (permissionsError) { + return permissionsError; + } + //Save Person + const savedPerson: DomainError | Person = await this.personRepository.create(person); + if (savedPerson instanceof DomainError) { + return savedPerson; + } + + const personenkontext: Personenkontext = this.personenkontextFactory.createNew( + savedPerson.id, + organisationId, + rolleId, + ); + //Save Personenkontext + const savedPersonenkontext: Personenkontext = await this.personenkontextRepo.save(personenkontext); + return { + person: savedPerson, + personenkontext: savedPersonenkontext, + }; + } + + private async checkReferences(organisationId: string, rolleId: string): Promise> { + const [orga, rolle]: [Option>, Option>] = await Promise.all([ + this.organisationRepo.findById(organisationId), + this.rolleRepo.findById(rolleId), + ]); + + if (!orga) { + return new EntityNotFoundError('Organisation', organisationId); + } + + if (!rolle) { + return new EntityNotFoundError('Rolle', rolleId); + } + + // Can rolle be assigned at target orga + const canAssignRolle: boolean = await rolle.canBeAssignedToOrga(organisationId); + if (!canAssignRolle) { + return new EntityNotFoundError('rolle', rolleId); // Rolle does not exist for the chosen organisation + } + + //The aimed organisation needs to match the type of role to be assigned + const organisationMatchesRollenart: OrganisationMatchesRollenart = new OrganisationMatchesRollenart(); + if (!organisationMatchesRollenart.isSatisfiedBy(orga, rolle)) { + return new RolleNurAnPassendeOrganisationError(); + } + + return undefined; + } + + private async checkPermissions( + permissions: PersonPermissions, + organisationId: string, + ): Promise> { + // Check if logged in person has permission + const hasPermissionAtOrga: boolean = await permissions.hasSystemrechtAtOrganisation(organisationId, [ + RollenSystemRecht.PERSONEN_VERWALTEN, + ]); + + // Missing permission on orga + if (!hasPermissionAtOrga) { + return new MissingPermissionsError('Unauthorized to manage persons at the organisation'); + } + + return undefined; + } } diff --git a/src/modules/person/person-api.module.ts b/src/modules/person/person-api.module.ts index 96d757d5d..6efab4d8b 100644 --- a/src/modules/person/person-api.module.ts +++ b/src/modules/person/person-api.module.ts @@ -15,6 +15,8 @@ import { DBiamPersonenuebersichtController } from './api/personenuebersicht/dbia import { DBiamPersonenkontextRepo } from '../personenkontext/persistence/dbiam-personenkontext.repo.js'; import { PersonInfoController } from './api/person-info.controller.js'; import { PersonApiMapper } from './mapper/person-api.mapper.js'; +import { DBiamPersonController } from './api/dbiam-person.controller.js'; +import { EventModule } from '../../core/eventbus/event.module.js'; @Module({ imports: [ @@ -25,6 +27,7 @@ import { PersonApiMapper } from './mapper/person-api.mapper.js'; OrganisationModule, KeycloakAdministrationModule, LoggerModule.register(PersonApiModule.name), + EventModule, ], providers: [ PersonApiMapperProfile, @@ -34,6 +37,12 @@ import { PersonApiMapper } from './mapper/person-api.mapper.js'; DBiamPersonenkontextRepo, PersonApiMapper, ], - controllers: [PersonController, PersonFrontendController, DBiamPersonenuebersichtController, PersonInfoController], + controllers: [ + PersonController, + PersonFrontendController, + DBiamPersonenuebersichtController, + PersonInfoController, + DBiamPersonController, + ], }) export class PersonApiModule {} diff --git a/src/modules/personenkontext/api/dbiam-personenkontext.error.ts b/src/modules/personenkontext/api/dbiam-personenkontext.error.ts index ecf412a11..d518adcbe 100644 --- a/src/modules/personenkontext/api/dbiam-personenkontext.error.ts +++ b/src/modules/personenkontext/api/dbiam-personenkontext.error.ts @@ -7,6 +7,7 @@ export enum PersonenkontextSpecificationErrorI18nTypes { GLEICHE_ROLLE_AN_KLASSE_WIE_SCHULE = 'GLEICHE_ROLLE_AN_KLASSE_WIE_SCHULE', ORGANISATION_MATCHES_ROLLENART = 'ORGANISATION_MATCHES_ROLLENART', PERSONENKONTEXT_ANLAGE_ERROR = 'PERSONENKONTEXT_ANLAGE_ERROR', + ROLLE_NUR_AN_PASSENDE_ORGANISATION = 'ROLLE_NUR_AN_PASSENDE_ORGANISATION', } export type DbiamPersonenkontextErrorProps = DbiamErrorProps & { i18nKey: PersonenkontextSpecificationErrorI18nTypes; diff --git a/src/modules/personenkontext/api/personenkontext-exception-filter.ts b/src/modules/personenkontext/api/personenkontext-exception-filter.ts index 30b21886c..3aaed7a31 100644 --- a/src/modules/personenkontext/api/personenkontext-exception-filter.ts +++ b/src/modules/personenkontext/api/personenkontext-exception-filter.ts @@ -9,6 +9,7 @@ import { NurLehrUndLernAnKlasseError } from '../specification/error/nur-lehr-und import { GleicheRolleAnKlasseWieSchuleError } from '../specification/error/gleiche-rolle-an-klasse-wie-schule.error.js'; import { PersonenkontextSpecificationError } from '../specification/error/personenkontext-specification.error.js'; import { OrganisationMatchesRollenartError } from '../specification/error/organisation-matches-rollenart.error.js'; +import { RolleNurAnPassendeOrganisationError } from '../specification/error/rolle-nur-an-passende-organisation.js'; @Catch(PersonenkontextSpecificationError) export class PersonenkontextExceptionFilter implements ExceptionFilter { @@ -34,6 +35,13 @@ export class PersonenkontextExceptionFilter implements ExceptionFilter) { + super( + `Personenkontext could not be created/updated because it violates ${PersonenkontextSpecificationErrorI18nTypes.ROLLE_NUR_AN_PASSENDE_ORGANISATION} specification`, + details, + ); + } +}