Hi @merlin1de,
the concept behind StarRate is genuinely compelling — bringing Lightroom-style rating and curation workflows into Nextcloud is a real gap in the ecosystem, and the idea of writing XMP metadata directly into JPEG files for cross-app compatibility is exactly the right approach.
Unfortunately, the current release has a critical packaging defect that makes it impossible to use for anyone installing through the App Store, so I’d strongly recommend pulling it until that’s resolved.
The problem
The make package build target explicitly excludes three interdependent files from the archive:
--exclude='vendor' \ # autoloader not included
--exclude='composer.json' \ # can't recreate it without this
--exclude='composer.lock' \ # can't recreate it without this
Without vendor/composer/autoload_psr4.php, Nextcloud has no way to map the OCA\StarRate\ namespace to the lib/ directory. The result is an immediate fatal error on every request:
OC\AppFramework\Utility\QueryNotFoundException:
Could not resolve OCA\StarRate\Controller\GalleryController!
Class "OCA\StarRate\Controller\GalleryController" does not exist
Because composer.json and composer.lock are also stripped from the archive, there is no way to repair this after installation — composer install has nothing to work with. The package is broken by construction.
The manual installation path in your README is correct and would work — git clone preserves composer.json and composer install --no-dev is explicitly called. The package target simply hasn’t been tested end-to-end.
Fix: Run composer install --no-dev --optimize-autoloader as part of the package target and keep vendor/ in the archive. Since your composer.json has no runtime dependencies at all (only "php": ">=8.1"), this only generates the autoloader files — no third-party packages are added, and the size impact is negligible.
Two minor things, (since I was in the code anyway):
-
German comments and log messages — the entire codebase comments in German, including exception messages and log output. There’s no hard rule against it, but it does make the project harder to approach for non-German speakers and somewhat unusual in the Nextcloud ecosystem where English is the de-facto standard. Worth considering for the next iteration.
-
Dead code in XmpService — three methods (writeSidecarLocal, readSidecarLocal, findMatchingLocalFiles) reference a SyncService in their docblocks that doesn’t exist in the codebase and are never called from anywhere. This looks like a planned feature that didn’t make it into the release. No harm done, but worth cleaning up to avoid confusion.
What looks good
the architecture is solid in several places:
TagService::getMetadataBatch() correctly batches all metadata into a single SQL query with an IN (...) clause instead of querying per file — exactly right for a gallery.
- per-request tag cache in
getOrCreateTag() avoids redundant DB roundtrips during batch rating.
- the use of Nextcloud’s official
ISystemTagManager/ISystemTagObjectMapper APIs, parameterized QueryBuilder queries, and correct #[NoAdminRequired] attribute usage shows familiarity with the platform. The foundation is there.
Fix the packaging, and this could be a genuinely useful app.
h.t.h.
ernolf