Commit graph

381 commits

Author SHA1 Message Date
ee3f8b4507 Register 0003_circles in Drizzle migration journal
The SQL file existed but was missing from _journal.json so the
migrator skipped it on deploy. Adding the journal entry ensures
the circles tables are created on next container boot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 01:14:38 +05:30
5fdb69679d Circle feature: C0–C9 multi-tenant social groups (Sprint 9 + 10)
Adds full circle functionality — private social groups for trusted families
to share milestones, memories, and posts with reactions and comments.

- 7-table DB migration: circles, members, invites, posts, comments, reactions, reports
- 11 API routes: create/list circles, posts feed, comments, emoji reactions, invite tokens, join flow, member management, reporting
- 3 new pages: /circle (list), /circle/[id] (feed + PostCard + CreatePostModal), /circle/join/[token]
- Copy-on-share for memory photos (independent R2 objects, never references originals)
- Admin controls: invite generation, member promote/demote/remove, last-admin guard
- C9 privacy consent screen before first post
- Menu entry added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 01:04:50 +05:30
c732d2d7c2 Add baby profile photo change from home screen
- New PATCH /api/children/[id] — updates image_url in children table
- New POST /api/children/[id] — returns presigned R2 URL for profile
  photos (stored under profiles/{childId}/ prefix, no memories row)
- FamilyProvider: expose updateChildImage() so UI updates instantly
  without a full re-fetch after upload
- Home page baby card: photo avatar is now a separate tap target from
  the growth link. Tap photo → file picker → upload to R2 → save URL.
  Camera overlay (📷) appears on hover/tap;  shown while uploading.
  Tapping name/age/arrow still navigates to growth as before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:51:45 +05:30
5297ab76ba Activity: each feed/sleep/diaper row independently tappable in 4-day strip
Each row in a day chip is now its own button. Tapping 🍼×2 on Thursday
opens a sheet scoped to feeds on Thursday only — not all logs for that day.
Sheet shows entries for that specific type, with edit/delete per entry and
a single focused "+ Add [type]" CTA at the bottom.
Rows showing ×0 render dimmed so missing entries stand out at a glance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:26:43 +05:30
3db6fb2710 Activity: guidelines above strip, interactive day chips
- Moved guidelines row ABOVE the 4-day strip (correct order)
- 4-day strip: each chip is now tappable
  → opens a day-detail bottom sheet showing all logs for that day
  → each log row has ‹ › arrow; tap opens edit/delete action sheet
  → empty state tells mama to use Generate sample history to pre-fill
  → quick-add row at bottom (+ Feed / + Sleep / + Diaper) for fast logging

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 23:47:20 +05:30
a14d8e7043 Fix activity page repetition + 4-day strip layout + guideline accuracy
- Remove redundant daily summary bar (Today chip in 4-day strip covers it)
- 4-day strip: reversed to oldest→newest order (Wed→Thu→Yest.→Today)
- 4-day strip: switched from flex to grid grid-cols-4 so all 4 chips
  fill the full row width evenly instead of floating left
- Today chip highlighted in rose-400 to stand out from past days
- Guidelines: corrected 9-12 mo (feeds 3→4, sleep 12→14h, diapers 3→4)
  per AAP; 12-18 mo sleep 11→13h, diapers 3→4; 18-24 mo sleep 11→12h,
  diapers 2→3; all now match mid-range AAP recommendations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 23:35:32 +05:30
164206c023 Activity page overhaul — 9 UX improvements
- FAB raised to bottom-20 to clear fixed bottom nav
- Branded loading: bouncing 🍼 😴 🚼 emojis
- Back button: white pill with shadow (matches other pages)
- Generate History moved to ⋯ overflow menu (keeps header clean)
- Filter pills: emoji labels (🍼 Feed / 😴 Sleep / 🚼 Diaper) + scrollbar-hide
- Daily summary bar: today's feed/diaper/sleep counts at a glance
- 4-day overview strip: quick multi-day snapshot above timeline
- Collapsible guidelines card: collapsed shows x/target fractions,
  expands to progress bars with actual/target display
