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>
Synculous
A routine and medication management app designed as a prosthetic for executive function. Built for people with ADHD.
The app externalizes the things ADHD impairs — time awareness, sequence memory, task initiation, and emotional regulation around failure — into a guided, sequential interface with immediate feedback and zero shame.
Architecture
synculous/
├── synculous-client/ # Next.js 16 frontend (React, Tailwind)
├── api/ # Flask REST API
│ ├── main.py # App entry point, auth routes
│ └── routes/ # Domain route modules
│ ├── routines.py # Routines CRUD + sessions
│ ├── routine_sessions_extended.py # Pause, resume, abort, notes
│ ├── routine_stats.py # Completion stats, streaks, weekly summary
│ ├── routine_templates.py # Premade routine templates
│ ├── routine_steps_extended.py # Step instructions, types, media
│ ├── routine_tags.py # Tagging system
│ ├── medications.py # Medication scheduling + adherence
│ ├── preferences.py # User settings + timezone
│ ├── notifications.py # Web push subscriptions
│ ├── rewards.py # Variable reward system
│ └── victories.py # Achievement detection
├── core/ # Shared business logic
│ ├── postgres.py # Generic PostgreSQL CRUD
│ ├── auth.py # JWT + bcrypt authentication
│ ├── users.py # User management
│ ├── routines.py # Routine/session/streak logic
│ ├── tz.py # Timezone-aware date/time helpers
│ └── notifications.py # Multi-channel notifications
├── scheduler/
│ └── daemon.py # Background polling for reminders
├── bot/ # Discord bot (optional)
├── ai/ # LLM parser for natural language commands
├── config/
│ ├── schema.sql # Database schema
│ ├── seed_templates.sql # 12 premade ADHD-designed routine templates
│ ├── seed_rewards.sql # Variable reward pool
│ └── .env.example # Environment template
├── docker-compose.yml
└── Dockerfile
Quick Start
# Copy environment config
cp config/.env.example config/.env
# Edit with your values
nano config/.env
# Start everything
docker-compose up
This starts five services:
| Service | Port | Description |
|---|---|---|
db |
5432 | PostgreSQL 16 with schema + seed data |
app |
8080 | Flask API |
scheduler |
— | Background daemon for medication/routine reminders |
bot |
— | Discord bot (optional, needs DISCORD_BOT_TOKEN) |
client |
3000 | Next.js frontend |
Features
Routines
- Create routines with ordered steps (4-7 steps recommended)
- Run sessions with a guided, one-step-at-a-time focus interface
- Complete, skip, pause, resume, or cancel sessions
- Swipe gestures for step completion on mobile
- Per-step timing with visual countdown
- Animated celebration screen on completion with streak stats and variable rewards
Premade Templates
12 ADHD-designed templates ship out of the box, seeded from config/seed_templates.sql:
| Template | What it's for |
|---|---|
| Morning Launch | Getting from bed to ready. First step: just sit up. |
| Leaving the House | The keys-wallet-phone checklist. |
| Focus Sprint | One focused work block with environment setup first. |
| Wind Down | Screen-first sleep transition. |
| Quick Tidy | Fast sweep, not deep cleaning. Completable on bad days. |
| Body Reset | Minimum viable hygiene. Zero judgment. |
| Unstuck | For executive function paralysis. Pure two-minute-rule. |
| Evening Reset | Set tomorrow up to be easier. |
| Move Your Body | Not a workout. Just movement. Starts with shoes. |
| Sunday Reset | Weekly prep so Monday doesn't ambush you. |
| Cook a Meal | One meal, start to finish, low activation energy. |
| Errand Run | Externalized planning + sequencing for errands. |
All templates follow the design framework: two-minute-rule entry points, concrete instructions, zero-shame language, 4-6 steps max.
Medications
- Scheduling: daily, twice daily, specific days, every N days, as-needed (PRN)
- "Today's meds" view with cross-midnight lookahead (late night + early morning)
- Take, skip, snooze actions with logging
- Adherence tracking and statistics
- Refill tracking with low-quantity alerts
- Background reminders via the scheduler daemon
Streaks and Stats
- Per-routine streak tracking (current + longest)
- Weekly summary across all routines
- Completion rate and average duration stats
- Victory detection (comebacks, weekend completions, variety, consistency)
- Milestone celebrations at 3, 7, 14, 21, 30, 60, 90, 100, 365 days
Rewards
- Variable reward pool seeded from
config/seed_rewards.sql - Random reward on routine completion (post-completion only, never mid-routine)
- Reward history tracking per user
- Common and rare rarity tiers
Notifications
- Web push notifications via VAPID
- Discord webhooks
- ntfy support
- Scheduled reminders for medications and routines
Timezone Support
All date/time operations respect the user's local timezone:
- The frontend sends
X-Timezone-Offsetwith every API request - The timezone offset is also persisted to
user_preferencesfor background jobs - Streaks, "today's meds," weekly stats, and reminders all use the user's local date
- The scheduler daemon looks up each user's stored offset for reminder timing
User Preferences
- Sound effects (default off — habituation risk)
- Haptic feedback (default on)
- Launch screen toggle
- Celebration style
- Timezone offset (auto-synced from browser)
API Overview
All endpoints require Authorization: Bearer <token> except /api/register and /api/login.
Auth
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/register |
Create account |
| POST | /api/login |
Get JWT token |
Routines
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/routines |
List user's routines |
| POST | /api/routines |
Create a routine |
| GET | /api/routines/:id |
Get routine with steps |
| PUT | /api/routines/:id |
Update routine |
| DELETE | /api/routines/:id |
Delete routine |
| GET | /api/routines/:id/steps |
List steps |
| POST | /api/routines/:id/steps |
Add a step |
| PUT | /api/routines/:id/steps/reorder |
Reorder steps |
| POST | /api/routines/:id/start |
Start a session |
Sessions
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/sessions/active |
Get active or paused session |
| POST | /api/sessions/:id/complete-step |
Complete current step |
| POST | /api/sessions/:id/skip-step |
Skip current step |
| POST | /api/sessions/:id/pause |
Pause session |
| POST | /api/sessions/:id/resume |
Resume session |
| POST | /api/sessions/:id/cancel |
Cancel session |
| POST | /api/sessions/:id/abort |
Abort with reason |
Medications
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/medications |
List medications |
| POST | /api/medications |
Add medication |
| GET | /api/medications/today |
Today's schedule with status |
| POST | /api/medications/:id/take |
Log dose taken |
| POST | /api/medications/:id/skip |
Log dose skipped |
| GET | /api/medications/adherence |
Adherence stats |
| GET | /api/medications/refills-due |
Refills due soon |
Stats
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/routines/:id/stats |
Routine completion stats |
| GET | /api/routines/:id/streak |
Routine streak |
| GET | /api/routines/streaks |
All streaks |
| GET | /api/routines/weekly-summary |
Weekly progress |
| GET | /api/victories |
Achievement detection |
Templates, Tags, Rewards, Preferences
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/templates |
List available templates |
| POST | /api/templates/:id/clone |
Clone template to user's routines |
| GET/PUT | /api/preferences |
User settings |
| GET | /api/rewards/random |
Random completion reward |
Environment Variables
| Variable | Description |
|---|---|
DB_HOST |
PostgreSQL host |
DB_PORT |
PostgreSQL port |
DB_NAME |
Database name |
DB_USER |
Database user |
DB_PASS |
Database password |
JWT_SECRET |
JWT signing secret |
DISCORD_BOT_TOKEN |
Discord bot token (optional) |
API_URL |
API URL for bot (default: http://app:5000) |
OPENROUTER_API_KEY |
OpenRouter API key (for AI parser) |
POLL_INTERVAL |
Scheduler poll interval in seconds (default: 60) |
Design Framework
Synculous follows a documented design framework based on research from 9 books on behavior design, cognitive psychology, and ADHD. The three core principles:
- Immediate Feedback — Visual state change on tap in <0.1s. Per-step completion signals. Post-routine celebration.
- One Thing at a Time — Current step visually dominant. No decisions during execution. 4-7 steps max per routine.
- Zero Shame — No failure language. Streaks as identity markers, not performance metrics. Non-punitive everywhere.
License
MIT