The Deck PUT API is a full replacement, not a partial update.
Previously, title and description were conditionally sent, causing:
- 400 errors when title not provided (it's required)
- Description being cleared when not explicitly set
Now all required fields (title, type, owner) and description are
always included in the payload using current card values when not
explicitly provided. This matches the existing pattern for type/owner.
Also simplified owner extraction since DeckCard.validate_owner
already ensures it's always a string.
Fixes#452🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Refactor tests to assert what SHOULD happen (partial updates preserve
unchanged fields) rather than documenting current buggy behavior.
Tests will fail until fix is implemented in client or upstream.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests document current behavior of update_card method:
- Updating without title fails (400) - title required but conditionally sent
- Updating with title clears description - PUT is full replacement
Related: #452🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Two issues prevented CSS from loading correctly:
1. Entry point naming mismatch: Vite output `main.css` but Nextcloud's
`Util::addStyle('astrolabe', 'astrolabe-main')` expected `astrolabe-main.css`
2. CSS code splitting: Vite extracted @nextcloud/vue component styles
into separate chunks (e.g., NcUserBubble-*.css) that Nextcloud doesn't
load automatically. Without these styles, the UI rendered incorrectly.
Changes:
- Rename entry point from `main` to `astrolabe-main`
- Add `cssCodeSplit: false` to bundle all CSS into the entry point
- Update assetFileNames to output consistent `astrolabe-main.css`
This increases CSS bundle from 11KB to 286KB but ensures all component
styles are available when the page loads.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The "Revoke Access" button in Astrolabe personal settings was failing
with "Unable to connect to server" error in multi-user basic auth mode.
Root cause: The JavaScript sends a POST request but the route was
configured to accept DELETE. Changed the route to:
- Use POST method (matching the JavaScript fetch call)
- Use /api/v1/background-sync/credentials/revoke path (avoiding
conflict with storeAppPassword which uses POST on the base URL)
Added integration test that verifies the complete revoke flow:
enable background sync → click revoke → verify credentials deleted.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The /oauth/login route was returning 404 in multi-user BasicAuth mode with
offline access enabled. This was because browser OAuth routes were gated
by `oauth_enabled` (only True for MCP OAuth modes), not by
`oauth_provisioning_available` which correctly includes hybrid mode.
The Management API (admin UI, webhook management) requires OAuth
authentication regardless of how MCP tools authenticate. These are
independent security concerns:
- MCP Tools: BasicAuth (waiting for upstream Nextcloud OAuth patches)
- Management API: OAuth (for admin UI, webhook management, vector sync)
Changes:
- Gate browser OAuth routes by oauth_provisioning_available instead of
oauth_enabled
- Add follow_redirects=True to OIDC discovery HTTP clients
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>