diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000..9942493 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,152 @@ +# CLAUDE.md - UMBRA + +## CRUCIAL CONTEXT EFFICIENCY + +### Subagent Discipline +- Prefer inline work for tasks under ~5 tool calls. Subagents have overhead — don't delegate trivially. +- When using subagents, include output rules: "Final response under 2000 characters. List outcomes, not process." +- Never call TaskOutput twice for the same subagent. If it times out, increase the timeout — don't re-read. + +### File Reading +- Read files with purpose. Before reading a file, know what you're looking for. +- Use Grep to locate relevant sections before reading entire large files. +- Never re-read a file you've already read in this session. +- For files over 500 lines, use offset/limit to read only the relevant section. + +### Responses +- Don't echo back file contents you just read — the user can see them. +- Don't narrate tool calls ("Let me read the file..." / "Now I'll edit..."). Just do it. +- Keep explanations proportional to complexity. Simple changes need one sentence, not three paragraphs. + +## Deployment & Access + +- **UMBRA is hosted on a remote machine** at `http://10.0.69.35` (not localhost). +- **Login PIN:** `1993` +- **Rebuilds are manual.** Do not run `docker-compose` commands — the user will rebuild on the remote machine when needed. +- **Browser automation** can access the live app at `http://10.0.69.35`. + +## Operational Procedures + +- Before making any changes or edits to code, create a branch. Once work is completed, commit and push to the branch automatically, then merge into main and push. +- When required: For backend work invoke the 'backend-engineer' subagent, for work on the front end, invoke the 'frontend-engineer' subagent. To review work use the 'senior-code-reviewer' subagent and for any research use the 'research-analyst' subagent. +- For any frontend UI related work you MUST use the frontend design skill AND reference the [stylesheet](.claude/context/stylesheet.md) to ensure visual consistency. The stylesheet defines all colors, typography, spacing, component patterns, and design principles for UMBRA. Do not invent new patterns. + +## Known Issues + +- **Git push auth flake.** The first `git push` to the Gitea remote will fail with an authentication error. Simply retry the same push command — the second attempt succeeds. + +## Hard Rules + +- **Naive datetimes only.** The DB uses `TIMESTAMP WITHOUT TIME ZONE`. Never send timezone-aware strings (no `Z` suffix, no `.toISOString()`). Use local datetime formatting helpers instead. +- **Eager load relationships in async SQLAlchemy.** Any `response_model` that includes a relationship (e.g. `ProjectResponse.tasks`) must use `selectinload()` when querying. Lazy loading raises `MissingGreenlet` in async context. +- **Never shadow SQLAlchemy names.** Model columns must not be named `relationship`, `column`, `metadata`, or other SQLAlchemy reserved names. The `person.py` model aliases the import as `sa_relationship` for this reason. +- **Frontend date inputs require exact formats.** `` needs `YYYY-MM-DD`, `` needs `YYYY-MM-DDThh:mm`. Backend may return `2026-02-15T00:00:00` which must be sliced/converted before binding. +- **All API routes are prefixed with `/api`.** Frontend axios base URL is `/api`. Nginx proxies `/api/` to backend:8000. Never duplicate the prefix. + +## Tech Stack + +### Backend +- **Python 3.12** (slim Docker image - no curl, use `urllib` for healthchecks) +- **FastAPI** with async lifespan, Pydantic v2 (`model_dump()`, `ConfigDict(from_attributes=True)`) +- **SQLAlchemy 2.0** async with `Mapped[]` type hints, `mapped_column()`, `async_sessionmaker` +- **PostgreSQL 16** (Alpine) via `asyncpg` +- **Alembic** for migrations +- **Auth:** PIN-based with bcrypt + itsdangerous signed cookies (not JWT) + +### Frontend +- **React 18** + TypeScript + Vite 6 +- **TanStack Query v5** for server state (`useQuery`, `useMutation`, `invalidateQueries`) +- **FullCalendar 6** (dayGrid, timeGrid, interaction plugins) +- **Tailwind CSS 3** with custom dark theme + accent color CSS variables +- **Sonner** for toast notifications +- **Lucide React** for icons +- Custom shadcn/ui-style components in `frontend/src/components/ui/` + +### Infrastructure +- **Docker Compose** - 3 services: `db`, `backend`, `frontend` +- **Nginx** (Alpine) serves frontend SPA, proxies `/api/` to backend +- Frontend served on port **80**, backend on port **8000** + +## Authority Links + +- [ui_refresh.md](.claude/projects/ui_refresh.md) - UI overhaul project plan, audit findings, implementation stages +- [stylesheet.md](.claude/context/stylesheet.md) - Design system & visual reference for all frontend work + +## Project Structure + +``` +backend/app/ + main.py # FastAPI app, router registration, health endpoint + config.py # Pydantic BaseSettings (DATABASE_URL, SECRET_KEY) + database.py # Async engine, session factory, get_db dependency + models/ # SQLAlchemy 2.0 models (Mapped[] style) + schemas/ # Pydantic v2 request/response schemas + routers/ # One router per feature (auth, todos, events, etc.) + +frontend/src/ + App.tsx # Routes + ProtectedRoute wrapper + lib/api.ts # Axios instance + getErrorMessage helper + hooks/ # useAuth, useSettings, useTheme, useCalendars + types/index.ts # TypeScript interfaces matching backend schemas + components/ + ui/ # 16 base components (Button, Dialog, Sheet, Card, Input, Select, etc.) + layout/ # AppLayout + Sidebar + auth/ # LockScreen (PIN setup/login) + dashboard/ # DashboardPage + widgets (Stats, Calendar, Todo, Upcoming, Countdown, etc.) + calendar/ # CalendarPage, CalendarSidebar, CalendarForm, EventForm, TemplateForm + todos/ # TodosPage + TodoList + TodoItem + TodoForm + reminders/ # RemindersPage + ReminderList + ReminderForm + projects/ # ProjectsPage, ProjectCard, ProjectDetail, ProjectForm, KanbanBoard, TaskRow, TaskForm, TaskDetailPanel + people/ # PeoplePage + PersonCard + PersonForm + locations/ # LocationsPage + LocationCard + LocationForm + settings/ # SettingsPage (accent color, PIN change, first day of week) +``` + +## Essential Commands + +```bash +# Build and run all services +docker-compose up --build + +# Rebuild single service after changes +docker-compose up --build backend +docker-compose up --build frontend + +# View logs +docker-compose logs -f +docker-compose logs -f backend + +# Reset database (destroys all data) +docker-compose down -v && docker-compose up --build + +# Stop everything +docker-compose down +``` + +## API Routes + +All routes require auth (signed cookie) except `/api/auth/*` and `/health`. + +| Prefix | Resource | +|----------------------|-----------------| +| `/api/auth` | PIN setup/login/logout/status | +| `/api/todos` | Todos CRUD + toggle | +| `/api/events` | Calendar events CRUD (incl. recurring) | +| `/api/event-templates` | Event templates CRUD | +| `/api/calendars` | User calendars CRUD + visibility | +| `/api/reminders` | Reminders CRUD + dismiss | +| `/api/projects` | Projects + nested tasks CRUD | +| `/api/people` | People CRUD | +| `/api/locations` | Locations CRUD + search | +| `/api/settings` | Settings + PIN change | +| `/api/dashboard` | Dashboard aggregation | +| `/api/upcoming` | Unified upcoming items | +| `/api/weather` | Weather data proxy | + +## Stop Conditions + +- **Do not** add timezone info to datetime strings sent to the backend +- **Do not** use `datetime.utcnow()` - use `datetime.now(timezone.utc)` instead (deprecated in 3.12) +- **Do not** return relationships from async endpoints without `selectinload()` +- **Do not** use `curl` in backend Docker healthchecks (not available in python:slim) +- **Do not** use `git push --force` or destructive git operations without explicit approval diff --git a/.claude/projects/ui_refresh.md b/.claude/projects/ui_refresh.md new file mode 100644 index 0000000..23c1d0a --- /dev/null +++ b/.claude/projects/ui_refresh.md @@ -0,0 +1,263 @@ +# UMBRA UI Refresh — Planning Document + +## Current UI Audit (2026-02-20) + +### Global Observations +- **Theme:** Dark background (~#0a0a0a), dark card surfaces (~#1a1a2e), blue/cyan accent +- **Sidebar:** Fixed left ~200px, solid blue highlight on active item, Lucide icons + labels, collapse chevron +- **Typography:** System sans-serif, white headings, muted gray subtext — functional but lacks personality +- **Cards:** Rounded borders with subtle gray stroke, no shadows, no hover effects, no transitions +- **Layout:** Full-width content area with no max-width constraint — cards stretch awkwardly on wide displays +- **Action buttons:** Consistent "+ Add X" blue filled buttons top-right on every page — good pattern +- **Empty states:** Centered icon + message — functional but lifeless +- **Scrollbars:** Default browser scrollbars — clash with dark theme + +### Page-by-Page Notes + +#### Login +- Centered dark card, lock icon, PIN input, blue "Unlock" button +- Clean and minimal — works well structurally +- Missing UMBRA branding/identity — feels like a generic auth screen +- No ambient atmosphere (no gradients, no glow, no texture) + +#### Dashboard +- 4 stat cards across top (Total Projects, In Progress, People, Locations) with colored Lucide icons +- "Upcoming (7 days)" section — flat list of events with "Event" badge right-aligned +- Bottom row: "Upcoming Todos" + "Today's Events" side by side +- **Issues:** + - Stat cards are flat rectangles with label/number/icon — no visual weight or hierarchy + - Icon colors (purple, purple, green, orange) feel arbitrary — no semantic meaning + - Upcoming list wastes horizontal space — event name far left, badge far right, nothing in between + - Bottom widgets have massive empty space when few/no items + - No week summary or schedule preview — missed opportunity for at-a-glance context + - "Welcome back. Here's your overview." is generic placeholder text + - No time-of-day awareness or contextual greeting + +#### Todos +- Search bar + "All Priorities" dropdown + category filter + "Show completed" checkbox +- All controls on single line — functional but cramped and visually flat +- Empty state: centered checkbox icon + message +- **Issues:** Filter controls are unstyled native elements mixed with custom — inconsistent + +#### Calendar (Month) +- FullCalendar month view with colored event dots/pills +- Color coding: blue (default), purple, green (multi-day), orange, yellow +- **Issues:** + - Prev/next navigation arrows are tiny unstyled squares (~16px) — nearly invisible + - "today" button is plain text with no visual emphasis + - Event text truncates on small cells with no tooltip or expand affordance + - Multi-day events (green/orange bars) visually dominate and obscure day cells + - No visual distinction for today's date in month grid + +#### Calendar (Week) +- Time grid with events as colored blocks — time + title visible +- Today column has yellowish-brown tint overlay +- **Issues:** + - The "today" tint is murky (#8B8000-ish overlay) — looks dirty rather than highlighted + - Past-time columns also have this tint, making it confusing + - No current-time indicator line + +#### Calendar (Day) +- Full-day column with same murky brown-yellow background +- **Issues:** When empty, entire content area is just a brown column — unappealing + - No visual distinction between past hours and future hours + +#### Reminders +- Tab bar: Active / Dismissed / All — clean blue active state +- Empty state similar to Todos +- Very sparse — large empty space below tabs + +#### Projects +- 3-column card grid +- Each card: ALL-CAPS name, status badge pill, "Progress" label with thin bar, task count, calendar icon + due date +- **Issues:** + - ALL-CAPS names are aggressive and hard to scan + - Status badges ("not started" / "in progress") are small outlined pills — low contrast + - Progress bars are extremely thin (~2px) and low-contrast against dark surface + - "Progress" label + "0/3 tasks" on same line wastes vertical space + - Cards have uneven internal spacing — description shows on some, not others + - No hover state or click affordance — cards don't feel interactive + +#### People +- 3-column card grid +- Each card: name, category badge (Friends = blue, Work = gray), birthday, edit/delete icons top-right +- **Issues:** + - Cards feel sparse — just 3 lines of info in a large rectangle + - No avatar placeholder — missed opportunity for visual anchoring + - Edit (pencil) and delete (trash) icons are small and far from the name + - Category badge colors don't match Locations page (Work = gray here, purple there) + +#### Locations +- 3-column card grid with location pin icon beside name +- Category badges: home = blue, work = purple +- Address shown as subtitle +- **Issues:** Badge color system inconsistent with People page + +#### Settings +- Three stacked sections: Appearance, Dashboard, Security +- Left-aligned at ~50% width, entire right half is empty +- Accent color picker: 5 colored circles (cyan, blue, purple, orange, green) +- **Issues:** + - Massive dead space on right — feels incomplete + - Color circles have no labels or tooltips + - Sections could use visual separation beyond just spacing + +--- + +## Design Critique (Frontend Design Review) + +### 1. Surface & Depth — "Everything lives on the same plane" +The biggest visual issue is that every element — cards, sidebar, content area, stat widgets — exists at the same depth. There are no shadows, no layering, no elevation changes. Modern dark UIs use subtle elevation to create hierarchy: +- Cards should float slightly above the background with soft box-shadows (`0 1px 3px rgba(0,0,0,0.3)`) +- The sidebar should feel like a separate layer with a subtle border or shadow on its right edge +- Hover states should lift cards slightly (`translateY(-1px)` + shadow increase) +- Active/selected states should have a gentle inner glow or border luminance shift + +### 2. Typography — "Functional but forgettable" +The current type system is plain system sans-serif with two weights (bold headings, normal body). For a personal life manager named "UMBRA," typography should reinforce brand identity: +- Consider a distinctive heading font (geometric sans like Outfit, Sora, or General Sans) +- Body text needs slightly more line-height for readability on dark backgrounds (1.6 minimum) +- The ALL-CAPS project names are too aggressive — use sentence case with semibold weight instead +- Stat card numbers should be larger and use tabular figures for alignment +- Muted text (#6b7280-range) is too low-contrast on dark backgrounds — bump to #9ca3af minimum + +### 3. Color System — "Arbitrary accents without semantic meaning" +Colors are applied without a clear system: +- Stat card icons use purple/purple/green/orange — why purple twice? No semantic connection +- Category badges are inconsistent: Work is gray on People, purple on Locations +- The calendar today overlay (#8B8000-ish) clashes with the cool-toned theme +- **Recommendation:** Establish a semantic color palette: + - Accent (cyan/blue): interactive elements, active states, links + - Success (emerald): completed, on-track + - Warning (amber): upcoming, due soon + - Danger (rose): overdue, delete + - Neutral (slate): secondary text, borders, disabled + - Category colors should be consistent app-wide (same color for "Work" everywhere) + +### 4. Spacing & Density — "Too much air, not enough content" +- Dashboard stat cards have generous internal padding but minimal content — lots of dead space +- The Upcoming list is a single-column spanning the full width with text far-left and badge far-right +- Settings page uses only half the viewport width +- Cards on People/Locations show 3 lines of info in ~150px tall containers +- **Recommendation:** Use a tighter grid system. Dashboard should use a 2-column or asymmetric layout below stats. Cards should breathe but not float in empty space. Consider max-width containers (1200-1400px). + +### 5. Interactivity — "Static pages, not a living app" +Zero motion, zero feedback: +- No hover states on any cards or interactive elements +- No transitions on page changes +- No loading states or skeleton screens +- No micro-interactions (checkbox toggle, card expand, badge pulse) +- Scrollbars are default browser chrome — jarring in dark theme +- **Recommendation:** Add CSS transitions on all interactive elements (150-200ms ease). Custom scrollbar styling with `scrollbar-color` and `::-webkit-scrollbar`. Subtle scale/shadow on card hover. + +### 6. Dashboard Specific — "A bulletin board, not a command center" +The dashboard is the first thing you see and it should feel alive: +- Missing: week-at-a-glance schedule/timeline +- Missing: contextual greeting (time of day + name) +- Missing: quick actions or shortcuts +- Stat cards don't link context — "5 Projects" but which ones matter right now? +- Bottom widgets (Upcoming Todos / Today's Events) are equal-width but Today's Events is more urgent +- **Recommendation:** Redesign dashboard as a "morning briefing" — today's schedule, this week's priorities, active project progress, quick-add shortcuts + +### 7. Component Quality — "Default HTML with Tailwind" +Several components feel like unstyled defaults: +- Calendar nav arrows are default FullCalendar squares — need custom styled buttons +- Filter dropdowns on Todos look like native `