feat: add onboarding tutorial for new users
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 3m4s

- Introduced a modular tutorial layer to guide new parents through the app setup process.
- Implemented a 3-step forced intro after first sign-in (PIN setup → child creation → chore creation).
- Added just-in-time contextual hints for various features as users encounter them.
- Persisted user progress on the backend with new fields in the User model.
- Created a new tutorial controller and step registry in the frontend for managing tutorial states.
- Added Help button for easy access to tutorial tips and a restart option in the user profile.
- Ensured accessibility and mobile responsiveness for the tutorial overlay.
- Included tests for backend and frontend functionalities related to the tutorial.
This commit is contained in:
2026-06-19 17:27:35 -04:00
parent d147bd6f27
commit e2bb9cd6b9
24 changed files with 1764 additions and 627 deletions

57
AGENTS.md Normal file
View File

@@ -0,0 +1,57 @@
# AGENTS.md
Family chore/reward manager. Flask + TinyDB backend (`backend/`), Vue 3 + TypeScript frontend (`frontend/`). Real-time updates over SSE.
## Commands
### Backend (run from `backend/`)
- Activate venv: `source .venv/bin/activate`
- Dev server: `python -m flask run --host=0.0.0.0 --port=5000` (entry: `main.py`)
- Required env vars: `SECRET_KEY`, `REFRESH_TOKEN_EXPIRY_DAYS`, `DIGEST_TOKEN_SECRET`, `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY` — Flask raises `RuntimeError` on boot if any are missing
- Optional: `DB_ENV` / `DATA_ENV` (`prod` | `test` | `e2e`) — picks `data/` vs `test_data/` dir (see `config/paths.py`)
- Tests: `pytest tests/``conftest.py` forces `DB_ENV=test` and sets dummy secrets. Single test: `pytest tests/test_routine_api.py::test_name`
- Python imports assume `backend/` is on `sys.path` (set by `conftest.py` / `flask run` cwd). Run pytest from `backend/`.
- Create admin user: `python scripts/create_admin.py` (admin role cannot be set via signup)
### Frontend (run from `frontend/`)
- Dev: `npm run dev` (Vite, https://localhost:5173)
- Lint: `npm run lint`
- Type-check: `npm run type-check`
- Unit tests: `npm run test:unit` (Vitest). Single: `npx vitest run path/to/file.spec.ts`
- E2E: `npx playwright test` — config auto-starts both `npm run dev` and the Flask backend with `DB_ENV=e2e DATA_ENV=e2e`. Tests live in `e2e/`.
- E2E buckets are Playwright projects (see `playwright.config.ts`) targeting directories under `e2e/mode_parent/`
## Architecture
### API routing — the `/api` prefix
- Frontend nginx (and Vite dev proxy) strips `/api` before forwarding. **Backend routes must NOT include `/api`.** Backend defines `@app.route('/user')`, frontend calls `/api/user`.
- `auth_api` is the only blueprint registered with a prefix: `url_prefix='/auth'` in `main.py:67`.
- API errors return `{ error, code }` (codes in `backend/api/error_codes.py`). Frontend extracts them via `parseErrorResponse(res)` in `src/common/api.ts`.
### Models — strict 1:1 parity
- Python `@dataclass`es in `backend/models/`. TypeScript interfaces in `frontend/src/common/models.ts`. Any model change requires updating both.
- Persistence is TinyDB via the thread-safe `LockedTable` wrapper (`backend/db/db.py`). Operate on model instances with `from_dict()` / `to_dict()` — never raw dicts.
### SSE event bus — mandatory for every mutation
- Every backend mutation (add/edit/delete/trigger) **must** call `send_event_for_current_user` from `api/utils.py`. Event types in `backend/events/types/` are mirrored in `frontend/src/common/backendEvents.ts`.
- Frontend: register listeners in `onMounted`, clean up in `onUnmounted`. SSE endpoint is `/events`.
### Background schedulers (started in `main.py` at boot)
- `start_deletion_scheduler` — runs hourly, deletes accounts marked for deletion after threshold
- `start_digest_scheduler` — email digests
- `start_state_expiry_scheduler` — expires stale state
- `start_chore_expiry_notification_scheduler` — chore expiry notifications
## Frontend conventions
- SFC file order: `<template>``<script>``<style scoped>`. TypeScript only in `<script>`. All styles must be `scoped`.
- Colors/spacing: use only `:root` CSS variables from `colors.css`. No hardcoded hex/px for themed properties.
- Layout shells: `ParentLayout` for admin/management, `ChildLayout` for child dashboard/focus.
- Images: models carry `image_id`; frontend resolves to `image_url` for rendering.
## Testing gotchas
- E2E tests use pre-authenticated sessions via `storageState` in `playwright.config.ts` — do **not** navigate to `/auth/login`. Import `E2E_EMAIL` / `E2E_PASSWORD` from `e2e/e2e-constants.ts`.
- E2E buckets that mutate shared state (default tasks, delete-account, create-child) use isolated users. Preserve this pattern when adding new buckets.
- Backend tests: `conftest.py` sets `DB_ENV=test` + dummy secrets. Test DB lands in `test_data/db/`, never touches production `data/`.
## Feature specs
Specs live in `.github/specs/`. If a spec has a checklist, all items must be marked done before the feature is complete.