- Today/Yesterday/weekday labels in timeline; Today styled in rose
- Better empty state with emoji and "Tap + to start logging" CTA
- Tap any log row → action sheet with Edit and Delete
  Edit: pre-fills LogModal with same values, deletes old log on save
  Delete: inline confirmation (no browser confirm()), then refresh
- New DELETE + PATCH handlers at /api/logs/[id] with family ownership check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 23:07:02 +05:30
94b80fd862 fix(settings/profile): anchor share dropdowns to their trigger buttons
Reverted fixed viewport positioning back to absolute — the parent cards
no longer have overflow-hidden so absolute works correctly now. Both
dropdowns (profile share and per-product share) appear directly below/above
their trigger button instead of floating at a random screen corner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:37:13 +05:30
f806e4d3bd fix(settings/profile): fix share dropdown invisible + expand click broken
Root cause: parent div had overflow-hidden which clipped absolute-positioned
dropdowns, making them render but be invisible (looked like click did nothing).

- Removed overflow-hidden from profile card container
- Share dropdowns now use fixed positioning to escape any parent overflow
- Merged chevron into the expand button so the whole left area is one tap target
- Per-product share sheet also changed to fixed bottom-28 right-4

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 22:29:38 +05:30
fb402e9898 feat(settings/profile): move share to per-product, profile share on card header
- Each product row now has an ↗ share button (product URL shared, not profile)
  WhatsApp message: "Found this for our baby — [title]: [url]"
- Only one product share sheet open at a time; closes on backdrop tap
- Profile page share (↗) moved to the profile card header row where it
  contextually belongs — shares the /m/slug link, not a product
- Removed the share button that was on the Products section header

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:40:51 +05:30
8598259fb1 feat(settings/profile): collapsible profile card + share sheet
Collapsible profile card:
- Starts collapsed if profile already exists (shows name + URL slug)
- Expands/collapses via chevron toggle row
- Auto-collapses after Save Profile succeeds

Share sheet on Product Recommendations:
- ↗ Share button appears once a valid slug is set
- Options: Copy link (clipboard, shows  feedback), WhatsApp deep link,
  and native Web Share API ("More options") when browser supports it
- Backdrop click closes the sheet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:34:52 +05:30
3b62841bd4 fix(settings/profile): align My Profile page with app theme
- Background: flat gray → rose-to-amber gradient (matches all other pages)
- Header: add back button with rounded-xl pill style + xl font title
- Buttons: bg-pink-500 → bg-rose-400 throughout
- Loading: spinner → branded emoji bounce (consistent with home screen)
- Toggle: checkbox → styled toggle switch matching app UI language
- Layout: remove desktop max-w-lg wrapper; full-width mobile layout
- Input styling: unified inputClass with focus ring + consistent padding
- Empty state: plain text → emoji + two-line message
- Product rows: border div → bg-gray-50 pill card (matches wardrobe style)
- Add pb-24 so content clears the bottom nav bar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:26:38 +05:30
3d0e6ed46c fix(menu): remove absolute positioning that hid Wardrobe on mobile
Settings/Sign Out used absolute bottom-0, overlapping the bottom of the
menu items list on shorter screens. Converted to normal flow with mt-4
and added pb-28 so the list clears the bottom nav bar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:17:45 +05:30
70ff02c930 feat(home): overhaul home screen with bottom nav and UX improvements
- Add persistent bottom navigation bar (Home / Activity / AI / Menu)
- Fix TodaySummary bug: last-log times now show today's events only
- Replace 6 hardcoded AI chips with 3 AI-generated context-aware chips
- Show child's real profile photo in baby card (fallback to 👶 emoji)
- Recent Activity limited to 3 items with "See all →" link to /activity
- "Suggested now" promoted to prominent amber banner with "Log it →" CTA
- Offline pending banner is now a tappable retry button
- Branded loading state with bouncing emoji (🍼 😴 🚼 👶)
- Remove unused Button import from page.tsx
- Expose image_url via /api/children and Child type/FamilyProvider

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:08:58 +05:30
8a75adb94e feat(home): horizontal scrollable quick log + wardrobe shortcut
- Convert Quick Log from grid-cols-4 to horizontal scroll strip so
  it scales to any number of actions without layout breakage
