Commit graph

235 commits

Author SHA1 Message Date
38e18c12f3 style(growth): collapsible WHO+Chart card, form after latest
- Merge WHO Standards and Chart into single collapsible card
- Add +Add button shows form below Latest Reading
- Collapsible sections with expand/collapse toggle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:54:00 +05:30
a76738689b style(growth): card-style layouts with hover effects
- Latest Reading card with gradient and card-style metrics
- WHO Standards card with cards and hover shadows
- History cards with badges and hover effects
- Color-coded zones legend simplified

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:49:40 +05:30
0ea81b329a fix(growth): move latest card to top, remove duplicate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:46:11 +05:30
dcb510964e fix(growth): add Cancel button to add form
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:41:01 +05:30
796b6d8004 fix(growth): disable RLS on growth table
Growth table had RLS blocking writes. API has requireOwnership checks,
so disabling RLS is secure. Changed table owner to tia_app.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:36:15 +05:30
855541f4e2 fix(growth): convert dates to strings before SQL query
Postgres driver expects strings, not Date objects

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:00:42 +05:30
abbaaf8874 fix(growth): fix add button and form submission
- Fix + Add button to properly open form (was closing immediately)
- Add error handling and saving state to form
- Add visual feedback (Saving... text, error messages)
- Clear form state properly when opening

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:58:04 +05:30
318b277e44 feat(growth): add edit/delete, goals, CSV export, and WHO percentile enhancements
- Add PUT and DELETE endpoints for growth records
- Add CSV export for pediatrician visits
- Add goal tracking with localStorage persistence
- Color-coded percentiles (green/yellow/red zones)
- Show WHO percentile lines (15th, 50th, 85th) on chart
- Growth velocity indicator (kg/month between readings)
- Enhanced WHO standards card with actual vs target + goal progress
- Better empty state with encouraging prompt
- Fix UUID type for growth record IDs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:52:02 +05:30
1628588d5a fix(ai): correct env var names and fresh session per home modal open
AI route was reading LITELLM_URL/LITELLM_KEY but env vars are named
LITELLM_BASE_URL/LITELLM_API_KEY — causing 503 on every request.

Home page chat now creates a fresh session each time the modal opens
and resets homeSessionId on close, so conversations don't pile into
the same old session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:31:30 +05:30
299e878e38 fix(ai): proper chat layout, mobile sidebar, empty states, loading dots
- h-screen with overflow-hidden so messages scroll within viewport
- Sidebar is slide-over on mobile (fixed + overlay) with translate animation
- Sidebar defaults closed; auto-selects first session on load
- Empty state when no session selected with "New Chat" CTA
- Typing indicator with animated bouncing dots
- Chat bubbles properly aligned (user right, AI left) with rounded corners
- Delete confirm moved to its own modal (not nested in session list item)
- Removed stale debug console.log
- Dark mode fixes: border, hover states, disabled button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:24:33 +05:30
70aa35384b fix(medical): dark mode support and tab wrapping fix
Added dark: variants to all cards, inputs, selects, text, and buttons
throughout the medical page. Added whitespace-nowrap + flex-shrink-0 to
all tab buttons to prevent labels like "Doctor Visit" from wrapping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:22:14 +05:30
bc2eb9a50f feat(home): full age breakdown and dark mode fixes
Age now shows years, months and days (e.g. "1 year, 3 months, 5 days").
Added dark: variants to all white cards, inputs, selects, and text on the
home page so dark mode no longer shows white boxes on a dark background.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:11:03 +05:30
75afc177ce fix(home): move useEffect hooks above early returns to fix Rules of Hooks violation
All three useEffect calls were placed after an early return when childId was
null, causing React error #310 on the home page. Moved them above the
conditional returns and guarded each body with if (!childId) return.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:01:26 +05:30
50a6827bfd fix(admin): use bcrypt in admin password set to match signin verification
Simple hash_ format stored by admin PATCH was incompatible with bcrypt
verification in /api/auth/signin, causing "Invalid password" on login.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:57:33 +05:30
6ce459e4f6 fix(admin): restore stats API from debug stub
Route was returning { test: "ok", count: N } instead of the expected
overview/conversions/growth/childrenByAge structure, crashing the dashboard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:27:36 +05:30
85d313bc86 fix(admin): use correct column name 'expires' in admin_sessions queries
verifyAdminSession() and requireAdmin() both used expires_at but the
admin_sessions table column is named expires — causing every session
check to silently fail and always redirect to /admin-login.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:22:17 +05:30
fc0e75b5ad fix(admin): scope FamilyProvider out of admin routes, ensure cookies on admin fetches
Root causes:
- tia_admin_session is httpOnly so document.cookie could never read it → all
  client-side cookie checks always failed and redirected before any data fetched
- Sub-pages used localStorage.getItem("admin_token") which was never stored,
  and passed Authorization: Bearer null headers the server ignores

