- SidebarMenuAction (the expand chevron on Patients/Pharmacy/Messages) used a
physical right-1, so in Arabic it sat on the right over the icons. Use the
logical end-1 so it's on the right in English and the left in Arabic, clear of
the icons.
- Revert the earlier header change: the notification bell and collapse toggle go
back to their original placement (no RTL column stacking, no mirrored glyph,
notifications popover back to side="right").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Arabic RTL: stack the collapse arrow/bell above the nav icons instead of
pinning them to the opposite edge; mirror the panel-toggle glyph; flip the
notifications popover to open toward the content side.
- "Use my current location" now reverse-geocodes (OpenStreetMap Nominatim) to
fill address/city/country, not just latitude/longitude, with a graceful
coordinates-only fallback. New settings.location.geoPartial key in all 5 locales.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
backend: public GET /api/portal/:clinic/doctors and /availability, and
thread a chosen provider into portal bookings (conflict check unchanged).
frontend: fix site-wide Arabic RTL — anchor the sidebar right for RTL and
mirror the Switch thumb. Add a Patient Portal section (open/copy/QR) to
Settings → Signing and a "Use my current location" GPS button to the clinic
location editor. New i18n keys across all five locales.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Chat: history pill now shows a History icon + a Start-new-chat (SquarePen)
button; removed the duplicate chat-history list from the sidebar.
Email: deployment-wide email provider config (Resend/Postmark/SendGrid/SMTP) in
Settings → Developers, with encrypted API key and a Send-test action. sendEmail
dispatches via the chosen provider (REST via fetch; SMTP via nodemailer).
Forgot password with no provider: alert the clinic admin(s) via a "System"
message card in Messages + a bell notification (seeded system user + per-clinic
System conversation); clicking deep-links to /settings?tab=careTeam&member=<id>.
Admins can set a member's password directly from the employee dialog
(PATCH /api/staff/:id/password via Better Auth's internal context — no admin
plugin needed).
Patient Portal: "New patient" booking path registers a demographics-only patient
then books; bookings reject double-booked slots (409).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Live invite: ring a clinic member into a room (socket call:invite + a bell
notification); the invitee gets a toast with a Join action. Notifications of
type "meeting" deep-link to /messages/meetings?room=, which auto-joins.
- Scheduling: new scheduled_meetings table + /api/meetings/events (list mine,
create, delete); a Calendar tab on the Meetings page with a month picker
(meeting-day dots), the day's agenda, and a Schedule-meeting dialog
(title/date/time/participants).
- Redesign: rounded control bar with tooltips (mic/cam/screen/invite + separated
red Leave), speaking ring on tiles (Web Audio), and live room-occupancy counts
via call:presence broadcasts. Migration 0025.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
real Live card, persistent chat history
Analytics & earnings:
- Analytics now carries real money computed from invoices (billed/paid/
outstanding + by-month); new Earnings section on the Analysis page drawn with
the project's Bklit chart components (shared EarningsChart).
AI agent reaches the whole clinic:
- new read tools getClinicInfo / getAnalytics / listInventory render clinic,
analytics (with a Bklit earnings chart) and inventory cards in chat
- proposeInvoice turns an uploaded purchase/medication list into an invoice
(new "invoice" action-preview kind → createInvoice); invoices/appointments
auto-create/link a patient (ensurePatient) so they hit the Patients page
Live card:
- plots real data — patients checked in today — via GET /api/analytics/live
(polled); value pill clamped and margins widened so nothing spills the card
Persistent AI chat history (Claude-style):
- ai_chat_threads + ai_chat_messages (migration 0016); per-user, org-scoped
thread CRUD under /api/chat/threads
- chat panel owns a thread id, loads /?thread=<id>, and auto-saves after each
exchange; sidebar lists past chats (open/delete), "New chat" starts fresh
Verified with backend typecheck + frontend tsc + next build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- sidebar + auth logo now invert to black in light mode (dark unchanged),
same trick the docs site uses — no second asset needed
- prescriptions page: search by patient, file number, medication,
prescriber or status, with no-match / empty states
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>
Auto-generate notifications on patient record create/update (fan out to
the other clinic members, pushed live), and wire the sidebar bell to real
data via a useNotifications hook over the shared socket: live unread badge,
real list, mark-all-read on open. Drops the hardcoded sample array and the
dead "View all" link.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Appointments: a Calendar button next to Add opens a month-grid dialog
(reuses the Calendar primitive + shared ScheduleList); the schedule day is
marked and selecting it lists that day's appointments.
- Patients sub-nav: new Prescriptions page (mock list + KPIs) with a compact
"New prescription" dialog reusing the patient quick-search pattern.
- Notes: deleting a note now goes through a reusable ConfirmDialog instead of
deleting immediately.
- New top-level Messages page: two-pane email-style inbox (list + reading pane
with mock reply composer), mirroring the Notes layout.
- Sidebar logo bumped from size-9 to size-10.
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>
Components:
- Replace components/ui primitives with COSS equivalents from the @coss/* shadcn
registry. Add menu/preview-card/group; remove the superseded dropdown-menu,
hover-card, button-group; keep carousel (no COSS equivalent).
- Migrate live call sites to canonical COSS APIs preserving layout/behavior:
sidebar menus (nav-user, team-switcher, nav-notifications), chat-input radio
menu, patient dialogs/cards, auth forms (FieldGroup -> flex column), settings.
- ai-elements: migrate the live conversation/message with behavior parity
(Tooltip via render, Group/GroupText); repoint dormant files (hover-card ->
preview-card, dropdown-menu -> menu, button-group -> group, InputGroupButton
-> Button). Residual pre-existing Base UI type drift stays behind
ignoreBuildErrors.
Theme:
- Adopt COSS default neutral tokens in globals.css with light + dark palettes.
- Add next-themes (defaultTheme=dark, enableSystem) and drop the forced dark
class. Align font variables to the COSS contract (--font-sans/-heading/-mono).
Make scrollbars theme-aware.
i18n:
- Add i18next + react-i18next (lib/i18n/config.ts, locales/en/translation.json,
components/i18n-provider.tsx mounted in layout). Convert auth forms, sidebar
nav, and settings tabs to useTranslation() as the reference pattern.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Connects the UI-only app to the new backend over Better Auth + a small
patient API client, replacing the in-memory fixture and placeholder identity.
- Better Auth React client (lib/auth-client.ts) + shared access-control
roles; API client (lib/api-client.ts) sending credentials cross-origin.
- Designed (auth) route group: login, signup, verify-email, forgot/reset
password, clinic onboarding, and accept-invite.
- proxy.ts (this Next's renamed middleware) optimistic redirect + an
authoritative client AppAuthGuard requiring a session and active clinic.
- Real identity in nav-user (useSession + sign out); the unused team
switcher repurposed as an organization (clinic) switcher; Care-team
settings tab manages members and invitations.
- lib/patients.ts now calls the org-scoped API (types unchanged); patients
table and create/edit dialog updated for async create/update.
- next.config: standalone output + Dockerfile for containerized runs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Patients: new /patients directory table (name, MRN, age·sex, status,
last seen, allergies) with search + Add patient; clicking a row opens
the record in the chat via /?patient=<#>. chat-panel reads that search
param (Suspense-wrapped) and runs the lookup once on arrival. Sidebar
"Patients" now links to /patients; lib/patients gains listPatients().
- Settings: re-themed to clinical tabs (Profile · Records · Signing ·
Care team · Developers) — clinician profile, patient notifications,
patient-owned-storage/signed-records features, and a Signing key panel.
Same layout/components, only content changed.
- Sidebar footer: Polar-style NavUser (avatar + name + chevron) opening a
menu upward — Settings · Docs & GitHub · Theme · Log out. Collapsed
("locked"): avatar only, name on hover (tooltip), menu opens to the
right. Placeholder identity (no auth yet).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- app-sidebar: remove the "Saved" and "Conversations" nav items (dead #
links) and the "temetro / Clinic" team switcher; footer is now a plain
"temetro · open source" wordmark. Keep the notifications bell. Drop the
now-unused Bookmark/MessageSquare/Logo/TeamSwitcher imports.
- CLAUDE.md (frontend): rewrite "What this is" to match the current
patient-records flow (/patient cards, sparklines, create/edit dialog over
the mock fixture) and point to the project vision; note team-switcher.tsx
is unused.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>