- Add Wardrobe 👗 shortcut linking directly to /wardrobe/add,
  saving mama the Menu → Wardrobe → Add Garment 3-tap journey
- Fix: replace non-existent `no-scrollbar` class with `scrollbar-hide`
  across page.tsx, wardrobe pages, memories page, and TabBar component

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:21:32 +05:30
1994725101 feat(wardrobe): add complete wardrobe feature (W0–W9)
Schema (W0):
- Add garments, garment_wears, outfits tables with Drizzle migrations
- Drizzle migrations 0001 (garments/wears) and 0002 (outfits) auto-apply on deploy
- RLS policies in drizzle/manual/06-wardrobe-rls.sql (apply via superuser in prod)

API (W1–W9):
- POST /api/garments/upload — direct upload to R2 garments/ prefix with sharp thumbnail
- POST /api/garments/tag — vision tagging via LiteLLM, defensive parse, category validated
- GET/POST /api/garments — list with composable filters, create
- GET/PATCH/DELETE /api/garments/[id] — detail, edit, delete
- POST /api/garments/[id]/wear — log worn date
- GET /api/garments/outgrowth — pure SQL, explicit size ordering (no lexicographic sort)
- GET /api/garments/packing — active garments grouped by category
- GET /api/garments/outfit — Open-Meteo weather + deterministic outfit pairing, no LLM
- GET/POST /api/garments/outfits + DELETE [id] — saved outfits

Pages:
- /wardrobe — grid with status/category/size/season filters + outgrowth nudge
- /wardrobe/add — 3-step capture→vision→form, size required, batch-friendly
- /wardrobe/[id] — detail/edit/status lifecycle + wear history
- /wardrobe/packing — packing checklist by category
- /wardrobe/outfit — weather-aware suggestions with shown basis
- /wardrobe/saved-outfits — view/delete saved combinations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:09:22 +05:30
c4304615ec chore(dev): align dev Postgres to pg18 matching production
Production runs Postgres 18; the dev compose file pinned pg16. A pg_dump
from prod (v18) cannot be restored by a v16 pg_restore — the dump header
is rejected. Matching the major version fixes restores and removes a
latent source of dev/prod behaviour drift.

Also adopts the pg18 image's data-directory convention: the volume now
mounts at /var/lib/postgresql (the image places data in a version
subdirectory), and drops the obsolete compose 'version' key.
2026-05-23 14:22:15 +05:30
9b9b551463 feat(db): wire migration runner into the deploy pipeline
Makes schema changes deploy automatically: edit schema -> db:generate ->
commit -> push -> Dokploy redeploys -> migrations apply on container start.
No more Dokploy database terminal.

Components:
- src/db/migrate.ts: standalone migrator (single short-lived connection,
  fails loud on error so a bad migration crashes the container instead of
  letting the app serve a half-migrated schema)
- scripts/build-migrator.mjs: esbuild bundles migrate.ts -> dist/migrate.mjs
  with drizzle-orm + postgres inlined. Needed because Next.js standalone
  output keeps neither as a separate node_modules package.
- Dockerfile: builder runs db:build-migrator; runner copies migrate.mjs +
  drizzle/; CMD is 'node migrate.mjs && node server.js'
- package.json: db:generate / db:migrate / db:studio / db:pull /
  db:build-migrator scripts; esbuild promoted to an explicit devDependency
- pnpm-lock.yaml resynced

