Skip to content

feat(principal): map CalDAV room metadata properties - #8263

Draft
Rikdekker wants to merge 1 commit into
nextcloud:mainfrom
Rikdekker:feature/room-metadata
Draft

feat(principal): map CalDAV room metadata properties#8263
Rikdekker wants to merge 1 commit into
nextcloud:mainfrom
Rikdekker:feature/room-metadata

Conversation

@Rikdekker

Copy link
Copy Markdown

Summary

Extend the principal model in src/models/principal.js to extract room-specific properties from CalDAV principal responses. These properties are defined in the CalDAV standard and already served by Nextcloud room backends, but are not yet used by the Calendar frontend.

Mapping them into the principal model makes them available for any future UI improvement (such as the room finder in the follow-up PR) without changing how principals are fetched.

What

Adds 7 new properties to the principal object (defaults null for non-room principals):

Property DAV source Notes
roomSeatingCapacity roomSeatingCapacity Number or string
roomType roomType Trimmed
roomFeatures roomFeatures Trimmed; comma-separated list
roomBuildingAddress roomBuildingAddress Stripped of leading/trailing whitespace and commas
roomBuildingName Derived from roomBuildingAddress (first segment before comma)
roomNumber roomBuildingRoomNumber Trimmed
roomAddress Constructed from above Used for event LOCATION field

The string sanitization (leading comma strip, trim) handles edge cases like CSV-imported room data with empty building-name fields, e.g. , Science Park 140, 1098 XG, AmsterdamScience Park 140, 1098 XG, Amsterdam.

Why

This change is part of splitting #7996 into focused, reviewable PRs as suggested by @nimishavijay. The principal mapping has no UI impact and is fully backward compatible (defaults null), so it can be reviewed and merged independently of the visual room finder that depends on it.

Scope

  • ~50 lines added to src/models/principal.js
  • Backward compatible: all new properties default to null
  • No template, style, or service changes
  • No new dependencies
  • No breaking changes to existing principal consumers

Tests

  • tests/javascript/unit/models/principal.test.js — 10 tests pass, including a new test verifying that roomBuildingAddress is correctly stripped of leading commas/whitespace.

Related

Test plan

  • Existing principals (users, groups, circles, resources, regular rooms without metadata) still map correctly with null for room properties
  • A room principal with all DAV properties set produces the expected roomBuildingName, roomAddress, etc.
  • A room principal with leading comma in roomBuildingAddress is sanitized
  • npm run test:unit passes

@codecov

codecov Bot commented May 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/models/principal.js 80.95% 3 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Extend the principal model to extract room-seating-capacity,
room-type, room-features, room-building-address, and
room-building-room-number from CalDAV principal responses.

These properties are defined in the CalDAV standard and already
served by Nextcloud room backends, but not yet used by the Calendar
frontend. Mapping them into the principal model makes them available
for any future UI improvement (e.g. a browsable room finder) without
changing how principals are fetched. Backward compatible: properties
default to null when not provided by the backend.

Also derives roomBuildingName from the building address (first
segment) and constructs a roomAddress string suitable for the event
LOCATION field.

Signed-off-by: Rik Dekker <rik@rikdekker.nl>
@Rikdekker
Rikdekker force-pushed the feature/room-metadata branch from e87c932 to a66d94f Compare May 5, 2026 20:46
@SebastianKrupinski

Copy link
Copy Markdown
Contributor

Hi @Rikdekker

Thank you for the PR. I will review it as soon as I can.

@github-actions

Copy link
Copy Markdown

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

@odzhychko odzhychko self-assigned this Aug 3, 2026
@odzhychko odzhychko added 2. developing Work in progress 3. to review Waiting for reviews enhancement New feature request Feature: Scheduling Anything around scheduling meetings, free-busy, resources, attendees and so on labels Aug 3, 2026
@github-project-automation github-project-automation Bot moved this to 🏗️ In progress in 💌 📅 👥 Groupware team Aug 3, 2026
@odzhychko odzhychko removed the 2. developing Work in progress label Aug 3, 2026
@odzhychko
odzhychko marked this pull request as draft August 3, 2026 06:18
@odzhychko

Copy link
Copy Markdown
Contributor

Proposing #8693 to supersede this PR. Nothing really wrong here except some misalignment with type-safety, type-conversion and modeling.

@odzhychko

Copy link
Copy Markdown
Contributor

