Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .claude/skills/test-architectuur-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Sarah validates GEMMA compliance, reviews architecture decisions, and monitors c
- **Browser**: Use Playwright MCP browser tools (prefixed `mcp__browser-N__`, where N is assigned by the orchestrator)
- **Login URL**: `{FRONTEND}/login`

## Organization & Permissions Context

Sarah's account is in the Default Organisation (expected for VNG roles). The org permission system requires the internal Nextcloud org UUID to match a register object. If org fetch fails (404 in console), edit/delete buttons will be disabled — this is expected for VNG-raadpleger roles that primarily read/view rather than edit. Run `bash softwarecatalog/test-setup.sh` if org assignments are broken.

## Test Scope

### Primary Steps
Expand Down
8 changes: 8 additions & 0 deletions .claude/skills/test-functioneel-beheerder.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ Peter has full system access. He activates organizations, manages users, maintai
- **Login URL**: `{FRONTEND}/login`
- **Backend Admin**: `{BACKEND}/` ({ADMIN_USER}:{ADMIN_PASS})

## Organization & Permissions Context

Peter's account (`peter.vandijk@test.nl`) is in the Default Organisation. **Important**: the admin user (`admin`) has a known limitation — "Default Organisation" has no matching register object in `voorzieningen/organisatie`, which causes org fetch 404 errors and disables edit/delete in beheer.

- **For frontend beheer testing**: Log in as `peter.vandijk@test.nl` (NOT `admin`). Peter has full admin group membership and a proper org assignment.
- **For Nextcloud backend testing** (OpenCatalogi admin, OpenRegister config): Use `admin:admin` via the backend URL — these features don't depend on the org permission system.
- If you see "org fetch error" or disabled edit/delete buttons, the active org UUID doesn't have a matching register object. Run `bash softwarecatalog/test-setup.sh` to fix org assignments.

## Test Scope

### Primary Steps
Expand Down
10 changes: 10 additions & 0 deletions .claude/skills/test-gemeente.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ Maria manages her municipality's software landscape in the Softwarecatalogus. Sh
- **Browser**: Use Playwright MCP browser tools (prefixed `mcp__browser-N__`, where N is assigned by the orchestrator)
- **Login URL**: `{FRONTEND}/login`

## Organization & Permissions Context

Maria's active organization is **Test Gemeente**. The internal Nextcloud org UUID matches a register object in `voorzieningen/organisatie`, which is required for edit/delete permissions to work.

- **Beheer tables** show objects based on RBAC rules — gebruik-beheerder can see ALL objects (not just own org) for most schemas
- **Edit/Delete buttons** require the org data fetch to succeed — if you see disabled actions or missing buttons, check for org fetch 404 errors in the console
- **Do NOT test beheer as admin** — admin's "Default Organisation" has no register object, so org fetch always fails and permissions are broken
- The test setup script (`bash softwarecatalog/test-setup.sh`) creates test objects as maria.vanderberg so they get the correct org assignment
- If beheer tables are empty or missing expected test objects, run the test setup script

## Test Scope

### Primary Steps
Expand Down
11 changes: 11 additions & 0 deletions .claude/skills/test-leverancier.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ Jan manages his company's products in the Softwarecatalogus. He registers applic
- **Browser**: Use Playwright MCP browser tools (prefixed `mcp__browser-N__`, where N is assigned by the orchestrator)
- **Login URL**: `{FRONTEND}/login`

## Organization & Permissions Context

Jan's active organization is **Test Leverancier BV**. The internal Nextcloud org UUID matches a register object in `voorzieningen/organisatie`, which is required for edit/delete permissions to work.

- **Beheer tables** only show objects owned by Jan's org (RBAC scoping by `@self.organisation`)
- **Edit/Delete buttons** require the org data fetch to succeed — if you see disabled actions or missing buttons, check for org fetch 404 errors in the console
- **Do NOT test beheer as admin** — admin's "Default Organisation" has no register object, so org fetch always fails and permissions are broken
- The test setup script (`bash softwarecatalog/test-setup.sh`) creates test objects as jan.pietersen so they get the correct org assignment
- If beheer tables are empty, run the test setup script to create/verify test objects

## Test Scope

This agent tests the following steps from the test flow (`testen.md`):
Expand Down Expand Up @@ -126,6 +136,7 @@ This agent tests the following steps from the test flow (`testen.md`):
| #453 | Zoeken: filters van slag met filter Type=Koppeling | Step 14 |
| #454 | Wizard koppelingen: Reeds bestaande koppelingen voor worden niet gevonden | Step 11 |
| #456 | Consistentie in werking van wizards | Step 7 |
| #457 | Koppeling: verwijderen geeft een 400-error | Step 11 |

## Acceptance Criteria Reference