BUG FIX: .dockerignore had 'drizzle/' — migration SQL was excluded from the
build context, so even a correct Dockerfile COPY would have found nothing.
This was the second half (with the .gitignore bug in commit 1) of why the
migration pipeline never worked. Now only _archived/_introspected are
excluded.

Verified: full docker build succeeds; runner image contains migrate.mjs +
drizzle baseline; migrator tested end-to-end against a scratch DB (35
tables created, __drizzle_migrations populated, idempotent on rerun).
2026-05-23 13:40:30 +05:30
edd239fa69 chore(db): regenerate baseline migration from corrected schema
drizzle-kit generate against the now-prod-aligned schema produces a
single baseline migration covering all 35 tables.

VERIFIED: 0000_baseline_prod_2026_05_19.sql was compared column-for-column
and type-for-type against the drizzle-kit pull introspection of tia_prod.
Table sets identical, all columns and types match. The baseline is a
faithful representation of production.

This baseline will be marked as already-applied in prod's
__drizzle_migrations table (done out-of-band, not in git), so the migrator
runs nothing on the next deploy. It exists purely as the reference point
for future schema diffs.

Adds drizzle/README.md documenting the baseline reset and the migration
workflow going forward.
2026-05-23 12:25:20 +05:30
a3d3a140ed refactor(db/schema): align TypeScript schema with production
Path A baseline reconciliation. drizzle-kit pull against tia_prod showed
prod had drifted well past schema.ts because legacy hand-rolled migrations
0003-0015 wrote to the DB but were never reflected back into TypeScript.

Shared-table drift fixed:
- users:          + password_hash, + password_updated_at
- families:       + tier, + max_children, + max_members
- children:       col is 'stage' (kept JS key currentStage -> stage);
                  'image_url' not 'profile_photo_url'; birth_date is DATE;
                  sex nullable; dropped phantom stage_overrides
- family_members: dropped phantom display_name
- family_invites: dropped phantom display_name, accepted_at
- audit_log:      + resource_id, + resource_type; metadata -> jsonb; +5 indexes
- memories:       + vision_tags (text[]), + vision_embedding (vector 1536)
- logs.ts:        'diapers' phantom table renamed to diapersLogs ('diapers_logs')

19 missing tables added across new files:
- admin.ts:     admins, admin_sessions, password_resets
- support.ts:   support_tickets, support_responses
- ai.ts:        chat_sessions, chat_messages, ai_usage
- medical.ts:   medicines, medication_doses, allergies, illness_logs, doctor_visits
- affiliate.ts: member_profiles, recommended_products, product_clicks
- logs.ts:      + milestone_achievements
- audit.ts:     + log_corrections

BUG FIX: schema/index.ts never re-exported ./logs — Drizzle was blind to
feeds/sleeps/vaccinations/growth/medications. Now exported.

Verified: tsc --noEmit has zero non-test errors. Dropped phantom columns
confirmed to have zero references in src/.
2026-05-23 12:17:20 +05:30
e7d68c2fc6 chore(db): archive legacy migrations, stop gitignoring drizzle/
The drizzle/ folder was in .gitignore (line 34) — likely confused with
the build 'out/' dir. Effect: migration SQL never reached the server on
deploy, so the migration pipeline could never have worked. Only 7 of 18
files were ever force-tracked; 0000-0010 + most of manual/ were untracked.

- Remove drizzle/ from .gitignore; document why it must be tracked
- Archive legacy hand-rolled migrations 0000-0015 + manual/ to
  _archived_pre_baseline_2026-05-19/ (kept on disk; history retains old copies)
- Archive stale meta/ (knew of only 3 of 16 migrations)
- Baseline regeneration follows in subsequent commits
2026-05-23 12:05:50 +05:30
5fe24b8c59 feat(settings): move growth CSV export from growth header to settings page
- Remove 📥 export button from growth page header (less clutter)
- Add "Export Growth Data" row in settings with child name and CSV download
- Fetches growth records on demand, shows loading state while exporting

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 23:24:28 +05:30
acd2adde7e fix(growth): move add form to top, fix empty-state bug, clean up UI
- Add Measurement form now appears directly below the header (not buried
  after WHO card) so it's immediately visible when + Add is tapped
