The "Enable AI assistant" toggle already disabled the AI for everyone
(including owners/admins) at the policy layer, but the copy read as an
employee-only control and the Analysis surface stayed visible. Clarify
that the master switch covers admins too, and close the gaps: hide the
Analysis nav/command entry and redirect /analysis (alongside the chat
home) to /patients when AI is disabled. The employee-only toggle remains
the secondary option that keeps AI for owners/admins.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- new org_ai_policy table + GET/PUT /api/ai/policy (read for any member,
write owner/admin only); migration 0018
- /api/chat hard-blocks (403) when AI is off for the caller
- Settings → AI "Availability" section: enable AI, or disable for
employees only (owners/admins keep access); read-only for non-admins
- sidebar, command palette and route guard hide/redirect the AI chat
when it's disabled for the current user
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the email-invitation flow with admin-provisioned staff accounts and
add role-based access that changes what each member sees.
Backend:
- Enable Better Auth `username` plugin (staff sign in by username); regenerate
auth schema (+ username/displayUsername on user) and migration 0007.
- Add `doctor` and `reception` roles to the access-control RBAC. `reception` is
scoped to scheduling + registration (no `prescription` statement).
- New `/api/staff` route: POST creates a user (auth.api.signUpEmail) and adds
them to the active clinic (auth.api.addMember); GET lists members + usernames.
Gated by requirePermission({ member: ["create"] }).
- Redact clinical PHI for the reception role in the patients service (read,
create and update) so demographics-only is enforced server-side.
Frontend:
- usernameClient + Email|Username tabs on the login form.
- lib/roles.ts: useActiveRole + Better-Auth-permission-driven nav visibility,
default landing, and a route guard (reception -> /appointments, blocked from
clinical routes). Applied to the sidebar, command palette and auth guard.
- Care team page now provisions staff via a two-step Add-team-member dialog
(details -> username/password) hitting /api/staff; removes the email-invite
and pending-invitation UI. New members are contactable from Messages
automatically (they become org members).
- Hide clinical sections of the patient form and the admin-only settings tabs
for non-clinical/non-admin roles.
All permission management stays in Better Auth (per the better-auth skills now
referenced in backend/CLAUDE.md).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Footer is now a single user row. The ⌘K command hint moved into the user
menu below Theme, and the clinic switcher became a hover submenu below that
(revealing the active clinic's name/slug/count, the switch list, and
Create clinic). Removed SidebarCommandButton and deleted team-switcher.tsx.
- Patients sub-nav (Patients / Appointments & Schedule): no icons, no
background change on hover/active — only the text color changes.
- Appointments & Schedule: added an "Add" button that opens the create-patient
dialog.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Round-2 fixes to the 6 features:
- Logo: enlarge the sidebar mark, drop the inline wordmark, and show
"temetro" via a hover tooltip; bigger logo on the auth screens.
- Sidebar footer: wrap the quick-nav, clinic switcher, and user menu in a
single bordered block so it reads as one footer instead of three cards.
- Sidebar nav: highlight the active page (usePathname + data-[active]), and
add an Appointments & Schedule sub-page under Patients that auto-expands
for the current section. New mock /appointments page; reachable via ⌘K.
- Notes: redesign to a two-pane list + editor with an Empty state on the
right when nothing is selected; fix the editor so text starts top-left
(div instead of a centering <button>); compact the toolbar; add
.note-content typography in globals.css so headings/lists/etc. actually
render (the app has no typography plugin).
- Patients: new PatientDetail laid out to fit the side Sheet (stacked
full-width sections, no nested click-to-expand dialogs); keep Edit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Several navigation/UX additions:
- Command palette (⌘K): components/command-palette.tsx wraps the app shell
(mounted in app/(app)/layout.tsx) with a controlled COSS CommandDialog listing
the nav pages; a "Quick nav" Kbd button in the sidebar footer also opens it.
Installed @coss/kbd. Extracted the nav list into lib/nav.ts so the sidebar and
palette share one source of truth.
- Clinic switcher moved from the sidebar body into the footer; its menu now
opens a read-only "Clinic info" dialog and a "Create clinic" dialog instead of
routing to /onboarding. Shared CreateClinicForm (components/clinic/) is reused
by onboarding.
- Patients: clicking a row opens a right-side Sheet with the full record
(components/patients/patient-detail-sheet.tsx) instead of navigating to the
chat; PatientResult gained a vertical "column" layout for the Sheet.
- New Analysis page (app/(app)/analysis/) — a mock dashboard (revenue/profit,
patient volume, appointments, operations) reusing Sparkline + Card + Badge.
- Logo: set metadata.icons so the new mark appears as the browser-tab favicon.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>