Open
Conversation
…rience Eliminates ~500ms overhead from every API request by moving background job registration from boot() (runs every request) to info.xml (runs once at install). Also optimizes OrganisationService with in-memory caching and FileChangeListener with early path checks to reduce first-user login from 7.8s to 4.1s. - Remove 8 redundant $jobList->has() DB queries from boot() - Move 4 background jobs to declarative info.xml registration - Add request-level in-memory cache to getUserOrganisations() - Pass pre-loaded organisations to getActiveOrganisation() to avoid double lookup - Only run admin/RBAC checks on org creation, not every lookup - Cache extraction scope in FileChangeListener (1 DB read vs 128 per skeleton) - Check file path before settings DB read for early skip Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Files uploaded by admin or non-admin users were stored under that user's Nextcloud folder, but public/anonymous access (via @publicpage endpoint) could not resolve the file because IRootFolder::getById() requires a user context. Added getFileViaKnownUsers() fallback in FilesController::show() that tries the object owner, then the OpenRegister system user, then admin to find the file by ID. Also improved FolderManagementHandler::getNodeById() to fall back to root folder lookup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove all catch-and-fallback-to-blob patterns that silently return empty results from the unused openregister_objects table when MagicMapper/UnifiedObjectMapper operations fail. Operations now propagate errors instead of hiding them. Changed: find(), tryMagicMapperFindAll(), insert(), update(), deleteObjects(), publishObjects(), depublishObjects(), shouldUseMagicMapper(), shouldUseMagicMapperForRegisterSchema() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Register lookups for file/folder operations should not apply multitenancy filtering, as registers are shared infrastructure that all users need to access. This fixes non-admin users being unable to upload files to objects because the register lookup was blocked by org-based filtering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rjzondervan
approved these changes
Feb 22, 2026
When creating organisations, a unique constraint violation on the slug column would crash the entire request. Now the service catches the DbalException and returns the existing organisation instead. Also adds findBySlug() to OrganisationMapper and downgrades the noisy FilePropertyHandler isFileProperty log from warning to debug. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When createOrganisation encounters a slug collision and finds an existing entity by slug, update its UUID to match the requested UUID if they differ. This ensures the entity UUID stays in sync with the object UUID, preventing broken references in downstream code that relies on UUID-based lookups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Set SITE_TITLE=Softwarecatalogus on nginx frontend service - Add 'extend' to reserved property list in MagicSearchHandler to prevent it from being treated as a search filter Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… results When findByRelationBatchInSchema() returned 0 results (e.g., empty magic table or no matching objects), the cache was not populated due to a `if (count > 0)` guard. This caused every entity to fall through to the slow per-entity findByRelation() path, which does LIKE scans on the blob table and iterates all magic mapper tables. On the test environment with 3,093 organisations and an empty contactpersoon magic table, this caused _extend[]=contactpersonen to take 10-13 seconds instead of <1 second. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OAS documentation generation was failing with 500 for org-bound registers because RegisterMapper::find() applied multitenancy filtering. Registers with an organisation UUID were inaccessible to users outside that org, including for public API documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…roperties Linked diensten and koppelingen were not shown on applicatie pages because resolveSchemaReference() and getSchema() applied multi-tenancy filtering when looking up schemas internally. This caused $ref references like "#/components/schemas/dienst" to fail resolution when the schema belonged to a different organization than the current user, breaking both: - The single-object API (_extend=diensten on show endpoint) - The list API (batch preloadInverseRelationships path) The fix bypasses RBAC and multi-tenancy for internal schema resolution since schemas must always be accessible when resolving inversedBy references regardless of the requesting user's organization. Resolves: VNG-Realisatie/Softwarecatalogus#373 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The OAS specification endpoint was only returning 1 of 6 schemas because findMultiple() applied multi-tenancy filtering by default. Schemas belonging to organizations other than the current user's were excluded. OAS generation is a system-level operation that needs access to all schemas in a register, regardless of organization ownership. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The export endpoint returned 500 because registerMapper.find() applied multi-tenancy filtering by default. Registers with an organisation set (like voorzieningen) were excluded when the current user's org didn't match. The lookup is only needed for filename generation — access control is already handled by setRegister/setSchema above. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Apache-2.0 LICENSE with EUPL-1.2. Update appinfo/info.xml, composer.json, and package.json license fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ObjectsController: Accept both 'format' and 'type' query parameters for export, so CSV downloads work from all endpoints consistently. - UserService: Wrap getUserOrganisationStats() in try-catch to prevent 500 errors on /api/user/me when organisation data is unavailable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add schema title to the delete dialog heading and body text so users can see what type of object (applicatie, dienst, etc.) they are about to delete, instead of a generic confirmation message. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add PR checks for PHP quality (PHPCS, PHPMD, phpmetrics) and frontend quality (ESLint, stylelint) that run on pull requests to main branches. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add OpenSpec config, change tracking for deep link registry and global search features, and shared Nextcloud app specifications. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add DeepLinkRegistryService for cross-app entity linking, notes and tasks controllers/services with DTOs, comments entity listener, object cleanup listener, and fix global unified search across registers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Nextcloud App Store schema does not accept EUPL-1.2 as a valid licence value, causing all release uploads to fail with HTTP 400. Revert to 'agpl' which is in the accepted set. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The unstable release workflow now derives the version from the branch's own info.xml instead of from main, making version bumps self-contained. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…logging OrganisationMapper now catches duplicate slug constraint violations and updates the existing organisation instead of throwing. Also removed 5 verbose INFO-level log statements that dumped full entity state on every save. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rning - n8n_workflows config: use raw.githubusercontent.com instead of github.com/blob/ URL which returns HTML instead of JSON - MagicMapper: remove owner from critical null-field warning since owner can legitimately be null for public/unauthenticated objects Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a background text extraction job runs for an object that was deleted between queueing and execution, this is expected behavior and should not produce a warning in the log. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nextcloud's ControllerMethodReflector parses annotations matching @[A-Z]\w+ and tries to split parenthesized values by '='. The @SuppressWarnings(PHPMD.xxx) annotations don't contain '=' causing PHP warning "Undefined array key 1" on every controller request. Lowercasing to @SuppressWarnings makes the reflector skip them while PHPMD still reads them correctly (case-insensitive). Fixes ~12,000+ PHP warnings in the Nextcloud log. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
findExtendedBy() was re-fetching each schema via find() just to get its uuid and slug, triggering 3 extra queries per schema (schema SELECT + org preferences + org hierarchy CTE). With 67 schemas this caused ~201 redundant queries per request. Now accepts optional knownUuid/knownSlug parameters so the controller can pass already-loaded values, reducing total queries from ~269 to ~68. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Batch operations and request-scoped caching to eliminate N+1 query patterns. Query warnings dropped from 29 to 10 (65% reduction), QueryBuilder warnings from 46 to 21 (54% reduction). Changes: - Add batch findAllExtendedBy(), getStatisticsGroupedBySchema() methods - Batch file tag loading in RenderObject (2 queries instead of 2*N) - Pre-load schemas in bulk for CacheHandler name resolution - Pre-seed export name map from already-loaded objects - Cache organisation stats across duplicate buildUserDataArray() calls - Add request-scoped find() cache to SchemaMapper and RegisterMapper - Fix processFilePropertiesWithRollback log level (error -> debug) Resolved endpoints (0 warnings): create, export, index, schemas, publications Reduced: updateMe 135->124, patch data-dependent Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PHP converts ?_facets[]=foo&_facets[]=bar into a numerically-indexed array; expand these by joining with comma before passing to expandFacetConfig / expandFacetConfigFromAllSchemas. Also adds CacheWarmupJob background job and app store images/screenshots. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rash on UUID change When a slug collision occurs during organisation creation, the save() path sets a new UUID on the entity before calling update(). The previous update() called findByUuid(entity->getUuid()) to retrieve the old state for event dispatch — but the new UUID doesn't exist yet, causing a DoesNotExistException and a 500 error from OrganisationController. Fix: Find the old entity by database integer ID using a QueryBuilder query. This is stable across UUID changes. Falls back to entity itself as old state if the ID lookup fails. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ias error
Nextcloud's QueryBuilder registers the table with the prefix as alias
(e.g. *PREFIX*storages) on PostgreSQL, so ->join('storages', ...) fails
with "alias not part of FROM clause". Fix by using an explicit 's' alias
in both ->from() and ->join().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename website/ → docusaurus/ (preserves git history) - Move website/docs/ → docs/ at repository root - Existing dev-notes from root docs/ merged into docs/development-notes/ - Update docusaurus.config.js: path '../docs', editUrl → docusaurus/ - Update documentation.yml: trigger development branch, cd docusaurus - Update CONTRIBUTING.md copy destination to docs/development/ - Update logo.svg with blue hexagon app-store icon - Create img/app-store.svg with blue hexagon connection icon 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>
Real bugs fixed: - BulkController: add missing registerId arg to deleteObjectsBySchema() - TablesController: replace non-existent findBySlug() with find() - MagicMapper: fix @return void docblock to @return array on updateTableStructure() - ImportHandler: declare missing static property $isDependencyCheckActive - DeepLinkRegistration: strtr() positional args (replacePairs is not a valid param name) - FilePropertyHandler: rename duplicate 'file' array key to 'filename' - ValidationHandler: change $saveCallback type from callable to array - EntityRecognitionHandler: add is_string() guards before json_decode() calls - TaskService: change return types of createTask/updateTask to ?array (nullable) - UnifiedObjectMapper: rename $_rbac/$_multitenancy params to $rbac/$multitenancy to match parent Psalm config: - Add suppressions for OC\Files\AppData\Factory, Doctrine\DBAL, OCA\DAV, Sabre, OC\DB - Add InvalidThrow and UnsupportedPropertyReferenceUsage suppressors 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.
Nieuwe Organisatie aanmaken en accepteren zet niet een gebruiker direct om.
De organisatie die aangemaakt word in openregister heeft niet het zelfd uuid als die in het voorzieningen register
Calls na eerste inlog zijn heel traag
Mijn account update contactpersoon niet. Contactpersoon update wel mijn account
Niet ingelogd geeft 404 bij het ophalen van logo's