A tool that plans your week across multiple interests without burning out — built as a learning project pairing each feature with an AI engineering concept.
backend/ FastAPI — all the AI logic lives here
frontend/ Next.js — the daily-use interface
cd backend
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .envFill in .env:
ANTHROPIC_API_KEY— from https://console.anthropic.comTODOIST_API_TOKEN— Todoist → Settings → Integrations → Developer → API tokenGOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET— create an OAuth 2.0 Client ID (type: Web application) at https://console.cloud.google.com/apis/credentials, after enabling the "Google Calendar API" for the project. Addhttp://localhost:8000/auth/google/callbackas an authorized redirect URI.
Run it:
uvicorn main:app --reload --port 8000Then, once, visit http://localhost:8000/auth/google/login in your browser to
connect your calendar (one-time consent flow; token is cached in token.json).
Docs / try endpoints interactively: http://localhost:8000/docs
cd frontend
npm install
npm run devVisit http://localhost:3000. It talks to the backend at the URL set in
.env.local (NEXT_PUBLIC_API_BASE, defaults to http://localhost:8000).
POST /api/plan— takes your interests, weekly time budget, energy notes, and optional feedback from last week, returns a structured weekly plan (not free text) using Anthropic's tool-use forced structured output.GET /api/todoist/tasks— pulls your current Todoist tasks (not yet wired into the plan prompt — that's a good next step).GET /api/calendar/events— pulls upcoming calendar events (also not yet wired into the prompt).POST /api/plan/push-to-todoist— writes a generated plan back into Todoist as tasks with due dates.GET /api/plan/wallpaper— renders the most recently generated plan as a bird's-eye PNG (7-day grid, colored by interest area) sized for a phone lock screen. 404s untilPOST /api/planhas run at least once (the plan is cached tobackend/data/latest_plan.json, gitignored). Meant to be polled by a device-side automation rather than the frontend — on Android, a Tasker profile ("HTTP Request" → save PNG → "Set Wallpaper", scoped to the lock screen) is the simplest way to keep it fresh without a native app.
- Structured output via forced tool-use (
app/services/planner.py) - System prompt design encoding actual reasoning (pacing, variety, burnout awareness) instead of a bare instruction
- Separating the LLM call, the data schema, and the API layer
- Real OAuth (Google) vs simple token auth (Todoist) — different auth patterns you'll hit constantly in real integrations
- Wire Todoist tasks + Calendar events into the
_build_user_messageprompt inplanner.pyso plans respect what's already committed. - Add few-shot examples of "good" vs "bad" plans to the system prompt.
- Store generated plans + user feedback somewhere (start with a flat JSON file, no need for a database yet) — this becomes your eval dataset.
- Build a small eval script: given a plan + feedback, score it (rule-based first, then try an AI-as-judge prompt) for variety/pacing/burnout risk.