- Removed `&& latest` guard — form now works even with zero records
- Goals and Add are mutually exclusive: opening one closes the other
- 3-column grid for measurement inputs (weight / height / head on one row)
- Sticky header with backdrop-blur, smaller title (text-sm), icon-style
  export and goals buttons
- All cards use rounded-2xl + shadow-sm for consistent look
- "Add First Measurement" in empty state scrolls to top and opens the form

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:49:30 +05:30
9c0afa2054 feat(memories): 4-col grid, hover effects, folder label per tile, no blank tiles
- grid-cols-4 (~40% smaller than 3-col) with gap-1 and rounded-xl corners
- Hover: scale-110 image + dark overlay + expand icon (⤢)
- Subtle shadow + ring border on each tile
- Folder emoji + name shown below each tile (when assigned)
- Filter out tiles with no URL and remove tiles that fail to load (onError → null)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:45:23 +05:30
fb45250a27 feat(memories): smaller title, tap-to-zoom viewer, custom folder creation
- Header title reduced to text-xs (~50% smaller)
- Tap image in viewer to zoom 2x; tap again to zoom out
- Tap outside image area to toggle UI chrome (top bar / captions)
- "New folder" pill at end of folder row and in upload picker
- Custom folders saved to localStorage (tia_custom_folders)
- Custom folders appear in folder pills, upload picker, and move-to-folder sheet
- Emoji picker (15 options) + name input for new folders

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:35:31 +05:30
704faf070b feat(memories): redesign gallery with folders, grid view, and fullscreen viewer
- 9 recommended folders (First Steps, Bath Time, Feeding, etc.) stored as description
- 3-column square grid layout replacing masonry+rotation
- Folder picker modal before upload; PATCH assigns folder after upload
- Fullscreen MemoryViewer with tap-to-toggle captions and folder reassignment
- Loading shimmer per tile, processing overlay, lazy loading
- Removed all floating/rotation elements causing overflow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 22:19:07 +05:30
0e047e110f fix(memories): route upload through server proxy to avoid R2 CORS failure
Direct PUT to R2 presigned URL is cross-origin, causing "Failed to fetch"
in browsers without R2 CORS configured. Use the existing PUT /api/upload
proxy handler instead — file goes client → Next.js → R2 server-side.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:57:48 +05:30
96d28cbadc refactor: full codebase sweep — shared types, utilities, component splits
New foundations:
- src/types/index.ts — shared domain types (Child, Log, GrowthRecord, Medicine,
  Dose, Allergy, Visit, Illness, Vaccination, AIChat, ChatSession, Goal)
- src/lib/formatting.ts — calculateAge, formatAge, formatTimeAgo (eliminates
  3 duplicate implementations spread across page.tsx and growth/page.tsx)
- src/lib/api.ts — typed fetch helpers (api.get/post/patch/delete) with
  consistent error handling; replaces manual fetch boilerplate

New shared components:
- src/components/PageHeader.tsx — reusable back-link + title header
- src/components/TabBar.tsx — horizontal pill tab bar
- src/components/CalendarView.tsx — extracted from activity/page.tsx (was ~170 inline lines)
- src/components/medical/ — medical page split into 5 focused tab components:
  VaccineTab, MedicineTab, AllergyTab, VisitTab, IllnessTab

Pages updated:
- medical/page.tsx: 1029 → 42 lines (thin shell wiring the 5 tab components)
- activity/page.tsx: uses CalendarView + shared Log type + api.ts
- growth/page.tsx: uses shared GrowthRecord/Goal types + formatAge; fixes
  `any` catch clauses; fixes undefined → null in Chart.js dataset values
