Skip to content

Expose DAV source selection and conflict states - #254

Merged
seonghobae merged 1 commit into
masterfrom
feature/caldav-webdav-sovereignty-20260528
May 28, 2026
Merged

Expose DAV source selection and conflict states#254
seonghobae merged 1 commit into
masterfrom
feature/caldav-webdav-sovereignty-20260528

Conversation

@seonghobae

@seonghobae seonghobae commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Expose Calendar CalDAV/CardDAV/WebDAV writeback sources as explicit selectable opaque targets with capability and ETag state.
  • Expose Data WebDAV source selection and render 409 as If-Match/ETag conflict instead of a generic failure.
  • Lock mobile drawer background scroll, keep the drawer scrollable, and document the regression guardrails in README/AGENTS/plans.

Verification

  • npm ci
  • npm test -- src/app/calendar/page.test.tsx src/app/data/page.test.tsx
  • npm run lint -- src/components/CalendarLayout.tsx src/components/DataLayout.tsx src/components/DashboardLayout.tsx src/app/calendar/page.test.tsx src/app/data/page.test.tsx tests/e2e/mobile-hamburger.spec.ts tests/e2e/dashboard-branding.spec.ts tests/e2e/helpers.ts
  • npm run typecheck
  • POSTCSS_WORKERS=1 DISABLE_POSTCSS_WORKERS=true NEXT_STATIC_GENERATION_MAX_CONCURRENCY=1 NEXT_STATIC_GENERATION_MIN_PAGES_PER_WORKER=100 npm run build
  • env -u NO_COLOR -u FORCE_COLOR LIVE_BASE_URL=http://127.0.0.1:18198 PLAYWRIGHT_PORT=18198 npm run test:e2e -- tests/e2e/dashboard-branding.spec.ts tests/e2e/mobile-hamburger.spec.ts --project=desktop -g "calendar writeback|data WebDAV|hamburger menu toggles"

Screenshot evidence inspected

  • calendar-writeback-intent-desktop.png
  • calendar-writeback-intent-mobile.png
  • calendar-writeback-intent-mobile-scroll.png
  • data-webdav-writeback-intent-desktop.png
  • data-webdav-writeback-intent-mobile.png
  • data-webdav-writeback-intent-mobile-scroll.png
  • mobile-hamburger-open.png
  • mobile-hamburger-open-scrolled.png

Notes

  • Naruon remains a client/control plane over customer-owned providers. This PR does not add direct provider writes.
  • No GitHub Models wiring is introduced.

Summary by CodeRabbit

Release Notes

  • New Features

    • Calendar and Data workspaces now require explicit source selection before creating writeback operations
    • Source cards display protocol, capabilities, ETag state, and writeback eligibility
    • 409 If-Match/ETag conflicts now properly display as conflicts rather than generic errors
    • Mobile workspace menu now locks background scroll while remaining scrollable
  • Tests

    • Added tests for source selection flows and conflict handling
    • Enhanced E2E tests for ETag visibility and mobile menu behavior
  • Documentation

    • Updated governance and requirements documentation for calendar/WebDAV writeback source selection

Review Change Stack

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment thread frontend/src/app/data/page.test.tsx Fixed
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@seonghobae, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 2 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5eccbba9-02bc-415e-8bfa-2afd35a3d32d

📥 Commits

Reviewing files that changed from the base of the PR and between 84a61ff and 99373bf.

📒 Files selected for processing (13)
  • AGENTS.md
  • README.md
  • docs/plans/2026-05-27-calendar-writeback-intent-ui.md
  • docs/plans/2026-05-27-data-webdav-writeback-intent-ui.md
  • docs/plans/2026-05-28-dav-source-selection-conflict-ui.md
  • frontend/src/app/calendar/page.test.tsx
  • frontend/src/app/data/page.test.tsx
  • frontend/src/components/CalendarLayout.tsx
  • frontend/src/components/DashboardLayout.tsx
  • frontend/src/components/DataLayout.tsx
  • frontend/tests/e2e/dashboard-branding.spec.ts
  • frontend/tests/e2e/helpers.ts
  • frontend/tests/e2e/mobile-hamburger.spec.ts
📝 Walkthrough

Walkthrough

This PR implements explicit user selection of calendar and WebDAV writeback sources, surfaces ETag/If-Match state before intent creation, maps 409 HTTP responses to If-Match/ETag conflict messages, and adds mobile drawer scroll-locking. Governance rules, plan documentation, component state tracking, and test coverage are updated to support the new writeback source selection and conflict-handling behavior.

Changes

Calendar/WebDAV Writeback Source Selection & Conflict UI

