100 Commits

Author SHA1 Message Date
Chelsea
215c3d7f95 fix yesterdays schedule blocking todays 2026-02-20 20:04:35 +00:00
fe07b3ebe7 Fix cross-midnight adaptive dose creating false missed reminders
When adaptive timing shifts a late-night dose past midnight (e.g. 23:00
→ 00:42), the scheduler would create a new pending schedule on the next
day even if the dose was already taken. The proximity window was too
narrow to match the take log against the shifted time.

- Skip creating schedules for doses already taken/skipped (checks
  today + yesterday logs against base_time)
- Fix midnight wraparound in proximity check for should_send_nag
- Display base_time (actual dose time) in reminders instead of the
  internal adjusted_time

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 07:58:45 -06:00
019561e7cd Fix bot routine scheduling field mismatch and add debug logging
Bot was sending days_of_week/times but API expects days/time, so
bot-scheduled routines never got reminders. Also handle NULL frequency
from pre-migration rows and add detailed logging to routine reminder
checks for diagnosing further issues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 00:21:22 -06:00
e89656a87c Fix adaptive medication timing and update README
- Fix double notifications: remove redundant check_medication_reminders()
  call, use adaptive path as primary with basic as fallback
- Fix nag firing immediately: require nag_interval minutes after scheduled
  dose time before first nag
- Fix missing schedules: create on-demand if midnight window was missed
- Fix wrong timezone: use user_now_for() instead of request-context
  user_now() in calculate_adjusted_times()
- Fix immutable schedules: recalculate pending schedules on wake event
  detection so adaptive timing actually adapts
- Fix take/skip not updating schedule: API endpoints now call
  mark_med_taken/skipped so nags stop after logging a dose
- Fix skipped doses still triggering reminders: check both taken and
  skipped in adaptive reminder and log queries
- Update README with tasks, AI step generation, auth refresh tokens,
  knowledge base improvements, and current architecture

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 23:34:38 -06:00
03da0b0156 Fix timezone mismatch in already-taken check 2026-02-19 20:51:44 -06:00
cf29d17183 Also suppress nags for skipped medications 2026-02-19 20:40:31 -06:00
cc1aace73d Fix presence tracking and med reminder bugs 2026-02-19 20:31:43 -06:00
a19e30db68 Fix medication reminders for already-taken meds
- Convert created_at from UTC to user's local timezone before comparing dates

- Add scheduled_time check in adaptive reminders (was only checking if any dose was taken today)

