feat(navigation): clicking an enclave opens last/default room + settings gear (LC-143) #166

Merged
nrupard merged 2 commits from feat/lc-143-enclave-last-room into main 2026-05-20 20:30:53 +02:00
Owner

Summary

Clicking an enclave opens the room you last had open there (or the default room), instead of an enclave home page. Enclave settings move to a gear button (LC-143).

Changes

  • Redirect: GET /enclave/{id} now redirects to the last-opened room in that enclave, validated against the current accessible set; falls back to the default (first, name-ordered) room. The landing page renders only when the enclave has no accessible rooms (empty/onboarding state).
  • Persistence (migration 0040, enclave_last_room): one row per (user, enclave), upserted on room open in get_room. Survives restart. Stale rows (deleted room / lost access) fall back to the default.
  • Settings gear: the enclave switcher rail (top-left) shows a gear on the active enclave's tile -> /enclave/{id}/settings. Gated by SwitcherEntry.can_manage (owner/admin or site admin), computed in load_switcher. Non-managers never see it.

Acceptance criteria

  • Clicking an enclave opens the room you last had open there.
  • First visit opens the default/main room.
  • Last-selected room persists across sessions (SQLite, survives restart).
  • Enclave with no rooms degrades gracefully (landing/onboarding, no crash).
  • Settings reachable via a gear button (top-left rail), not the enclave icon.
  • Gear respects RBAC (managers only).

Open questions resolved: gear lives in the switcher rail (top-left); last-room is per-account (server-side).

Tests

routes_enclave_nav.rs: default-room redirect, last-room reopen + persistence, empty-enclave landing, gear manager-only visibility. Three existing tests that assumed /enclave/{id} renders the landing updated to follow the redirect. Migration 0040 appended to hand-rolled lists. just check, just test, just test-saas green.

🤖 Generated with Claude Code

## Summary Clicking an enclave opens the room you last had open there (or the default room), instead of an enclave home page. Enclave settings move to a gear button (LC-143). ## Changes - **Redirect**: `GET /enclave/{id}` now redirects to the last-opened room in that enclave, validated against the current accessible set; falls back to the default (first, name-ordered) room. The landing page renders only when the enclave has **no** accessible rooms (empty/onboarding state). - **Persistence** (migration `0040`, `enclave_last_room`): one row per `(user, enclave)`, upserted on room open in `get_room`. Survives restart. Stale rows (deleted room / lost access) fall back to the default. - **Settings gear**: the enclave switcher rail (top-left) shows a gear on the **active** enclave's tile -> `/enclave/{id}/settings`. Gated by `SwitcherEntry.can_manage` (owner/admin or site admin), computed in `load_switcher`. Non-managers never see it. ## Acceptance criteria - [x] Clicking an enclave opens the room you last had open there. - [x] First visit opens the default/main room. - [x] Last-selected room persists across sessions (SQLite, survives restart). - [x] Enclave with no rooms degrades gracefully (landing/onboarding, no crash). - [x] Settings reachable via a gear button (top-left rail), not the enclave icon. - [x] Gear respects RBAC (managers only). Open questions resolved: gear lives in the switcher rail (top-left); last-room is per-account (server-side). ## Tests `routes_enclave_nav.rs`: default-room redirect, last-room reopen + persistence, empty-enclave landing, gear manager-only visibility. Three existing tests that assumed `/enclave/{id}` renders the landing updated to follow the redirect. Migration `0040` appended to hand-rolled lists. `just check`, `just test`, `just test-saas` green. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(navigation): clicking an enclave opens last/default room; settings gear (LC-143)
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 5s
21d0d8886a
Clicking an enclave used to land on an enclave home page. Now GET /enclave/{id} redirects to the room the user last had open in that enclave, falling back to the default (first, name-ordered) room. The landing page only renders when the enclave has no accessible rooms - an empty/onboarding state.

Persistence (migration 0040, enclave_last_room): one row per (user, enclave), upserted on room open in get_room. Survives restart. A stale row (room deleted or access lost) is validated against the current accessible room set before redirect and falls back to the default.

Settings move out of the click target: the enclave switcher rail (top-left) now shows a settings gear on the active enclave's tile, linking to /enclave/{id}/settings. Gated by SwitcherEntry.can_manage (owner/admin or site admin), computed per enclave in load_switcher via perms::enclave_can_manage. Non-managers never see the gear.

Tests: routes_enclave_nav.rs covers the default-room redirect, last-room reopen + persistence, the empty-enclave landing fallback, and the gear's manager-only visibility. Updated three existing tests (routes_enclave.rs x2, routes_sidebar_categories.rs) that assumed /enclave/{id} renders the landing - they now follow the redirect to the room page (whose sidebar carries the same room/category markup). Migration 0040 appended to the hand-rolled migration lists. just check, just test, just test-saas all green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(navigation): pick enclave default room from the openable set (LC-143)
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 4s
0a63c6cc44
get_landing chose the redirect target (last/default room) from the manage-view room list, which includes private rooms an enclave owner is not a member of. get_room enforces is_room_accessible (site-admin god-mode, else public-in-enclave or explicit private membership), so an owner could be redirected straight into a 403. Pick the target from a list built with can_see_all_private = is_site_admin, matching the accessibility get_room enforces; the manage-view list is still used for the empty-state landing render. New test: an owner not in a private room lands on the public room, not the inaccessible private one.

Note: load_switcher does a per-enclave membership lookup (now) plus the existing per-enclave branding resolve on every authed page. Acceptable for typical enclave counts; a batched lookup is a clean follow-up if enclave-per-user grows large.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
nrupard deleted branch feat/lc-143-enclave-last-room 2026-05-20 20:30:53 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!166
No description provided.