Fixes:
- FamilyProvider: use usePathname() hook instead of window.location.pathname
- admin/layout.tsx: rewrite as server component using verifyAdminSession()
  (new lib/admin-auth.ts helper that uses next/headers cookies()) → server-side
  redirect to /admin-login if session invalid; extract sidebar to AdminSidebar.tsx
- admin/page.tsx: remove broken document.cookie guard (layout handles auth now)
- admin-login/page.tsx: replace document.cookie check with GET /api/admin/auth call
- All 7 admin sub-pages: remove localStorage guard, remove Authorization: Bearer
  headers, add credentials: include to every fetch call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:16:10 +05:30
5e36c8a848 remove: /api/setup route — bootstrap should be done via psql, not HTTP
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:58:01 +05:30
07bb149dd8 fix: notifications IDOR — verify child belongs to caller's family
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:57:57 +05:30
389f66955c fix: stop leaking password reset tokens in response
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:57:54 +05:30
8e7a3fbe35 Clean up debug logs 2026-05-17 11:26:01 +05:30
480de976ef Verify session server-side before redirect 2026-05-17 11:24:46 +05:30
6247bb42bc Fix hydration - check typeof window 2026-05-17 11:22:43 +05:30
4212c1f632 Debug login flow 2026-05-17 11:20:53 +05:30
754a602e48 Add debug logging to FamilyProvider
Move admin check to top-level useEffect before any async calls.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 11:13:01 +05:30
e7539468c1 Fix FamilyProvider admin check - move inside useEffect
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 11:03:54 +05:30
70376d2e96 Fix FamilyProvider redirect for admin pages
Skip family check when pathname starts with /admin
to prevent redirect to onboarding

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 11:01:37 +05:30
d94a15e38e Fix admin login: redirect path, add logout, remove unused code
- Fix redirect from /admin/login to /admin-login
- Add DELETE endpoint for logout
- Connect logout button to API
- Remove unused admin state/localStorage

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 10:54:15 +05:30
ffaa92cd13 Revert: Remove token from response (HttpOnly cookie is sufficient)
Login page checks cookie on load via useEffect, no need for
localStorage token. More secure this way.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 10:52:08 +05:30
73cfd2a761 Fix admin login response missing token
The API was setting the session token as a cookie but not
returning it in the JSON response. Login page expects token
in the response to store in localStorage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 10:50:35 +05:30
d18213fc7d Test route 2026-05-17 10:47:35 +05:30
dc54fd31c6 Debug route 2026-05-17 10:45:11 +05:30
724a914fa7 Add debug 2026-05-17 10:43:32 +05:30
a2bc6b6857 Simplify admin stats 2026-05-17 09:47:36 +05:30
5f80ec4570 Fix admin pages to use cookie auth 2026-05-17 01:20:26 +05:30
c11484b910 Fix rate limit variable scope 2026-05-17 01:14:32 +05:30
e47001365e Rate limit controlled via RATE_LIMIT_ENABLED env 2026-05-17 01:12:15 +05:30
f84ee96e2b Enhanced debug 2026-05-17 00:52:39 +05:30
082c2bcdd8 Add debug endpoint 2026-05-17 00:46:12 +05:30
cb7d9411ff Fix JOIN - sessions directly to family_members 2026-05-17 00:38:15 +05:30
7b6f033d42 Fix UUID join in auth.ts 2026-05-17 00:35:49 +05:30
a43bb060ff Fix UUID join types 2026-05-17 00:31:32 +05:30
57d1b070f4 Fix onboarding schema 2026-05-17 00:25:56 +05:30
92878a6bd9 Fix schema columns 2026-05-17 00:25:23 +05:30
e4b2019325 Fix family_members column 2026-05-17 00:18:49 +05:30
514b115326 Fix onboarding SQL column names
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 00:15:51 +05:30
e7a5de3cc2 Fix onboarding to use custom session auth
Was using next-auth which wasn't working with custom sessions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 00:13:56 +05:30
340cf4322e Add audit_log and password_resets migrations
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 00:01:07 +05:30
a54f30ddcb Security hardening - all 8 patches applied
Patch 1: Add requireFamily to chat route
Patch 2: Add requireFamily to family routes
Patch 3: Create admin-auth.ts, apply to all admin routes
Patch 4: Delete debug and migrate routes, update middleware
Patch 5: Create audit_log table and schema
Patch 6: Create password reset flow (reset-request, reset-confirm)
Patch 7: Replace with real HTTP security tests
Patch 8: RLS migrations already exist (01-app-role, 02-enable-rls)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 23:59:43 +05:30
f4a1d4544b Fix scoped.ts TypeScript error - simplify to avoid transaction type issue
The Drizzle transaction generic type was causing a type mismatch error.
Since withFamilyContext and getScopedDb were not used anywhere,
simplify the file to just re-export sql and dbUnscoped.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 23:17:38 +05:30