- page.tsx (home): uses shared Log/AIChat/ChatSession types + formatTimeAgo/
  calculateAge from formatting.ts; removes inline type definitions
- ai/page.tsx: uses shared AIChat/ChatSession types
- FamilyProvider.tsx: uses shared Child type; fixes `c: any` mapping

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:37:39 +05:30
3ebb3055a5 feat(logging): time presets, FAB on activity, today summary, smart defaults
- Extract offline queue to src/lib/offline-queue.ts
- Extract shared LogModal with time presets (Just now/5/15/30min/Custom)
  and smart default pre-fill from last log of same type
- Replace ActivityScroller with TodaySummary (today's counts + last time)
- Fix activity page: GET /api/logs without type param now returns all logs merged
- Fix field naming: log.loggedAt / log.amount (camelCase throughout)
- Add FAB to activity page for zero-navigation quick logging
- Recent Activity shows 5 most recent entries with correct field names

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:21:00 +05:30
93db148a65 fix(ui): replace baby face emoji with diaper symbol for diaper logs
Swap 👶🚼 (baby-changing symbol) in all four diaper-specific spots:
activity page getIcon(), homepage ActivityScroller, quick log button,
and recent activity list. Other 👶 usages (child profiles, onboarding,
admin children nav) are left unchanged as they represent babies, not diapers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:07:56 +05:30
5863c8c2e6 feat(activity): implement calendar view
Month grid with Su–Sa columns, colored activity dots per day (rose=feed,
blue=sleep, amber=diaper). Tapping a day opens a detail panel below the
grid with the full log list for that day. Month navigation with prev/next
arrows; future months are disabled. Filter pills apply to both views.
Limit raised to 200 entries so calendar data spans multiple months.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 11:04:42 +05:30
515e93aae1 fix(activity): repair full log flow — quick log → activity page
Three bugs fixed:

1. GET /api/logs required a `type` param; activity page calls without one,
   always receiving {error} → empty list. Fixed: when type is omitted,
   merge feeds + diapers_logs + sleeps, sort by time, return camelCase
   fields (loggedAt, subType, amount) matching the activity page interface.

2. Type-specific queries (used by homepage) still return raw snake_case
   rows unchanged so the homepage "Recent Activity" section is unaffected.

3. LogModal initialised subType as "breast_milk" regardless of log type.
   Adding a useEffect to reset it (breast_milk / wet / nap) when type
   changes prevents bad enum values from being sent for diaper/sleep logs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 10:49:00 +05:30
a75a543373 fix(milestones): align page UI to match activity and growth pages
- Rose gradient background instead of flat gray
- Header with ← back link and child name subtitle
- Active filter/category pills use bg-rose-400 instead of purple
- Progress bar gradient updated to rose-to-pink
- Full-width px-4 layout (removed max-w-2xl wrapper)
- Date picker uses design system Input + Button components
- Empty state with icon, consistent with other pages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 10:30:21 +05:30
7189fc766c refactor(ui): apply design system components across all pages
Replace raw <input>/<button>/<select> elements with Button, Card, Input,
Select, Modal, Badge, and ConfirmDialog from @/components/ui in all
non-admin and admin pages. Removes ~550 lines of inline Tailwind utility
classes from form elements while keeping all business logic intact.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 10:24:43 +05:30
291eb4793b feat(g5-g6): age-aware UX + mama affiliate page
G5 — Age-Aware UX:
- useStageCheck hook: maps birth date → BabyStage (newborn/infant/sitter/crawler/toddler/walker)
- Time-of-day fast-log suggestion chip on home page (time × stage matrix)
- Milestones page: 25 WHO/AAP milestones, category filter, progress bar, inline date picker
- Milestones API: GET (merged definitions + achievements), POST (upsert), DELETE (un-mark)
- DB: milestone_achievements table with unique(child_id, milestone_key)
- Milestones 🌟 added to menu

G6 — Mama Affiliate Page:
- member_profiles, recommended_products, product_clicks tables
- /api/profile CRUD (GET/PUT), /api/profile/products (GET/POST/PATCH/DELETE)
- Public routes: /api/profile/[slug] and /api/profile/[slug]/click (IP hashed)
- /settings/profile: slug + bio editor, product list with ↑↓ reorder + click counts
- /m/[slug]: beautiful public page (gradient bg, product grid, Shop → click tracking)
- Settings page link to profile setup

DB migrations: 0014_milestones, 0015_affiliate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 00:59:17 +05:30
5ca655fbe6 Merge pull request 'feat(g1-g4): design system, memories, medical tracking, AI brain' (#1) from feat/g1-g4-design-memories-medical-ai into main
Reviewed-on: #1
2026-05-17 12:27:43 +00:00
c2cabc01d3 feat(g1-g4): design system, memories pipeline, medical tracking, AI brain
G1 — Design System: 14 UI primitives (Button, Card, Modal, Sheet, Input,
Textarea, Select, EmptyState, LoadingShimmer, ConfirmDialog, WashiTape,
Badge, Avatar, Tabs), PageTransition with Framer Motion, sun/moon CSS vars,
Caveat font, /dev/components visual showcase.

G2 — Memories Pipeline: R2 presigned uploads, Sharp thumbnail generation,
LiteLLM vision captions + pgvector embeddings, CSS masonry gallery with
infinite scroll, private toggle, semantic search fallback to ILIKE.

G3 — Medical: dose log + correction audit trail, IAP vaccine bulk import,
emergency escalation page, pediatrician phone in settings.

G4 — AI Brain: keyword guardrail → LLM classifier → structured DB tool-use
(7 tools) → memory search → general parenting handler; ai_usage table;
22-case medical bypass safety test suite.

DB migrations: 0011_memories, 0012_medical_doses, 0013_ai_usage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 17:48:34 +05:30
c787caa821 fix: add Resend for password reset emails + install F1-F2 deps
- Wire Resend to /api/auth/reset-request with fallback for dev
- Install: sharp, recharts, next-pwa, resend, @react-pdf/renderer, @types/sharp

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:42:45 +05:30
c459b4411a fix: secure /api/ai endpoint and remove debug routes
- Add auth to /api/ai via requireFamily middleware
- Remove /api/ai and /api/auth/debug from public routes
- Delete debug/test routes that expose internal state

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:41:47 +05:30
797c970d81 Fix Quick Log save and diaper icon
- Fix handleSubmit to properly wait for API response before closing
- Change diaper icon from 🧷 to 👶
- Update activity scroller diaper icon

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:23:11 +05:30
9e258d74b4 Add activity scroller to home page
- Add time-based activity scroller showing lastFeed, lastSleep, lastDiaper times
- Scrolling marquee animation below vaccine reminders
- Fix diaper icon to 🧷
- Link baby profile card to growth page
- Add loading state for recent logs

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:15:20 +05:30
b10bfb0e2f docs: add growth page features to CLAUDE.md
Document the growth page components, state management, color codes, and layout order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:47:52 +05:30
7fc33a791c fix(growth): add form conditional on latest like goals
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:29:13 +05:30
52a46de86b fix(growth): move add form below latest, reorder layout
- Add form now appears between Latest Reading and WHO card
- Remove duplicate form below WHO card
- Similar pattern to Goals card

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:21:29 +05:30
f82fca224d style(growth): collapsible WHO+Chart, collapsed view with icons, collapsible history
- WHO card shows icons + values when collapsed (⚖️ 📏 )
- Chart is collapsible inside expanded WHO view
- History is collapsible with scroll for many records
- Add formatAge to history items

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:05:01 +05:30
a3d0b06501 fix(growth): show age in years+months format
- Show age as "1y 4mo" instead of just months
- Add formatAge helper function
- Apply to Latest Reading and WHO card

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 14:57:51 +05:30
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