Files

7.1 KiB

PROJECT BABY MONITOR

OVERVIEW

Baby monitor - self-hosted web app for tracking infant sleep. Dual-stack monorepo: React 19/Vite 6/TypeScript frontend + Python 3.14/FastAPI backend. Optimized for Raspberry Pi 4 (ARM64).

STRUCTURE

./
├── frontend/           # React 19 SPA
│   ├── src/
│   │   ├── api/      # React Query hooks
│   │   ├── components/
│   │   │   ├── stats/   # Charts, grids, trends (8 files - highest density)
│   │   │   └── tracker/ # Sleep session controls
│   │   ├── hooks/    # Custom React hooks
│   │   ├── types/    # TypeScript interfaces
│   │   └── utils/
│   └── tests/         # e2e (Playwright), unit (Vitest)
├── backend/           # FastAPI + SQLModel
│   ├── scripts/       # one-off scripts for migrations / fixes / etc
│   ├── app/
│   │   ├── routers/   # API endpoints
│   │   └── utils/
│   └── tests/        # pytest + asyncio
└── docker-compose.yml

WHERE TO LOOK

Task Location Notes
Add sleep session backend/app/crud.py create_session, update_session
Fetch sleep data frontend/src/api/ React Query hooks for sessions
UI components frontend/src/components/ tracker/, stats/ subdirs
Backend models backend/app/models.py SQLModel definitions
API schemas backend/app/schemas.py Pydantic request/response
Settings / env vars backend/app/config.py Pydantic-settings, reads .env
Database init backend/app/database.py Engine setup, init_db()
Timezone logic backend/app/utils/time_utils.py Historical bug source — handle with care

CONVENTIONS

  • Backend: SQLModel (not pure SQLAlchemy), async aiosqlite, pytest-asyncio.
  • Frontend: React 19, TanStack Query v5, Tailwind v4, no ESLint config (yet).
  • Python: >=3.14 required. Managed via uv with Hatch backend for packaging.
  • Scripts: All scripts created in the backend folder must be placed explicitly in backend/scripts/.
  • CI/CD: Deployment is managed via Gitea workflows (.gitea/ directory). Do not create .github/ directories or Makefiles.

ANTI-PATTERNS (CRITICAL GUARDRAILS)

  • Type Safety: No type suppression (as any, @ts-ignore, @ts-expect-error). Type safety is strictly enforced.
  • Error Handling: No empty catch blocks. Explicit error handling/logging is required.
  • Testing Integrity: NEVER delete or comment out failing tests to make a suite "pass". Fix the code or update the test properly.
  • Frontend JS Slop: NEVER create .js or .jsx files for the frontend. Use only TypeScript (.ts, .tsx). Write clean, type-safe code.
  • Assumption Error: NEVER assume the content of ANY files. ALWAYS read the target file to confirm its structure and implementation before modifying or referencing it.

MANDATORY EXECUTION PROTOCOLS (INJECTABLE)

The following protocols must be strictly adhered to upon injection:

  • Read Before Edit: ALWAYS read the entire target file before performing any edit operation.
  • Post-Edit Verification: Immediately after an edit, verify that no lines have been duplicated.
  • Stability Check: Following any code change, run both backend and frontend services AND the full test suite to ensure system stability.

COMMANDS

Backend Development

cd backend
uv sync
uv run uvicorn app.main:app --reload   # runs on http://localhost:8000

# Run all tests
uv run pytest

# Run a specific test file (preferred during debugging)
uv run pytest tests/test_stats.py -v

Frontend Development

cd frontend
npm install
npm run dev    # runs on http://localhost:5173

# Unit tests (Vitest)
npm run test

# Unit + e2e tests (Vitest + Playwright)
npm run test:all

# Lint
npm run lint

Docker (production-like, ARM64)

# Full stack — frontend served on http://localhost:8080
docker compose up --build

ENVIRONMENT VARIABLES

Backend reads from backend/.env (optional — all have defaults):

Variable Default Purpose
DATABASE_URL sqlite+aiosqlite:///./data/sleep.db SQLite DB path
CORS_ORIGINS http://localhost:5173 Allowed CORS origins (comma-separated)
LOG_LEVEL info Uvicorn log level

In Docker the DB is persisted via a bind-mount at ./backend/data/.

🛑 DIRECTORY NAVIGATION & FILE DISCOVERY

Context: This is a full-stack monorepo containing massive generated/dependency folders (node_modules, dist, venv, .venv, __pycache__, etc.). Unrestricted file listings will bloat your context window, crash your session, and cause severe token waste.

  • NEVER use ls -R: This command is strictly forbidden in this repository.
  • NEVER use find without -maxdepth: Unbounded find crawls dependency trees just like ls -R. Always add -maxdepth 3 or tighter.
  • Primary Discovery: To map out files or explore the project tree, ALWAYS use git ls-files. This is your default command and ensures you only interact with human-written source code.
  • Structural Context: If you explicitly need a visual directory layout to understand architecture, use tree appended with the mandatory ignore flags:
tree -I 'node_modules|.git|dist|build|__pycache__|venv|.venv|env|.pytest_cache|.mypy_cache|.ruff_cache|*.egg-info'
  • Searching Code: If you need to search for text or code blocks across the repo, ALWAYS use git grep "search_term" instead of standard grep -r to avoid crawling ignored or minified assets.

🧠 TASK DELEGATION & CONTEXT PRESERVATION

Context: The main OpenCode agent context window is our most critical resource. Executing complex tasks, debugging cross-file issues, or writing massive features directly in the main thread causes severe context bloat, leading to code hallucinations and dropped instructions.

  • Delegate Aggressively: For any complex implementation, structural change, or task larger than a single file edit, you MUST invoke a subagent via the Task tool. Act strictly as the architectural orchestrator; let subagents handle the iterative coding labor.
  • Scope Narrowly: Give subagents highly specific, isolated, and atomic objectives (e.g., "Read backend/app/routers/auth.py and summarize endpoints" or "Write a unit test for the frontend sleep tracker component").
  • Strict Summarization: Subagents are STRICTLY FORBIDDEN from passing raw terminal dumps, unedited file blocks, or their internal step-by-step logs back to the main thread.
  • Return Format: Subagents must return only clear, actionable results back to the orchestrator: a concise summary of findings, the exact lines of code that require modification, or direct confirmation of a successful execution.

NOTES

  • Entry Points: frontend/src/main.tsx (Frontend) & backend/app/main.py (Backend).
  • Database: Local SQLite managed via aiosqlite for an entirely async-first data layer.
  • Target Architecture: Built specifically for ARM64 deployment on a Raspberry Pi 4 via Docker.