- Prevents duplicate reminders when user is in a different timezone than UTC
2026-02-19 20:12:22 -06:00
e9a2f96f91 Fix offset-naive/aware datetime error in nag checker
Make last_nag_at timezone-aware before subtracting from the tz-aware
current_time, and store future nag timestamps with timezone.utc to
prevent the mismatch recurring.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 19:43:32 -06:00
4c4ff5add3 Allow scheduling multiple medications at once, remove time conflicts
- Multi-med creation form: add any number of medication cards in one session, each with independent name/dosage/unit/frequency/times settings
- Submit button labels dynamically (Add 1 / Add N Medications)
- Removed all schedule conflict checking — medications can now coexist at the same time slot as each other and as routines

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 19:38:44 -06:00
33db2629e3 Add every-N-day frequency toggle to new routine page
The schedule editor on /dashboard/routines/new was missing the
Weekly/Every N Days toggle that was added to the edit page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 19:26:44 -06:00
ecb79af44e Fix bugs, add auto-refresh, quick-complete tasks, and every-N-day routines
- Fix bot auth: merge duplicate on_ready handlers so session restore runs (#13)
- Fix push notifications: pass Uint8Array directly as applicationServerKey (#6)
- Show specific conflict reason on schedule save instead of generic error (#17)
- Add inline checkmark button to complete tasks on routines timeline (#18)
- Add visibility-change + 60s polling auto-refresh to routines, meds, tasks (#15)
- Add every-N-day routine scheduling: schema, API, scheduler, and UI (#16)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 19:04:52 -06:00
24a1d18b25 Show tasks on the routines timeline
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 17:02:30 -06:00
d45929ddc0 Fix off-day med reminders and add medication editing
Scheduler: check_nagging() now calls _is_med_due_today() before creating
on-demand schedules or processing existing ones — prevents nagging
for specific_days / every_n_days meds on days they are not scheduled.

Web client: add Edit button (pencil icon) on each medication card linking
to /dashboard/medications/[id]/edit — new page pre-populates the full
form (name, dosage, unit, frequency, times, days, interval, notes)
and submits PUT /api/medications/:id on save.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 16:49:12 -06:00
bebc609091 Add one-off tasks/appointments feature
- DB: tasks table with scheduled_datetime, reminder_minutes_before, advance_notified, status
- API: CRUD routes GET/POST /api/tasks, PATCH/DELETE /api/tasks/<id>
- Scheduler: check_task_reminders() fires advance + at-time notifications, tracks advance_notified to prevent double-fire
- Bot: handle_task() with add/list/done/cancel/delete actions + datetime resolution helper
- AI: task interaction type + examples added to command_parser
- Web: task list page with overdue/notified color coding + new task form with datetime-local picker
- Nav: replaced Templates with Tasks in bottom nav

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 16:43:42 -06:00
2951382c51 Fix auth persistence: web client session timeout + bot cache loss
Web client: trustDevice now defaults to true so a refresh token is always
issued on login, preventing deauth after the 1-hour access token expiry.
Users can still uncheck the box on shared devices.

Bot: cache file path is now env-configurable (BOT_CACHE_FILE) and
defaults to /app/cache/user_cache.pkl. Docker Compose mounts a named
volume at /app/cache so the session cache survives container restarts.
saveCache() now creates the directory if it doesn't exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 16:32:07 -06:00
95ebae6766 Add AI task composition for routines (bot + web client)
Users can now describe a goal and have AI auto-generate 4-7 ADHD-friendly
steps, which they can review and modify before saving.

- ai/ai_config.json: Add step_generator prompt and ai_compose examples
  to command_parser so bot recognises vague task descriptions
- api/routes/ai.py: New POST /api/ai/generate-steps endpoint — calls
  LLM via ai_parser, validates and sanitises returned steps
- api/main.py: Register new ai_routes module
- bot/commands/routines.py: Add ai_compose action — generates steps,
  shows numbered list with durations, uses existing yes/no confirm flow
- synculous-client/src/lib/api.ts: Add api.ai.generateSteps(goal)
- synculous-client/src/app/dashboard/routines/new/page.tsx: Add
  Generate with AI panel with collapsible textarea, loading spinner,
  and inline error; generated steps slot into existing editable list

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 13:56:54 -06:00
9fb56edf74 Route general questions to knowledge base via LLM classification
The command parser was returning needs_clarification for advice/how-to
questions that didn't explicitly reference a book. Updated ai_config.json
to classify any question that isn't about meds or routines as a knowledge
query, added book hints for DBT vs ADHD, and added concrete examples
(e.g. "how do I do things I don't want to do?").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 13:25:13 -06:00
288e447d3e Fix nagging for doses not yet due — check scheduled time before nagging
should_send_nag() was iterating all pending schedules for today without
verifying the scheduled time had actually passed. A dose scheduled for
18:00 would get nagged at 13:15. Add an early return when current_time
is before the scheduled dose time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:17:51 -06:00
d2b074d39b Fix VARCHAR vs TIME type mismatch in med_logs queries (#15)
The medication_schedules.adjusted_time column is a TIME type, but
med_logs.scheduled_time is VARCHAR. When adjusted_time values were
passed into queries against med_logs, PostgreSQL rejected the
comparison. Add _normalize_time() to convert datetime.time objects
to "HH:MM" strings at the entry points of should_send_nag,
record_nag_sent, and mark_med_taken.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:14:20 -06:00
d4adbde3df Fix issues #6, #7, #11, #12, #13: med reminders, push notifications, auth persistence, scheduling conflicts
- Fix TIME object vs string comparison in scheduler preventing adaptive med
  reminders from ever firing (#12, #6)
- Add frequency filtering to midnight schedule creation for every_n_days meds
- Require start_date and interval_days for every_n_days medications
- Add refresh token support (30-day) to API and bot for persistent sessions (#13)
- Add "trusted device" checkbox to frontend login for long-lived sessions (#7)
- Auto-refresh expired tokens in both bot (apiRequest) and frontend (api.ts)
- Restore bot sessions from cache on restart using refresh tokens
- Duration-aware routine scheduling conflict detection (#11)
- Add conflict check when starting routine sessions against medication times
- Add diagnostic logging to notification delivery channels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:05:48 -06:00
6850abf7d2 fix partial-update overwrite bug in snitch and adaptive meds PUT handlers
Both handlers were building update_data with defaults for every field,
so a partial save (e.g. toggling one toggle) would silently reset all
other settings back to their defaults. Now only fields explicitly
present in the request body are written to the DB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-17 19:05:09 -06:00
f826e511d5 fixing snitch and adaptive medication timing persistance and logic 2026-02-17 18:52:35 -06:00
cf2b4be033 med scheduling fixes 2026-02-17 18:33:43 -06:00
8ac7a5129a fixed spamming i hope 2026-02-17 18:11:44 -06:00
80ebecf0b1 Changes Made
1. config/schema.sql — Added timezone_name VARCHAR(100) to user_preferences table + an ALTER TABLE migration at the bottom for existing DBs.
  2. core/tz.py — Rewrote with dual-path timezone support:
  - Request context: _get_request_tz() now checks X-Timezone-Name header (IANA) first, falls back to X-Timezone-Offset
  - Background jobs: New tz_for_user(user_uuid) and user_now_for(user_uuid) read stored timezone_name from prefs, fall back to numeric offset, then UTC
  - All existing function signatures (user_now(), user_today()) preserved for backward compat

  3. scheduler/daemon.py — Fixed 3 bugs:
  - _user_now_for() now delegates to tz.user_now_for() which uses IANA timezone names (DST-safe)
  - check_nagging() — replaced datetime.utcnow() with _user_now_for(user_uuid) so nags evaluate in user's timezone
  - poll_callback() — replaced single UTC midnight check with _check_per_user_midnight_schedules() that iterates users and creates daily schedules at their local midnight

  4. api/routes/preferences.py — Added "timezone_name" to allowed PUT fields.

  5. synculous-client/src/lib/api.ts — Added X-Timezone-Name header to every request + added timezone_name to preferences update type.

  6. synculous-client/src/app/dashboard/layout.tsx — Now syncs both timezone_offset and timezone_name (via Intl.DateTimeFormat().resolvedOptions().timeZone) on session start.
2026-02-17 18:02:07 -06:00
0e28e1ac9d logo update from ai logo to human made 2026-02-17 16:43:23 -06:00
ac27a9fb69 you can pick your friends but you shouldnt pick your skin 2026-02-17 03:39:43 -06:00
d673d73530 opus pass 2 2026-02-17 00:30:05 -06:00
123a7ce3e7 claude bugpass 2026-02-17 00:20:06 -06:00
Chelsea
3d3b80fe96 partial 2026-02-17 05:46:59 +00:00
Chelsea
596467628f feat: add Discord presence status indicator in settings
Add a visual status indicator showing:
- Online/offline status with colored dot indicator
- Last seen timestamp
- Typical wake time (if available)

The indicator now displays whenever Discord notifications are enabled,
not just when presence tracking is active.
2026-02-17 04:37:13 +00:00
Chelsea
a0126d0aba fix: include adaptive_mode when enabling adaptive timing toggle
The API requires adaptive_mode when adaptive_timing_enabled is true,
but the frontend was only sending the enabled flag. This caused 400
errors when users tried to toggle adaptive timing on.

Now the toggle sends both fields when enabling, satisfying the API
validation requirements.
2026-02-17 04:35:55 +00:00
Chelsea
a2c7940a5c Fix issues #8, #9, #10, #11: scheduling conflicts, med reminders, adaptive timing, nagging
- #11: Add validation to prevent simultaneous scheduling of routines and medications
  - Added _check_schedule_conflicts() in routines.py
  - Added _check_med_schedule_conflicts() in medications.py
  - Returns HTTP 409 with descriptive error on conflict

- #10: Fix medication reminders not being sent
  - Added call to check_adaptive_medication_reminders() in daemon poll loop

- #9: Fix can't enable adaptive timing
  - Added proper error handling and logging in update_adaptive_settings()
  - Returns meaningful error message on database failures

- #8: Fix nagging not working
  - Added debug logging for missing settings
  - Auto-create medication schedules if they don't exist
  - Improved error logging (warning -> error)
2026-02-17 04:20:34 +00:00
3aad7a4867 Fix snitch test to actually insert a log entry that the bot will send 2026-02-16 21:20:25 -06:00
98706702da Fix snitch test to not send to wrong user, implement Discord DM sending for snitches 2026-02-16 21:16:33 -06:00
1d79516794 Temporarily disable adaptive medication check until database migration is run 2026-02-16 21:09:05 -06:00
f740fe8be2 Add fallback to original medication reminders when adaptive tables don't exist 2026-02-16 21:02:34 -06:00
6e875186b4 Fix datetime import and add database migration script 2026-02-16 20:21:07 -06:00
35f51e6d27 Add complete snitch system UI to settings page with contact management and consent flow 2026-02-16 20:16:29 -06:00
a6ae4e13fd Add complete snitch feature with contact management, consent system, and notification delivery 2026-02-16 20:14:03 -06:00
69163a37d1 Add complete UI for adaptive medication settings with presence tracking and nagging configuration 2026-02-16 20:04:58 -06:00
84c6032dc9 Register adaptive medication API routes 2026-02-16 20:01:27 -06:00
d4fb41ae6b Add adaptive medication timing, Discord presence tracking, and nagging system 2026-02-16 20:00:53 -06:00
1ed187b0dd Properly merge original Discord bot with JurySystem DBT integration 2026-02-16 19:29:35 -06:00
2feaf0cdc0 Convert JurySystem to Discord bot 2026-02-16 19:26:16 -06:00
09d453017c Update embedding file path in config 2026-02-16 19:22:58 -06:00
833800842a Add config.json for JurySystem with OpenRouter API key 2026-02-16 19:20:40 -06:00
e4e6ad44ac Fix datetime comparison error in victories API 2026-02-16 19:14:36 -06:00
c7be19611a Merge branch 'main' of https://git.scorpi.us/chelsea/Synculous-2 2026-02-16 19:08:19 -06:00