Expand Down
4 changes: 4 additions & 0 deletions .claude/skills/test-samenwerking.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Linda represents a collaboration that acts as BOTH a supplier (offering shared s
- **Browser**: Use Playwright MCP browser tools (prefixed `mcp__browser-N__`, where N is assigned by the orchestrator)
- **Login URL**: `{FRONTEND}/login`

## Organization & Permissions Context

Linda's active organization is **Test Samenwerking**. The org permission system requires the internal Nextcloud org UUID to match a register object in `voorzieningen/organisatie`. If org fetch fails (404 in console), edit/delete buttons will be disabled. Do NOT test beheer features as `admin` — use the test persona accounts. Run `bash softwarecatalog/test-setup.sh` if org assignments are broken.

## Test Scope

### Primary Steps
Expand Down
4 changes: 4 additions & 0 deletions .claude/skills/test-security-officer.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Mark monitors security requirements, validates privacy implementations, and ensu
- **Browser**: Use Playwright MCP browser tools (prefixed `mcp__browser-N__`, where N is assigned by the orchestrator)
- **Login URL**: `{FRONTEND}/login`

## Organization & Permissions Context

Mark's active organization is **Test Gemeente** (same as Maria). The org permission system requires the internal Nextcloud org UUID to match a register object in `voorzieningen/organisatie`. If org fetch fails (404 in console), edit/delete buttons will be disabled. Do NOT test beheer features as `admin` — use the test persona accounts. Run `bash softwarecatalog/test-setup.sh` if org assignments are broken.

## Test Scope

### Primary Steps
Expand Down
91 changes: 91 additions & 0 deletions .github/workflows/sbom.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: SBOM

on:
push:
branches: [main, development, feature/**, bugfix/**, hotfix/**]
pull_request:
branches: [main, development]

jobs:
sbom:
runs-on: ubuntu-latest
name: "SBOM Generation & Validation"

steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref || github.ref_name }}
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
extensions: mbstring, intl, zip, gd, curl, xml, json
tools: composer:v2

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Install Composer dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader

- name: Generate PHP SBOM
run: composer CycloneDX:make-sbom --output-format=JSON --output-file=bom-php.cdx.json --spec-version=1.5 --omit=dev --omit=plugin

- name: Install npm dependencies
run: npm ci

- name: Generate npm SBOM
run: npx @cyclonedx/cyclonedx-npm --output-file bom-npm.cdx.json --spec-version 1.5 --omit dev

- name: Merge PHP + npm SBOMs
run: |
jq -s '.[0] * {components: ([.[].components[]?] | unique_by(.purl // .name))}' bom-php.cdx.json bom-npm.cdx.json > sbom.cdx.json

- name: Install Grype
uses: anchore/scan-action/download-grype@v5

- name: CVE scan SBOM
run: grype sbom:sbom.cdx.json --fail-on critical

- name: Composer audit
run: composer audit --format=json || true

- name: npm audit
run: npm audit --audit-level=critical

- name: Commit SBOM
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add sbom.cdx.json
if git diff --cached --quiet; then
echo "No SBOM changes to commit"
else
git commit -m "chore: update SBOM"
git push
fi

- name: Upload SBOM artifact
uses: actions/upload-artifact@v4
with:
name: sbom-softwarecatalog
path: sbom.cdx.json
retention-days: 90

- name: Attach SBOM to release
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: softprops/action-gh-release@v2
with:
files: sbom.cdx.json
1 change: 1 addition & 0 deletions .phpunit.cache/test-results
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":2,"defects":{"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleOrganizationCreatedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactCreatedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerCreatedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactUpdatedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerUpdatedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactDeletedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerDeletedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerLockedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerUnlockedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactRevertedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerRevertedEvent":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleEventWithNullObject":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testExceptionHandlingDuringEventProcessing":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\OrganisationUserWorkflowTest::testCompleteOrganisationUserWorkflow":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\OrganisationUserWorkflowTest::testWorkflowWithGemeenteOrganisation":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\OrganisationUserWorkflowTest::testWorkflowWithSamenwerkingOrganisation":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\OrganisationUserWorkflowTest::testWorkflowWithCommunityOrganisation":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\OrganisationUserWorkflowTest::testConvertContactpersoonWhenUserAlreadyExists":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\OrganisationUserWorkflowTest::testPasswordChangeWithInvalidUser":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\ContactPersonHandlerTest::testGetRoleGroupByOrganizationType":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\ContactPersonHandlerTest::testAddUserToGroupWithCheck":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testSendOrganizationWelcomeEmailSuccess":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testSendOrganizationWelcomeEmailWithoutEmail":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testSendGebruikerWelcomeEmailSuccess":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testSendContactWelcomeEmailSuccess":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testSendEmailFailure":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testSendEmailException":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testGetSenderEmail":8,"OCA\\SoftwareCatalog\\Tests\\Unit\\Service\\EmailServiceTest::testGetSenderName":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testGetKoppelingenGebruikForProductUuid":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testGetKoppelingenGebruikForModuleUuid":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testGetKoppelingenGebruikForOrganisationUuid":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testAmbtenaarAccessToAllOrganisations":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testPaginationParameters":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testResponseFormatConsistency":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testInvalidUuidReturnsEmptyResults":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testOrganisationOwnerAccessToOwnedProductUsage":8,"OCA\\SoftwareCatalog\\Tests\\Integration\\KoppelingenGebruikIntegrationTest::testThreeOrganisationAccessControlMatrix":8},"times":{"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleOrganizationCreatedEvent":0.029,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactCreatedEvent":0.001,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerCreatedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactUpdatedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerUpdatedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactDeletedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerDeletedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerLockedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerUnlockedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleContactRevertedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleGebruikerRevertedEvent":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testHandleEventWithNullObject":0,"OCA\\SoftwareCatalog\\Tests\\Unit\\EventListener\\SoftwareCatalogEventListenerTest::testExceptionHandlingDuringEventProcessing":0}}
9 changes: 5 additions & 4 deletions aanvullende-informatie.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
> Alle issues zijn ook beschikbaar als individuele markdown bestanden in de [issues/](issues/) map (met beschrijving, reacties en afbeeldingen).
> Zie ook: [issues.md](issues.md) voor de volledige lijst met acceptatiecriteria per issue.

**Totaal: 159 issues** | Open: 207 | Gesloten: 233
**Laatste sync:** 2026-03-05 | +6 nieuwe issues (#451-#456) | +2 gesloten issues (#225, #315)
**Totaal: 160 issues** | Open: 207 | Gesloten: 233
**Laatste sync:** 2026-03-09 | +1 nieuw issue (#457)

---

Expand Down Expand Up @@ -317,9 +317,9 @@ Na het verwerken van elk issue, update deze tabel:
---

## Open issues
*76 issues*
*77 issues*

### Bug (45)
### Bug (46)

| # | Issue | Analyse | GitHub | Checked |
|---|-------|---------|--------|--------|
Expand Down Expand Up @@ -368,6 +368,7 @@ Na het verwerken van elk issue, update deze tabel:
| [454](issues/454.md) | Wizard koppelingen: Reeds bestaande koppelingen niet gevonden | Cross-supplier koppelingen niet zichtbaar in wizard | [#454](https://github.com/VNG-Realisatie/Softwarecatalogus/issues/454) | [ ] |
| [455](issues/455.md) | Tabblad koppelingen en contactpersonen publiekelijk niet getoond | Koppelingen en contactpersonen tabs niet zichtbaar voor publiek (RBAC) | [#455](https://github.com/VNG-Realisatie/Softwarecatalogus/issues/455) | [ ] |
| [456](issues/456.md) | Consistentie in werking van wizards | Wizard afsluiting inconsistent qua tekst, knoppen en flow | [#456](https://github.com/VNG-Realisatie/Softwarecatalogus/issues/456) | [ ] |
| [457](issues/457.md) | Koppeling: verwijderen geeft een 400-error | DELETE koppeling retourneert 400 bij zowel geimporteerde als nieuwe koppelingen | [#457](https://github.com/VNG-Realisatie/Softwarecatalogus/issues/457) | [ ] |

### Datakwaliteit (10)

Expand Down
2 changes: 2 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,7 @@
['name' => 'gebruik#getGebruiken', 'url' => '/api/gebruik', 'verb' => 'GET'],
['name' => 'gebruik#getGebruikenForDeelnemer', 'url' => '/api/gebruik/deelnemer', 'verb' => 'GET'],

// SPA catch-all — serves the Vue app for any frontend route (history mode routing)
['name' => 'dashboard#page', 'url' => '/{path}', 'verb' => 'GET', 'requirements' => ['path' => '.+'], 'defaults' => ['path' => '']],
],
];
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"twig/twig": "^3.8"
},
"require-dev": {
"cyclonedx/cyclonedx-php-composer": "^6.2",
"edgedesign/phpqa": "^1.27",
"guzzlehttp/guzzle": "^7.8",
"nextcloud/coding-standard": "^1.4",
Expand All @@ -92,7 +93,8 @@
"allow-plugins": {
"bamarni/composer-bin-plugin": true,
"php-http/discovery": true,
"dealerdirect/phpcodesniffer-composer-installer": true
"dealerdirect/phpcodesniffer-composer-installer": true,
"cyclonedx/cyclonedx-php-composer": true
},
"optimize-autoloader": true,
"sort-packages": true,
Expand Down
Loading
Loading