Commit graph

373 commits

Author SHA1 Message Date
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
b3e8b0a75f Fix TypeScript error in AI route 2026-05-16 23:13:24 +05:30
5acb2760cc Fix db imports: use dbUnscoped 2026-05-16 23:12:33 +05:30
2196c3d07d Security hardening: auth, bcrypt, rate-limiting, RLS, audit 2026-05-16 23:11:01 +05:30
4cf886ea43 Add security libs: auth, audit, rate-limit, scoped db 2026-05-16 23:10:56 +05:30
149d8bc72c auth: fix family_id join with uuid cast 2026-05-16 23:05:20 +05:30
ca4e1355d6 Dockerfile: enable pnpm in builder stage 2026-05-16 22:38:02 +05:30
aec1e4bcab Dockerfile: use pnpm install --ignore-scripts to bypass build approval 2026-05-16 22:37:16 +05:30
d5a48072d7 Dockerfile: approve build scripts for esbuild/sharp 2026-05-16 22:35:58 +05:30
6f800e07df Dockerfile: use pnpm instead of npm
- Replace npm ci with pnpm install --frozen-lockfile
- Use corepack to enable pnpm
- Update COPY for pnpm-lock.yaml
2026-05-16 22:34:36 +05:30
387da42286 Add growth chart with WHO percentile bands
- Line chart showing child's growth over time
- Toggle between weight/height/head
- WHO 50th percentile reference line
- WHO p3-p97 range zone

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 18:31:24 +05:30
0865706a94 Add WHO growth standards with percentile tracking
- Add head circumference to WHO standards (boys & girls 0-24 months)
- Update growth API to return WHO standards with records
- Update growth page to show percentile rankings
- Add head circumference input to form
- Use FamilyProvider instead of hardcoded childId
- Show percentile (e.g., "50th-85th") for each measurement

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 18:07:41 +05:30
260e287f0b Add vaccine reminders to home page
- Show vaccine reminder banner on home page
- Link to medical page for details
- Show due/overdue status

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