fix: Fix Psalm errors and configure static analysis#188
Open
rubenvdlinde wants to merge 55 commits intomainfrom
Open
fix: Fix Psalm errors and configure static analysis#188rubenvdlinde wants to merge 55 commits intomainfrom
rubenvdlinde wants to merge 55 commits intomainfrom
Conversation
Updated description
Fix unstable release
Updated visibility of properties
- Add koppelingType field that auto-computes to "extern" when buitengemeentelijkVoorziening is filled, "intern" otherwise - Update naam default template with moduleB|buitengemeentelijkVoorziening fallback so external koppelingen show the BGV name - Update objectNameField in configuration to match Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ianceService The UUID was being looked up from the object data array ($moduleData['uuid']) which doesn't contain the UUID field. Changed to use $moduleObject->getUuid() which correctly reads it from the entity metadata. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rname backfill The listener searched contactpersonen by username field only, which was null for existing/imported data. Added case-insensitive email fallback using _search (ILIKE), username backfill on first match, and direct mapper save to bypass schema validation of legacy data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move background job registration from boot() (runs every request) to info.xml (runs once at install). Fixes wrong class reference in info.xml. - Remove $jobList->has() DB query from boot() - Fix info.xml: Cron\OrganizationSync → BackgroundJob\OrganizationContactSyncJob Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ter) After creating a user account, fork a background process that replicates Nextcloud's first-login filesystem setup (setupFS, copySkeleton, updateLastLoginTimestamp). This shifts the ~4s cost from the user's first login to an async fire-and-forget process, so both the admin response and the user's first login are fast. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- performOrganizationsSync: query per-schema magic table instead of empty openregister_objects blob table, with LEFT JOIN to find only orgs missing entities. Batch-processes with email suppression. - performContactSync: query magic table with INNER JOIN on accounts_data - performUserSync: query magic table with org entity join - Add backup entity creation in createOrUpdateContactPersonObject and processSpecificContactPerson when org entity missing - Wrap saveObject in try/catch so event listener failures don't block user creation tracking (addUserToOrganizationEntity, stats) - Fix ObjectEntity array access in SettingsService syncOrganisations - Clean up debug log levels (remove emoji critical logs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ContactpersoonService: add backup org entity creation when entity is missing during processContactpersoon() (same pattern as OrganizationSyncService backup). Catches DoesNotExistException and creates entity from org object if org is active. - OrganizationSyncService: add ensureOrganisationEntityPublic() wrapper for cross-service access to the private ensureOrganisationEntity() - OrganisatieService: cast naam/type to string to prevent TypeError when org name is numeric (e.g. "2150" stored as int) - SettingsService: handle ObjectEntity in search results (getUuid() instead of array access) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
saveObject() to update contact username triggers ObjectUpdatedEvent, which re-enters processContactpersoon() via handleContactpersoonUpdate, causing an infinite loop. Add static recursion guard that tracks contact UUIDs currently being processed — re-entry returns immediately. Cleared in finally block to ensure guard is always released. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add UUID and slug pre-checks in ensureOrganizationEntity() before attempting to create a new organisation entity. This prevents the SQLSTATE[23505] unique constraint violations on the slug column that were crashing production. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multiple bugs caused contact persons to lose their organisatie field (the link back to their organisation) when an organisation was activated: 1. The organisatie field was permanently destroyed by unset() calls before saveObject(). Now saved before unset and restored after save at all 4 locations. 2. processRelatedContactPersons could not find contacts linked via inversedBy (org→contact) because it only searched by the contact's organisatie field (which was null). Added fallback that looks up contacts from the org's contactpersonen UUID array. 3. Related contacts now get their organisatie field set before being passed to processSpecificContactPerson, ensuring user creation proceeds correctly. 4. updateContactpersoonObjectOwner now restores a missing organisatie field as a safety net. 5. Downgraded debug-only critical log levels to info. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Leverancier organisations registered by gemeenten are no longer publicly visible. Public users now only see organisations that are: registered by a Leverancier, of type Gemeente, or of type Samenwerking. Aanbod-beheerders only see their own organisation. Gebruik-beheerders retain full access. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dienst schema had two properties with title "Diensttype": `type` and `dienstType`, both with table.default=true, causing a duplicate column in the diensten table. Removed `dienstType` and made `type` the facetable field with aggregated=false to prevent cross-schema facet mixing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces empty placeholder content blocks (ph1, ph2) with actual seed data for the quote section and 3 content blocks on the front page. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ModuleVersionService was never registered as a service, causing ModuleComplianceSubscriber to silently fail when trying to create default 1.0.0 versions for new modules. The service was properly implemented but the container registration was missing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace existing license (Apache-2.0/AGPL) with EUPL-1.2 across all metadata files: LICENSE, appinfo/info.xml, composer.json, package.json. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…5, #373, #377, #394) Remove empty rollen enum array and add Gebruik-raadpleger to items enum. Add table.default=true to diensten and standaardVersies schemas for beheer table visibility. Add authorization.read=['authenticated'] to contactpersonen, e-mailadres, and telefoonnummer properties. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… #434, #352) Replace saveObject with ObjectEntityMapper.update() in registration flow to avoid validation cascades. Add email subaddress sanitization for username generation. Make ObjectModal support 12 object types via generic config. Add metadata hydration after user profile sync. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…schema moduleB now only references modules (removed oneOf with element). buitengemeentelijkVoorziening is now visible and shown in default table view. The UI keeps a single merged dropdown that maps to the correct field based on type. Resolves ambiguity from #433 where moduleB accepted both modules and elements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.1.139 already exists as a stable release in the Nextcloud appstore, causing the nightly upload to fail with HTTP 400. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Nextcloud appstore only accepts a fixed set of licence identifiers (agpl, AGPL-3.0-or-later, MIT, Apache-2.0, etc). EUPL-1.2 is not in the accepted list, causing all appstore uploads to fail with HTTP 400 since Feb 26. The actual LICENSE file remains EUPL-1.2 — this only changes the appstore metadata identifier. EUPL 1.2 has an explicit compatibility clause with AGPL-3.0. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OrganizationSyncService: add null-coalescing fallbacks for missing usersCreated/usersUpdated keys in sync result arrays. OrganisatieService: reduce catch block logging to only error message and UUID instead of full object dump with stack trace. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All sourceUrl and configuration references in the register JSON were using github.com/blob/ URLs which return HTML pages, not raw JSON. Converted to raw.githubusercontent.com for proper JSON fetching by the ConfigurationCheckJob cronjob. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The sync cronjob no longer needs user/org context since all ObjectService calls now explicitly pass _rbac: false and _multitenancy: false. This is correct because sync is a system-level operation. Changes: - OrganizationContactSyncJob: removed CronjobContextTrait usage and context warnings, simplified to direct service call - OrganizationSyncService: added _rbac: false, _multitenancy: false to 4 ObjectService calls that were using defaults - CronjobContextTrait: marked as @deprecated - SettingsService: marked 6 cronjob config methods as @deprecated - SettingsController: marked 4 cronjob config endpoints as @deprecated Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add vimeo/psalm ^5.26, phpstan/phpstan ^1.10 - Add nextcloud/coding-standard, phpcsstandards/phpcsextra, nextcloud/ocp - Create phpstan.neon config - Add phpcs-custom-sniffs/ (named parameters enforcement) - Rewrite phpcs.xml to target lib/ + add custom sniff reference - Add phpmetrics:violations, phpcs:output, phpstan scripts - Fix psalm script to use ./vendor/bin/psalm - Add code-quality.yml GitHub Actions workflow (blocks PRs on phpcs+phpmd) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rvice backup Refactor all function calls to use named arguments across controllers, services, event listeners, background jobs, and settings to comply with the Conduction PHPCS coding standard. Removes the leftover ArchiMateService_backup.php file. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The NC organisation UUID from objectData['organisation'] (RBAC system field) is different from the register organisatie object UUID. When an NC org hasn't been synced to a register object yet, the lookup fails with "Object not found". This is expected behaviour, not an error — the caller already handles the empty string return value gracefully. Downgrade from error to warning and simplify the log context. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixed PHPCS violations in 32 lib/ files (all at 0 errors). Changes include: - Added declare(strict_types=1) to all files missing it - Fixed property and method doc blocks (short descriptions, @param/@return order) - Replaced operator ! with === false/true explicit comparisons - Replaced implicit true comparisons with === true - Added named parameters to function calls - Expanded inline ternary IFs to if/else blocks - Fixed inline comments to end with periods - Added end-of-block comments (//end method()) - Fixed file doc comment formatting Large service classes intentionally skipped (too many violations for this pass): ArchiMateService (517), ArchiMateExportService (183), ArchiMateImportService (1174), SettingsService (527), SoftwareCatalogueService (319), OrganizationSyncService (291), ContactPersonHandler (252). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a complete Docusaurus 3.7 setup matching the pipelinq pattern: - docusaurus/ with config, custom.css (OWC green theme), homepage - docs/FEATURES.md with feature overview - .github/workflows/documentation.yml deploying to softwarecatalog.app on push to development - Blue hexagon app-store.svg as navbar logo Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Named parameter 'appName:' breaks on Nextcloud versions where the concrete URLGenerator still uses '$app' as the parameter name. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add tests/bootstrap-unit.php with OCP class autoloader (no Nextcloud bootstrap) - Update .github/workflows/code-quality.yml to run PHPUnit unit tests on every PR (uses --bootstrap tests/bootstrap-unit.php to skip Integration test setup) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Psalm (Static Analysis) step to code-quality.yml php-quality job Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Applicatie versie to applicatieversie
- Fix 4 InvalidNamedArgument bugs (wrong param names in method calls): - AangebodenGebruikService: query → baseQuery in addQueryFilters() - OrganisatieService: userData → user, organisationData → organization - HierarchyHandler: manager → managerUsername in setUserManager() - OrganisatieService: createOrganisation → name in createOrganisation() - Fix UndefinedThisPropertyFetch: replace non-existent $this->_userManager with $this->_container->get(IUserManager::class) in SoftwareCatalogueService - Fix named args in Application.php DI container registrations - Fix named args in SoftwareCatalogEventListener and ContactpersoonService - Update psalm.xml: add suppressions for all OCA\OpenRegister\* and missing OCP\* runtime classes (ICache, IGroup, ISession, IWidget, IRepairStep, etc.) - Remove phpro/grumphp from require-dev (conflicts with vimeo/psalm via amphp/amp dependency chain); update composer.lock accordingly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed InvalidArgument, InvalidReturnType, InvalidReturnStatement, InvalidCast, InvalidMethodCall suppressors from psalm.xml — exposing 5 real bugs that were previously hidden: - ArchiMateExportService::createSectionFolder(): return type was SimpleXMLElement but function can return null; fixed to ?SimpleXMLElement - ArchiMateExportService::extractModelMetadata(): return can be ArrayAccess; cast to (array) to satisfy array return type - ContactPersonHandler::assignUserGroups(): docblock said @return void but function signature and body return string; fixed docblock Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tested all remaining suppressors — removed those with 0 false positives: - ImplementedReturnTypeMismatch (0 errors without it) - NullableReturnStatement (0 errors without it) Confirmed as legitimate suppressors (tested, all false positives): - TypeDoesNotContainNull/Type, RedundantCondition: constant feature-flag patterns - InvalidArrayOffset/Access, EmptyArrayAccess: Psalm inference cascade from OCA\OpenRegister unknowns - UnusedVariable, NoValue: SimpleXMLElement::addChild() side-effect patterns Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
InvalidNamedArgumentbugs where method call sites used wrong parameter namesUndefinedThisPropertyFetch(non-existent$this->_userManagerproperty)psalm.xmlwith suppressions for allOCA\OpenRegister\*runtime classes and missingOCP\*stubs (ICache, IGroup, ISession, IWidget, IRepairStep, DoesNotExistException, IAccountManager)phpro/grumphpfrom require-dev (conflicts withvimeo/psalmviaamphp/amp); updatecomposer.lockTest plan
🤖 Generated with Claude Code