diff --git a/lib/Repair/RenameDutchSchemaSlugs.php b/lib/Repair/RenameDutchSchemaSlugs.php index f66d4b62..d8f4b844 100644 --- a/lib/Repair/RenameDutchSchemaSlugs.php +++ b/lib/Repair/RenameDutchSchemaSlugs.php @@ -69,7 +69,7 @@ class RenameDutchSchemaSlugs implements IRepairStep { * @var array */ public const SLUG_MAP = [ - 'beoordeeling' => 'assessment', + 'beoordeeling' => 'software-review', 'bioMaatregel' => 'bioMeasure', 'contactpersoon' => 'contactPerson', 'dienst' => 'service', diff --git a/lib/Service/ModerationService.php b/lib/Service/ModerationService.php index 62dfac8a..1d0b6f79 100644 --- a/lib/Service/ModerationService.php +++ b/lib/Service/ModerationService.php @@ -63,7 +63,7 @@ class ModerationService { /** * The review moderated catalog object type. */ - public const MODERATED_TYPE_REVIEW = 'assessment'; + public const MODERATED_TYPE_REVIEW = 'software-review'; /** * Pending (awaiting moderation) state — shared field value across types. diff --git a/lib/Service/ReviewAggregateService.php b/lib/Service/ReviewAggregateService.php index 8e13a1d7..510cb47a 100644 --- a/lib/Service/ReviewAggregateService.php +++ b/lib/Service/ReviewAggregateService.php @@ -43,7 +43,7 @@ class ReviewAggregateService { /** * The catalog object type reviews live on. */ - public const REVIEW_TYPE = 'assessment'; + public const REVIEW_TYPE = 'software-review'; /** * Public-visible moderation state. diff --git a/lib/Service/ReviewService.php b/lib/Service/ReviewService.php index 3bc2e1c8..640a5ee9 100644 --- a/lib/Service/ReviewService.php +++ b/lib/Service/ReviewService.php @@ -47,7 +47,7 @@ class ReviewService { /** * The catalog object type reviews live on. */ - public const REVIEW_TYPE = 'assessment'; + public const REVIEW_TYPE = 'software-review'; /** * Moderation state of a freshly-submitted review — mirrors diff --git a/lib/Service/SettingsService.php b/lib/Service/SettingsService.php index 280c852a..7099a8a3 100644 --- a/lib/Service/SettingsService.php +++ b/lib/Service/SettingsService.php @@ -119,7 +119,7 @@ class SettingsService { * @var array */ public const LEGACY_SCHEMA_KEY = [ - 'assessment' => 'beoordeeling_schema', + 'software-review' => 'beoordeeling_schema', 'bioMeasure' => 'bioMaatregel_schema', 'connection' => 'koppeling_schema', 'contactPerson' => 'contactpersoon_schema', @@ -907,7 +907,7 @@ public function getSchemaIdForObjectType(string $objectType): ?int { // (`koppeling_gebruik_schema`). Renaming a subset would resolve some // types and silently leave others reporting "not configured", which is // how the ratings feature died once already. Tracked as its own change. - 'assessment' => 'beoordeeling_schema', + 'software-review' => 'beoordeeling_schema', 'service' => 'dienst_schema', 'usage' => 'gebruik_schema', 'contract' => 'contract_schema', @@ -4143,7 +4143,7 @@ private function configureVoorzieningen(): array { 'usage' => 'gebruik_schema', 'contract' => 'contract_schema', 'connection' => 'koppeling_schema', - 'assessment' => 'beoordeeling_schema', + 'software-review' => 'beoordeeling_schema', 'module' => 'module_schema', 'compliancy' => 'compliancy_schema', 'moduleversie' => 'moduleVersie_schema', diff --git a/lib/Settings/softwarecatalogus_register.json b/lib/Settings/softwarecatalogus_register.json index f785464c..65402601 100644 --- a/lib/Settings/softwarecatalogus_register.json +++ b/lib/Settings/softwarecatalogus_register.json @@ -3,7 +3,7 @@ "info": { "title": "Software Catalog Register", "description": "Register containing AMEF and Voorzieningen schemas for the VNG Software Catalog application. This configuration includes schemas for applications, services, organizations, and compliance tracking.", - "version": "2.4.4", + "version": "2.5.0", "changelog": "2.4.4: organization.status was left behind by #520's enum translation — its `default` was still 'Concept' and its whole x-openregister-lifecycle block still named Concept/Actief/Deactief, while the enum and the migrated rows are Draft/Active/Inactive/merged. A default outside its own enum makes every newly created organisation fall out of the Organisations index filter, and a lifecycle whose from/to values match no row offers no transition at all — neither raises an error. The schema version is bumped with it because a deployed version >= the declared one makes the import SKIP, and OpenRegister's schemaContentDiffers() escape hatch compares only properties/required/authorization — never `configuration` — so a lifecycle-only edit would never have deployed. 2.4.3: Re-authored Dutch schema-level titles to English (dienst, kwetsbaarheid, contactpersoon, organisatie, gebruik, koppeling, beoordeeling, module, bioMaatregel, moduleVersie, sbomComponent); schema keys unchanged, Dutch labels now come from the app's l10n translation files. 2.4.2: Moved SBOM provenance properties (sbomLastImportedAt, sbomFormat, sbomFileName, sbomComponents) from the organisatie schema to moduleVersie, where SBOM imports actually record them; without this the moduleVersie magic table lacked the columns so recordProvenance() writes were silently dropped and the import-status endpoint always reported 'never imported'. 2.4.1: Re-authored Dutch schema property titles to English (property keys unchanged); Dutch labels now come from the app's l10n translation files." }, "x-openregister": { @@ -831,7 +831,7 @@ "usage", "contract", "connection", - "assessment", + "software-review", "compliancy", "moduleVersion", "sbomComponent", @@ -890,7 +890,7 @@ "magicMapping": true, "autoCreateTable": true }, - "assessment": { + "software-review": { "magicMapping": true, "autoCreateTable": true }, @@ -3941,9 +3941,9 @@ } } }, - "assessment": { + "software-review": { "uri": null, - "slug": "assessment", + "slug": "software-review", "x-openregister-notifications": { "review-submitted": { "trigger": {"type": "created"}, @@ -4020,7 +4020,7 @@ "handling": "related-object" }, "$ref": "#/components/schemas/module", - "inversedBy": "assessment" + "inversedBy": "software-review" } }, "diensten": { diff --git a/lib/Settings/stackiq_mock_register.json b/lib/Settings/stackiq_mock_register.json index 64cc2513..6a87e128 100644 --- a/lib/Settings/stackiq_mock_register.json +++ b/lib/Settings/stackiq_mock_register.json @@ -2,7 +2,7 @@ "openapi": "3.0.0", "info": { "title": "stackiq demo data", - "version": "1.0.0", + "version": "1.1.0", "description": "Demo data covering every schema this app supplies, offered as the first step of the app's setup walkthrough. Generated from the schemas themselves, so every object satisfies the schema that will validate it." }, "x-openregister": { @@ -27,7 +27,7 @@ } }, "schemas": { - "assessment": { + "software-review": { "properties": { "auteur": { "type": "string", @@ -104,7 +104,7 @@ "handling": "related-object" }, "$ref": "#/components/schemas/module", - "inversedBy": "assessment" + "inversedBy": "software-review" } }, "diensten": { @@ -211,7 +211,7 @@ "rating" ], "uri": null, - "slug": "assessment", + "slug": "software-review", "x-openregister-notifications": { "review-submitted": { "trigger": { @@ -7303,7 +7303,7 @@ { "@self": { "register": "stackiq", - "schema": "assessment", + "schema": "software-review", "slug": "assessment-voorbeeld-name-1-1" }, "name": "Voorbeeld Name 1", @@ -7326,7 +7326,7 @@ { "@self": { "register": "stackiq", - "schema": "assessment", + "schema": "software-review", "slug": "assessment-voorbeeld-name-2-2" }, "name": "Voorbeeld Name 2", @@ -7349,7 +7349,7 @@ { "@self": { "register": "stackiq", - "schema": "assessment", + "schema": "software-review", "slug": "assessment-voorbeeld-name-3-3" }, "name": "Voorbeeld Name 3", @@ -8872,7 +8872,7 @@ { "@self": { "register": "vng-gemma", - "schema": "assessment", + "schema": "software-review", "slug": "assessment-voorbeeld-name-1-1" }, "name": "Voorbeeld Name 1", @@ -8895,7 +8895,7 @@ { "@self": { "register": "vng-gemma", - "schema": "assessment", + "schema": "software-review", "slug": "assessment-voorbeeld-name-2-2" }, "name": "Voorbeeld Name 2", @@ -8918,7 +8918,7 @@ { "@self": { "register": "vng-gemma", - "schema": "assessment", + "schema": "software-review", "slug": "assessment-voorbeeld-name-3-3" }, "name": "Voorbeeld Name 3", diff --git a/src/manifest.json b/src/manifest.json index b3f99949..13267417 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -769,7 +769,7 @@ "title": "Reviews", "config": { "register": "@resolve:voorzieningen_register", - "schema": "assessment", + "schema": "software-review", "columns": [ "name", "auteur", @@ -790,10 +790,10 @@ "title": "Review", "config": { "register": "@resolve:voorzieningen_register", - "schema": "assessment", + "schema": "software-review", "_note": "Review / assessment archetype (beoordeeling). A review is read for its verdict then its subject: body leads with the review data (name, short + long markdown description, score) 8-wide left, a prominent score stat (waardering) top-right, and a Related panel + supporting-evidence Files panel stacked beneath it surfacing the reviewed subjects — the beoordeeling links modules[], diensten[] and koppelingen[] (the things assessed) plus its gebruik context. A review does not communicate, so per the comms hard-rule NO Emails/Meetings widgets appear. Audit trail stays a sidebar tab. FIX (softwarecatalog audit): rv-data (Review) now anchors gridX0/gridY0 so the left column starts flush with the right column instead of a whitespace hole opening up beside the score stat; rv-score/rv-related/rv-files were re-stacked in the right column to match rv-data's height. rv-related's title shortened from 'Reviewed modules & services' (truncated to 'Reviewed modules & s…' in the widget header) to 'Reviewed modules'.", "widgets": [ - { "id": "rv-score", "type": "stat", "title": "Rating", "icon": "Star", "content": { "label": "Rating", "icon": "Star", "source": { "register": "@resolve:voorzieningen_register", "schema": "assessment", "metric": "avg", "field": "rating", "filter": { "id": "@objectId" } } } }, + { "id": "rv-score", "type": "stat", "title": "Rating", "icon": "Star", "content": { "label": "Rating", "icon": "Star", "source": { "register": "@resolve:voorzieningen_register", "schema": "software-review", "metric": "avg", "field": "rating", "filter": { "id": "@objectId" } } } }, { "id": "rv-data", "type": "data", "title": "Review", "icon": "NoteTextOutline", "content": { "columns": 2 } }, { "id": "rv-related", "type": "related", "title": "Reviewed modules", "icon": "LinkVariant" }, { "id": "rv-files", "type": "integration", "integrationId": "files", "title": "Supporting evidence", "icon": "FolderOutline" } diff --git a/tests/Unit/Service/SettingsServiceCatalogTypeResolutionTest.php b/tests/Unit/Service/SettingsServiceCatalogTypeResolutionTest.php index ea4dea83..e7b2945e 100644 --- a/tests/Unit/Service/SettingsServiceCatalogTypeResolutionTest.php +++ b/tests/Unit/Service/SettingsServiceCatalogTypeResolutionTest.php @@ -98,16 +98,17 @@ function (string $app, string $key, string $default = '') use ($voorzieningenCon }//end makeService() /** - * `beoordeeling` — the type the ratings feature resolves — must map to - * schema 43 and register 11. + * `beoordeeling` — the config key the ratings feature resolves through — + * must map to schema 43 and register 11 for the `software-review` type. + * The object TYPE moved with the schema slug; the config KEY did not. * * @return void */ public function testBeoordeelingResolvesRegisterAndSchema(): void { $service = $this->makeService(); - $this->assertSame(43, $service->getSchemaIdForObjectType('assessment'), 'schema id'); - $this->assertSame(11, $service->getRegisterIdForObjectType('assessment'), 'register id'); + $this->assertSame(43, $service->getSchemaIdForObjectType('software-review'), 'schema id'); + $this->assertSame(11, $service->getRegisterIdForObjectType('software-review'), 'register id'); }//end testBeoordeelingResolvesRegisterAndSchema() @@ -131,7 +132,7 @@ public function testEveryCatalogTypeResolves(): void { 'sector' => 34, 'compliancy' => 51, 'moduleVersion' => 52, - 'assessment' => 43, + 'software-review' => 43, ]; foreach ($types as $type => $schemaId) { diff --git a/tests/e2e/spec-coverage/catalog-ratings.spec.ts b/tests/e2e/spec-coverage/catalog-ratings.spec.ts index 64d86a62..4aca5eb9 100644 --- a/tests/e2e/spec-coverage/catalog-ratings.spec.ts +++ b/tests/e2e/spec-coverage/catalog-ratings.spec.ts @@ -8,7 +8,7 @@ * ModuleDetail (/modules/:id) * src/modals/SubmitReviewModal.vue "Write a review" * src/views/settings/sections/ModerationQueue.vue - * reused for type="assessment" + * reused for type="software-review" * at /settings/admin/stackiq * manifest page `Reviews` (/reviews) the reviews index * @@ -79,7 +79,7 @@ test.beforeAll(async () => { test.afterAll(async () => { if (!ctx || !config) return - for (const schema of ['assessment', 'module']) { + for (const schema of ['software-review', 'module']) { const rows = await findAll(ctx, config.register, schema) for (const row of rows) { if (JSON.stringify(row).includes(RUN_ID)) { @@ -136,7 +136,7 @@ async function newAnonymousContext(): Promise { /** Open the seeded module's detail page and wait for the reviews panel. */ async function openModuleReviews(page: Page): Promise { - await page.goto(`${APP_BASE.replace(/\/$/, "")}/modules/${moduleUuid}`, { + await page.goto(`${APP_BASE.replace(/\/$/, '')}/modules/${moduleUuid}`, { waitUntil: 'domcontentloaded', }) await page @@ -379,7 +379,7 @@ test('reviews: a module with no approved reviews shows the empty aggregate, not }) expect(uuid, 'isolated module fixture has no uuid').not.toBe('') - await page.goto(`${APP_BASE.replace(/\/$/, "")}/modules/${uuid}`, { + await page.goto(`${APP_BASE.replace(/\/$/, '')}/modules/${uuid}`, { waitUntil: 'domcontentloaded', }) await page @@ -538,7 +538,7 @@ test('reviews: an anonymous POST cannot create a review', async () => { const rows = await findAll( ctx, config.register, - 'assessment', + 'software-review', `Anon review ${RUN_ID}`, ) expect( @@ -570,7 +570,7 @@ test('reviews: a client-supplied auteur/status is stripped, not stored', async ( `POST /api/reviews returned ${res.status()}: ${await res.text()}`, ).toBeLessThan(300) - const rows = await findAll(ctx, config.register, 'assessment', reviewTitle) + const rows = await findAll(ctx, config.register, 'software-review', reviewTitle) const stored = rows.find((r) => String(r.name ?? '') === reviewTitle) expect(stored, 'the review was not persisted at all').toBeTruthy() // The client-supplied author was IGNORED — the session identity won.