feat: Add @libre.graph.user.following and @libre.graph.tags properties to driveItem#37
feat: Add @libre.graph.user.following and @libre.graph.tags properties to driveItem#37
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the OpenAPI driveItem schema to expose two OpenCloud-specific, read-only fields needed to achieve parity with WebDAV REPORT search results (favorite/following and tags), enabling the web frontend to transition to Graph Search without losing these facets.
Changes:
- Add
@libre.graph.user.following(boolean, read-only) todriveItem. - Add
@libre.graph.tags(string array, read-only) todriveItem.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I find it a bit awkward, but for this particular case it also works suprisingly well ... I don't know... user as attribute name is probably rather weak semantically and we'd rather have something like owner, originator, sharedBy or something like that - so it's probably not too likely to clash with anything Up to you |
Summary
Add two read-only properties to the
driveItemschema:@libre.graph.user.following(boolean) — whether the current user is following this item@libre.graph.tags(string array) — the tags assigned to this itemMotivation
The OpenCloud web frontend currently uses WebDAV REPORT for search. The REPORT response includes
oc:favoriteandoc:tagsper result. To replace WebDAV search with the Graph Search API, thedriveItemresource must carry the same information — otherwise the Graph search is not equivalent and cannot fully replace REPORT.Both properties already have dedicated mutation endpoints:
POST .../items/{id}/follow/DELETE .../following/{id}PUT /extensions/org.libregraph/tags/DELETE /extensions/org.libregraph/tagsBut the
driveItemresource itself does not expose the resulting state. This PR closes that read gap.Changes
Two new properties on the
driveItemschema:Both are
readOnlybecause dedicated mutation endpoints already exist.Design considerations
Naming
Both properties use the
@libre.graph.*prefix as they are OpenCloud-specific extensions not present in the MS Graph API.@libre.graph.user.followingadditionally uses ausersegment to indicate it is user-specific — different users see different values for the same DriveItem. This is the first property using this prefix pattern and establishes a convention for potential future user-specific properties.@libre.graph.tagshas nousersegment because tags are global — all users see the same tags on an item.Why read-only
Both properties reflect state that is managed through dedicated endpoints:
@libre.graph.user.followingdriveItem(this PR)FollowDriveItem/UnfollowDriveItem@libre.graph.tagsdriveItem(this PR)AssignTags/UnassignTagsMaking them writable on the DriveItem would introduce a second mutation path for the same state, which complicates the API and raises questions about event semantics (should a PATCH that changes tags emit a
TagsAddedevent?). Keeping them read-only avoids this.Implementation notes
Both properties are already available in the backend — no storage or index changes needed:
Following: The favorite state is stored as a per-user xattr (
user.oc.fav.{userId}) and read viaArbitraryMetadata(keyhttp://owncloud.org/ns/favorite). TheFollowDriveItemhandler already callsStatand builds adriveItemresponse — it just doesn't populate the following field yet. Incs3ResourceToDriveItem(), the implementation needs to check the ArbitraryMetadata for the favorite key and set the property.Tags: Tags are stored in ArbitraryMetadata (key
tags, comma-separated string) and indexed in the Bleve search index as a string array. The WebDAV search response already reads and returns them. The Graph service needs to do the same incs3ResourceToDriveItem()by readingArbitraryMetadata["tags"]and splitting it into the string array.WebDAV REPORT parity
With these two properties, the gap between WebDAV REPORT and the Graph API narrows to only search-specific fields that belong on a future
searchHitresource, not ondriveItem:oc:favorite@libre.graph.user.followingoc:tags@libre.graph.tagsoc:highlightssearchHit.summaryoc:scoresearchHit.rankoc:has-previewthumbnails