@Rikdekker While reviewing this I was noticing small differences between data assumed here and data I would assume coming from https://github.com/nextcloud/calendar_resource_management. I guess test data in this PR is data that could come from rooms managed in https://github.com/nextcloud/RoomVox.

If you up for it, I'd like to collect the difference with you as you seem very knowledgeable about it.

This is what I noticed so far:

RoomVox/this PR calendar_resource_management/cdav-library/OCP\Calendar\Room\IRoomMetadata Open question?
roomSeatingCapacity Usually an number. But can be a string. Usually an number. But can be a string. Do you see any use-case for this being a string that is not parsable as a positive integer?
Data import Leaves spaces from import No import yet. Just CLI Any reason handle this in the fronted and not during import or in the backend?
roomAddress value Construction logic in this PR Construction logic in https://github.com/nextcloud/cdav-library/blob/ce0c5f17fe78ff04c63231accd21b739ff17e22f/src/models/principal.js#L117 Do you see room address as something that can always be derived? I was thinking of making it a property in the caldav object in the long run to. Then each room provider can have it’s own logic (e.g. either derived or even just user inputed)
Building name Derives from roomBuildingAddress Saved in the database. But not exposed on the dav object. What do you think about introducing roomBuildingName that can be set by room providers eliminating guessing in this and other clients?

For me it to boils down too try to introduce BUILDING_NAME and maybe ADDRESS (for roomAddress) as standards in https://github.com/nextcloud/server/blob/master/lib/public/Calendar/Room/IRoomMetadata.php ?

@Rikdekker

Copy link
Copy Markdown
Author

Thanks for picking this up @odzhychko — happy to have #8693 supersede this one; the stricter typing and validating as early as possible are clear improvements. Answers to your table:

roomSeatingCapacity as a non-parsable string — no use case that I know of. OCP\Calendar\IMetadataProvider::getMetadataForKey() is typed ?string, so every backend ships capacity over DAV as a string regardless of what it stores internally (RoomVox keeps ?int and casts). Parsing to a positive integer and discarding the rest is exactly right. Side note: that also makes the typeof dav.roomSeatingCapacity === 'number' branch dead code for real DAV data — harmless, but worth knowing.

Import whitespace / leading commas — you're right that it doesn't belong in the frontend. It came from a real dataset: an MS365 room export with empty Building and Floor columns, which produced values like , Science Park 140, 1098 XG, Amsterdam. I've since fixed that at the source, so no objection at all to dropping the sanitizing from the model — normalizing during import/in the backend is the right place.

roomAddress — agreed it shouldn't be derived in the calendar frontend. Two observations on taking it from cdav-library though:

  1. The getter joins [roomBuildingRoomNumber, roomBuildingStory, roomBuildingAddress] and returns '' — never null/undefined — when nothing is set. So in practice RoomPrincipal.roomAddress will be an empty string rather than null for rooms without metadata. Might be worth normalizing empty to null in the mapper; the unit test doesn't catch it because it mocks a plain object instead of a cdav Principal.
  2. "2.17, 2, Poppodium, Kerkstraat 10" isn't really what you want in an event LOCATION field, which is why I built a separate construction. A provider-supplied address would solve exactly that, so +1 on making it a real property with the derived value as fallback.

Building name — fully agree it's a heuristic. RoomVox writes the building name as the first segment of room-building-address by convention precisely because there is nowhere else to put it. A standardized BUILDING_NAME in IRoomMetadata (and exposed in cdav-library) would let clients group rooms by building without guessing, which is the single thing the room finder UI needs most. Happy to open the server + cdav-library PRs for BUILDING_NAME (and ADDRESS) if you'd like — just say the word.

One mismatch I ran into while checking this: IRoomMetadata::BUILDING_STORY is room-building-story and cdav-library only requests that key, while RoomVox was emitting room-building-floor. That's my bug and I'll fix it on our side — mentioning it because it explains why a floor filter stayed empty in my follow-up UI branch, and because roomBuildingStory in your PR is what makes that filter possible at all.

I'll rebase the room finder UI on top of #8693 (roomNumberroomBuildingRoomNumber, features as string[], capacity as number, building-name grouping moved into the component) and close this PR once #8693 lands.

🤖 AI (if applicable)

  • The content of this comment was partly or fully generated using AI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews enhancement New feature request Feature: Scheduling Anything around scheduling meetings, free-busy, resources, attendees and so on feedback-requested

Projects

Status: 🏗️ In progress

Development

Successfully merging this pull request may close these issues.

3 participants