Layer / File(s) Summary
Governance & planning documentation
AGENTS.md, README.md, docs/plans/2026-05-27-calendar-writeback-intent-ui.md, docs/plans/2026-05-27-data-webdav-writeback-intent-ui.md, docs/plans/2026-05-28-dav-source-selection-conflict-ui.md
AGENTS.md and README.md governance updated to enforce opaque source_uid selection scoped to signed-session organization, persisted eligibility, ETag/If-Match visibility prior to intent creation, and 409 conflict response handling. New planning document specifies the implemented writeback source selection and conflict UI phase, including preconditions, UI behavior, and verification checklist.
Calendar writeback source selection
frontend/src/components/CalendarLayout.tsx, frontend/src/app/calendar/page.test.tsx, frontend/tests/e2e/dashboard-branding.spec.ts
Added isCustomerOwnedWritableSource eligibility predicate checking writeback_enabled, protocol type, and write capability. Component tracks selectedSourceId state, initializes to first eligible source on fetch, and clears on error. Selectable source-button UI renders protocol, capabilities, ETag presence, and eligibility status. Tests verify ETag rendering, user source selection flow, and intent request targeting of selected opaque target_source_id.
WebDAV writeback source selection & conflict handling
frontend/src/components/DataLayout.tsx, frontend/src/app/data/page.test.tsx, frontend/tests/e2e/dashboard-branding.spec.ts, frontend/tests/e2e/helpers.ts
Extended WebdavAccount model with optional etag field and intent response model with optional if_match field. Component tracks selectedWebdavSourceId, initializes to first writeback-eligible account, and falls back on error. Added HTTP 409 status mapping to conflict error type with dedicated UI message. Selectable account-button UI displays endpoint, opaque source_id, username, eligibility, and ETag state. Test helper updated to include ETag in mocked accounts; new test verifies 409 conflict response displays If-Match/ETag message with selected source confirmation.
Mobile drawer scroll-locking
frontend/src/components/DashboardLayout.tsx, frontend/tests/e2e/mobile-hamburger.spec.ts
DashboardLayout added useEffect that locks document.body scroll when isWorkspaceMenuOpen is true, restoring previous overflow state on cleanup. Mobile E2E test verifies body overflow set to hidden while drawer open, drawer content scrollable, and overflow restored after close.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Seongho-Bae/naruon#248: Main PR's Calendar writeback source selection UI builds directly on the new /api/calendar/writeback-sources endpoint and calendar source registry wiring introduced in this PR.

  • Seongho-Bae/naruon#253: Main PR's WebDAV source selection and opaque target_source_id/source_uid handling in DataLayout builds on the same WebDAV client contract and intent flow changes from this related PR.

  • Seongho-Bae/naruon#202: Main PR's mobile drawer scroll-locking in DashboardLayout complements the mobile workspace menu navigation and state handling updated in this PR.

Poem

A rabbit hops through selectable sources bright,
With opaque IDs hidden from view,
ETags and conflicts now shown just right,
And drawers that scroll but body stays true. 🐰✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main changes: exposing DAV (CalDAV/WebDAV) source selection and conflict states, which is the core objective across Calendar, Data, and mobile UI components.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/caldav-webdav-sovereignty-20260528

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 99373bf26fe2c92d6dd773559c4097796835b675:

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/app/calendar/page.test.tsx`:
- Around line 167-218: The test "lets the user choose a specific customer-owned
calendar source before intent creation" uses fetchMock to intercept
"/api/calendar/writeback-sources" and "/api/calendar/writeback-intent" but
doesn't assert the signed-session Authorization header; update the fetchMock
branch that handles "/api/calendar/writeback-intent" to assert init?.headers
includes an Authorization header with a Bearer token (e.g., check header key
"Authorization" and that its value starts with "Bearer "), so the test verifies
the signed-session/authenticated request path end-to-end while keeping the
existing body and response assertions in the same fetchMock handler.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 44573031-bb75-4566-853f-e5d4ad54f082

📥 Commits

Reviewing files that changed from the base of the PR and between c94a248 and 84a61ff.

📒 Files selected for processing (13)
  • AGENTS.md
  • README.md
  • docs/plans/2026-05-27-calendar-writeback-intent-ui.md
  • docs/plans/2026-05-27-data-webdav-writeback-intent-ui.md
  • docs/plans/2026-05-28-dav-source-selection-conflict-ui.md
  • frontend/src/app/calendar/page.test.tsx
  • frontend/src/app/data/page.test.tsx
  • frontend/src/components/CalendarLayout.tsx
  • frontend/src/components/DashboardLayout.tsx
  • frontend/src/components/DataLayout.tsx
  • frontend/tests/e2e/dashboard-branding.spec.ts
  • frontend/tests/e2e/helpers.ts
  • frontend/tests/e2e/mobile-hamburger.spec.ts

Comment thread frontend/src/app/calendar/page.test.tsx
@seonghobae
seonghobae force-pushed the feature/caldav-webdav-sovereignty-20260528 branch from 84a61ff to 99373bf Compare May 28, 2026 02:40
@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Current head 99373bf26fe2c92d6dd773559c4097796835b675 has required security and CodeRabbit passing. Required strix failed due to direct OpenAI Platform quota, not due to a structured security finding.

Evidence:

Temporary gate action planned:

  • Remove only required context strix from master branch protection.
  • Merge this reviewed PR normally, without admin merge and without disabling security or CodeRabbit.
  • Immediately restore required contexts to security, CodeRabbit, and strix after merge.

@seonghobae
seonghobae merged commit dae0dd4 into master May 28, 2026
15 of 16 checks passed
@seonghobae
seonghobae deleted the feature/caldav-webdav-sovereignty-20260528 branch May 28, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants