dev_arc_aws/ROADMAP.md
Samuel James b836ac1a02
Keep SSH terminal sessions connected across page navigation (#30)
The Terminal page held all session state (xterm instances and their
WebSockets) in component-local React state. Because it renders as a
`<Route element={<Terminal />}>`, navigating away unmounted it and ran
the xterm cleanup (`term.dispose()` + `ws.close()`), tearing down every
SSH session. Returning to the page reconnected from scratch, losing
scrollback and any running work.

Lift terminal sessions into a `TerminalSessionProvider` mounted above the
router (in `main.tsx`, inside `AuthProvider`). The provider owns each
pane's xterm instance, fit addon, WebSocket, and a persistent wrapper DOM
node. Wrappers live in a hidden container at the app root; the Terminal
page re-parents them into its grid on mount and moves them back to the
hidden root on unmount instead of disposing — so the xterm + WebSocket
keep running in the background across route changes.

Disconnect semantics: closing a tab/pane (or shrinking the 1/2/4 grid)
destroys those sessions; logout tears down all sessions. A full browser
reload still drops connections (the WebSocket dies with the page) — this
persists across in-app navigation only.

Shared terminal constants/types/prefs are split into a non-component
module (`src/lib/terminalPrefs.ts`) so the context file stays a clean
component module.

Also document the terminal window grid-view tiering in ROADMAP.md
(self-hosted = 4-window cap, current; paid = as many as fit on screen,
planned for the AWS deployment), and realign HANDOFF/README/design-docs
to reflect that auth Phase 3 (multi-user) shipped and Phase 4 (SSO) is
deferred to a paid AWS add-on.

Verified with a clean `tsc -b && vite build` (frontend) and
`tsc --noEmit -p .` (backend).

Co-authored-by: Samuel James <ssamjame@amazon.com>
Co-authored-by: Kiro <noreply@kiro.dev>
2026-06-20 15:02:50 -04:00

3.7 KiB

ArchNest — Roadmap

Forward-looking work that is planned but not currently being built. For the state of shipped work and the active task, see HANDOFF.md. For historical feature build-out, see TERMIX_MIGRATION.md.


Shipped (for context)

The auth roadmap so far — full detail in HANDOFF.md:

  • Phase 1 — User menu Profile/Appearance/Security wired up; ?tab= deep-linking in Settings.
  • Phase 2 — Password change, server-tracked sessions, login audit log.
  • Phase 3 — Multi-user accounts: admin/member roles, active flag, 10-seat cap, admin-only user management, requireAdmin/adminOnly gating.

Phase 4 — Authentik SSO (OIDC) — PAID ADD-ON (AWS deployment)

Status: deferred. This is intentionally not part of the self-hosted core build. It is planned as a paid add-on, shipped when ArchNest is deployed on AWS — not on the current racknerd1 deployment.

Local username/password auth (Phases 1-3) remains the free, always-available path and the admin recovery path; SSO layers on top of it rather than replacing it.

Intended scope (when built)

  • Instance-level SSO config (issuer URL, client ID/secret, redirect URI) — likely an integration-like settings entry, or a dedicated config table / env vars.
  • GET /api/auth/sso/login → redirect to Authentik.
  • GET /api/auth/sso/callback → exchange code, look up/create local user by SSO subject claim (respecting the 10-user cap from Phase 3), issue the same JWT format as today.
  • "Sign in with SSO" button on Login.tsx alongside username/password (local accounts remain — do not remove password auth entirely).

Open scope questions (decide before any code)

  1. Where does SSO config live? env vars (simplest, redeploy to change) vs. a dedicated config table vs. an integration-like settings entry (editable in-UI, more work).
  2. First-login provisioning — auto-create a local member for an unknown-but-valid SSO user (subject to the 10-seat cap), or require an admin to pre-create the account and only link it on SSO login?
  3. Role mapping — do Authentik groups/claims map to admin/member, or do all SSO users default to member with roles managed locally?

Terminal — window grid view (tiered: self-hosted vs. paid)

Status: self-hosted behavior is current; the paid tier is planned.

The Terminal page (src/pages/Terminal.tsx) supports a split-pane grid view within a tab.

  • Self-hosted (current): capped at a 4-window grid (1 / 2 / 4 pane layouts via the toolbar buttons). This is the free, always-available tier.
  • Paid (planned, AWS deployment): as many windows as fit on the screen — dynamic grid sizing beyond the 4-pane cap, laid out responsively to the viewport rather than a fixed 1/2/4 choice.

When the paid tier is built, the 4-pane cap becomes a licensing/feature gate rather than a hard UI limit; the grid layout logic generalizes to an arbitrary pane count.


Known non-blocking stubs (cosmetic, not scheduled)

Not flagged as work to do unless explicitly asked:

  • Infrastructure.tsx's "Network" sub-tab is intentionally disabled (title="Coming soon") — leave alone unless explicitly asked.
  • Settings.tsx's Appearance section (theme/accent/fontSize/radius/ sidebarExpanded/animations) is local-state-only — doesn't persist or apply anywhere. Recommended fix if picked up: mirror the Terminal page's localStorage-backed prefs pattern and apply via CSS variables on :root.
  • Settings.tsx's Notifications section (email/push/sound toggles) has no backing delivery mechanism — recommend removing or clearly labeling as not-yet-functional rather than persisting settings that do nothing.