105 lines
6.8 KiB
Markdown
105 lines
6.8 KiB
Markdown
# Welcome — Junior Developer Onboarding
|
|
|
|
Welcome to **Föräldraledigplannerare**, a web app that helps Swedish parents plan their parental leave (föräldrapenning) and vacation days — alone or together with a partner — and see how many days they'll have left when their child turns 4. This guide gets you productive quickly on well-scoped pieces while the senior-owned, higher-risk parts are handled separately.
|
|
|
|
**Read first:** `ARCHITECTURE.md` — at least the overview (§0–§1), the data model (§3), and the section for whatever you pick up. Don't worry about absorbing all of it at once.
|
|
|
|
> **Foundation status — ready to build on.** The senior has finished the project foundation and the cross-cutting patterns, so you can start straight away. In place:
|
|
> - ✅ Backend reference slice (`VacationDays`) — tests in `tests/unit/test_vacation_days_repository.py`
|
|
> - ✅ Full schema + Alembic migrations (`migrations/versions/001_initial_schema.py`)
|
|
> - ✅ Auth (register/login/JWT) — `services/auth_service.py`, `routers/auth.py`
|
|
> - ✅ Workspace + invitation flow — `services/workspace_service.py`, `routers/workspace.py`
|
|
> - ✅ All 9 entities and their SQLite repos
|
|
> - ✅ `FetchDataService` contract + manual entry path (`services/fetch_data_service.py`)
|
|
> - ✅ Analytics service with days-left-at-age-4 (`services/analytics_service.py`)
|
|
> - ✅ Tips engine skeleton (`services/tips_service.py`) — rules ready to wire
|
|
> - ✅ `BreakPeriodService` (`services/break_period_service.py`)
|
|
> - ✅ Frontend project scaffolded + reference hook/component/test (`hooks/useVacationDays.ts`, `components/vacation-days/`)
|
|
> - ✅ CI pipeline (`.github/workflows/ci.yml`)
|
|
>
|
|
> **First step:** `cd backend && uv sync && uv run pytest` — confirm the suite is green, then pick up Task 1.
|
|
|
|
---
|
|
|
|
## 1. Tech stack & the big picture
|
|
|
|
- **Backend:** Python 3.14, FastAPI, `uv` for packages. Layered: `entities → repositories → services → routers`, wired with dependency injection.
|
|
- **Frontend:** TypeScript + React + Vite, tested with Vitest.
|
|
|
|
The single most useful thing you can do is study the **reference vertical slice** for the `VacationDays` entity. It shows every layer once, end-to-end. **You'll build new features by copying its shape.**
|
|
|
|
```
|
|
backend/app/
|
|
entities/vacation_days.py # 1. plain dataclass (the domain object)
|
|
models/vacation_days.py # 2. pydantic request/response schemas
|
|
repositories/vacation_days_repository.py # 3. abstract interface
|
|
repositories_impl/sqlite/vacation_days_repository.py # 4. SQLite implementation
|
|
services/vacation_days_service.py # 5. business rules
|
|
routers/vacation_days.py # 6. HTTP endpoints
|
|
backend/tests/unit/test_vacation_days_repository.py # 7. tests
|
|
```
|
|
|
|
## 2. Getting set up
|
|
|
|
**Backend**
|
|
```bash
|
|
cd backend
|
|
uv sync # install dependencies
|
|
uv run pytest # run tests (should pass)
|
|
uv run uvicorn app.main:app --reload # dev server on http://localhost:8000 (/health, /docs)
|
|
uv run ruff check . # lint
|
|
```
|
|
|
|
**Frontend**
|
|
```bash
|
|
cd frontend
|
|
npm install
|
|
npm run dev # dev server
|
|
npm test # Vitest
|
|
```
|
|
|
|
## 3. Your starter tasks
|
|
|
|
Work in small PRs, lowest number first. Each task says which existing file to copy.
|
|
|
|
### Backend — copy the `VacationDays` slice
|
|
|
|
1. **`BreakPeriod` tests** (great first task — all layers already exist, study and test them). Entity, schema, SQLite repo, service (`services/break_period_service.py`), and router (`routers/break_periods.py`) are all in place. Your job: write `tests/unit/test_break_period_repository.py` following the `test_vacation_days_repository.py` pattern. Remember to use the `seeded_ids` fixture (see `tests/conftest.py`) so FK constraints pass.
|
|
2. **`Child` CRUD + settings endpoints** (incl. `preschool_start_date`). Same pattern; wire the `PUT /api/settings/child/{child_id}` endpoint from `§5`.
|
|
3. **Parent-profile settings** (`salary_type`, `employment_status`) and **workspace `planning_goal`** endpoints from `§5`.
|
|
|
|
### Backend — pure utility functions (very test-friendly, no framework)
|
|
|
|
4. **Date helpers** in `app/utils/dates.py`: e.g. `add_months(date, n)`, `age_in_months(birth_date, on)`, `fourth_birthday(birth_date)`. Pure functions with thorough unit tests — the calculation engine will depend on these, so correctness matters (mind leap years / month-end).
|
|
5. **Swedish public-holiday helper** (`§6.2`): given a year, return the röda dagar (use the `holidays` library, Sweden locale; cache per year). Unit-test a few known dates. The calendar UI and the "wrap red days with vacation" tip both need this.
|
|
|
|
### Frontend
|
|
|
|
6. **Transcribe the TypeScript types** from `ARCHITECTURE.md §7` into `frontend/src/types/`. Mechanical but valuable — everything else builds on these.
|
|
7. **Presentational components** (take props, render UI, no business logic): `LoadingSpinner`, `Header`, `Footer`, `Layout`, `CalendarDay`, `CalendarEvent`, `OverviewMetrics`, `DaysBreakdown`, `ProgressChart`, `TipCard`, and the settings inputs (`VacationDaysInput`, `ChildBirthdayInput`, `ParentProfileInput`, `PlanningGoalSelector`, `BreakPeriodsInput`). Each with a Vitest render test.
|
|
8. **Frontend utils** `dates.ts` / `formatting.ts` (e.g. format day counts, sv-SE dates) with tests.
|
|
9. **Simple data hooks** following the reference hook the senior provides (e.g. `useVacationDays`, `useBreakPeriods`) — fetch + loading/error state.
|
|
|
|
## 4. Definition of done (every PR)
|
|
|
|
- Fully typed — no `any` in TS without a written reason; type hints on all Python.
|
|
- Tests added, **≥90% coverage** on the code you wrote; happy path **and** error cases.
|
|
- `ruff check` (backend) / ESLint (frontend) clean.
|
|
- Errors raised as `DomainError` subclasses (backend) — never a bare `except`, never a silent failure.
|
|
- Magic numbers for Swedish rules come from `config.py::LeaveRules`, not hard-coded.
|
|
- Keep PRs small and focused; a draft PR with questions is very welcome.
|
|
|
|
## 5. Out of scope — owned by the senior developer
|
|
|
|
These are higher-risk or high-ambiguity and belong to the senior. They're not blocking you — they're simply someone else's lane. You *can* build the presentational pieces around them (e.g. a `TipCard` component), just not the core logic:
|
|
|
|
- The **Försäkringskassan scraper / BankID** flow (legal + security sensitive).
|
|
- **Auth & security** (password hashing, tokens, sessions, invitation tokens).
|
|
- The **"days left at age 4" calculation** and planned-vs-actual reconciliation (`§6.5`).
|
|
- The **tips engine logic** — the SGI / payroll / red-day *rules* themselves (`§6`).
|
|
- **Database migrations** and the connection/pool setup.
|
|
|
|
## 6. Getting help
|
|
|
|
If a task is ambiguous, the data model is unclear, or a test is hard to write — ask early rather than guessing. Note what you tried and where you got stuck; that makes it quick for a senior to unblock you. Welcome aboard!
|