diff --git a/README.md b/README.md index 8f1d5c7..77e457c 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,53 @@ -# Mashov Parent Command Center +
-> The school portal a busy parent can actually keep up with โ€” every kid's messages, homework & behavior in one daily glance, on top of Israel's [Mashov](https://web.mashov.info) system. +# ๐ŸŽ’ Mashov Parent Command Center -**๐Ÿ”— Live app: [mashov.mitya.dev](https://mashov.mitya.dev)** +**The school portal a busy parent can actually keep up with** โ€” _glance ยท triage ยท done in 30 seconds_ -A mobile-first, Hebrew/RTL household dashboard that sits on top of the Mashov Israeli school API. Sign in once with your existing Mashov account and get a single, aggregated briefing across all your children โ€” what changed, who needs attention, and which school messages are waiting. +[![CI](https://github.com/mitekk/mashov/actions/workflows/ci.yml/badge.svg)](https://github.com/mitekk/mashov/actions/workflows/ci.yml) +![Node](https://img.shields.io/badge/Node-22-7c3aed?logo=nodedotjs&logoColor=white) +![Next.js](https://img.shields.io/badge/Next.js-15-0a0612?logo=nextdotjs&logoColor=white) +![NestJS](https://img.shields.io/badge/NestJS-11-ea2845?logo=nestjs&logoColor=white) +![Prisma](https://img.shields.io/badge/Prisma-5-2d3748?logo=prisma&logoColor=white) +![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16-336791?logo=postgresql&logoColor=white) +![Redis](https://img.shields.io/badge/Redis-7-dc382d?logo=redis&logoColor=white) +![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?logo=typescript&logoColor=white) -## What is this? +A mobile-first, Hebrew/RTL household dashboard over Israel's [Mashov](https://web.mashov.info) +school system. Sign in once with your existing Mashov account and get a single, aggregated +briefing across all your children โ€” what changed, who needs attention, and which school +messages are waiting. -The school portal already has all your kids' data โ€” it's just exhausting to use day to day. You log in, navigate a heavy legacy interface, switch context between children, and reassemble "what changed" from a half-dozen screens. Every time. +**๐Ÿ”— Live โ€” [mashov.mitya.dev](https://mashov.mitya.dev)** -This app removes that. It's a calm, low-click **summary and triage layer** over Mashov that answers one question fast: *what changed, who it affects, and what needs attention right now.* The goal is to understand your whole household's school status in **under 30 seconds**, without hunting through menus. +
-## What you get +> โš ๏ธ **Unofficial companion โ€” not affiliated with or endorsed by Mashov +> ([web.mashov.info](https://web.mashov.info)).** You sign in with your own school credentials; +> the app is **read-only** and never writes back to the portal. Stored credentials are encrypted +> at rest. + +--- + +- **For parents** โ€” [What it is](#what-it-is) ยท [What you get](#what-you-get) ยท [How it works](#how-it-works) ยท [Good to know](#good-to-know) +- **For developers** โ€” [Quick start](#quick-start) ยท [Architecture](#architecture) ยท [Tech stack](#tech-stack) ยท [Testing](#testing) ยท [Configuration](#configuration) ยท [Docs & decisions](#docs--decisions) + +--- + +## ๐Ÿ  For parents + +### What it is + +The school portal already has all your kids' data โ€” it's just exhausting to use day to day. You +log in, navigate a heavy legacy interface, switch context between children, and reassemble "what +changed" from a half-dozen screens. Every time. + +This app removes that. It's a calm, low-click **summary and triage layer** over Mashov that +answers one question fast: *what changed, who it affects, and what needs attention right now.* The +goal is to understand your whole household's school status in **under 30 seconds**, without +hunting through menus. + +### What you get - **๐Ÿ“‹ One daily briefing** โ€” a single mixed feed of what changed across all your children, newest first. - **๐Ÿ”” Attention first** โ€” surfaces who needs you: new unread messages, behavior and attendance events, and recently assigned homework. @@ -22,103 +57,103 @@ This app removes that. It's a calm, low-click **summary and triage layer** over - **๐Ÿ“ฑ Mobile-first & RTL** โ€” designed for the phone and built for Hebrew (including mixed Hebrew/English) from the ground up. - **๐Ÿ”’ Private by default** โ€” each parent gets their own read/handled state, and stored credentials are encrypted at rest. -## How it works +### How it works 1. **Sign in** โ€” pick your school and log in with your Mashov username and password (the school year is detected automatically). 2. **First sync** โ€” the app pulls your household's latest data once in the background. 3. **Glance** โ€” open it whenever, see what's new across all your kids, and drill into a single message or child only if you need to. -## Good to know +### Good to know -This is a reading and triage companion, **not** a rebuild of the school portal. It's read-only by design and intentionally scoped โ€” it does **not** include grades, report cards, or performance analytics. Think "daily briefing," not "admin portal." +This is a reading and triage companion, **not** a rebuild of the school portal. It's read-only by +design and intentionally scoped โ€” it does **not** include grades, report cards, or performance +analytics. Think "daily briefing," not "admin portal." -## Tech stack - -| Layer | Tech | -|-------|------| -| Frontend | Next.js + TypeScript (mobile-first, RTL) | -| Backend | NestJS + TypeScript + per-household sync engine | -| Database | PostgreSQL | -| Cache / rate limiting | Redis | -| Infrastructure | Docker Compose | - ---- +## ๐Ÿ› ๏ธ For developers -## Prerequisites - -- [Docker](https://docs.docker.com/get-docker/) and Docker Compose v2 -- Node.js 22+ (for local development without Docker) - -## Quick Start (Docker) +### Quick start ```bash -cp .env.example .env -# Fill in your Mashov credentials in .env -docker compose up --build +cp .env.example .env # then fill in your Mashov credentials +docker compose up --build # db, redis, backend, frontend (hot reload via the override file) ``` -- Frontend: http://localhost:3000 -- Backend API: http://localhost:3001 -- Health check: http://localhost:3001/health - -## Environment Variables - -| Variable | Description | Example | -|----------|-------------|---------| -| `DATABASE_URL` | PostgreSQL connection string | `postgresql://postgres:postgres@db:5432/mashov` | -| `DB_NAME` | Database name | `mashov` | -| `DB_USER` | Database user | `postgres` | -| `DB_PASSWORD` | Database password | `postgres` | -| `MASHOV_SEMEL` | School ID (semel) | `482273` | -| `MASHOV_YEAR` | Academic year | `2026` | -| `MASHOV_USERNAME` | Parent ID number (username) | `your_id_number` | -| `MASHOV_PASSWORD` | Parent password | `your_password` | -| `ENCRYPTION_KEY` | 64-char hex key for encrypting stored credentials | `your_64_hex_chars_here` | -| `REDIS_URL` | Redis connection string | `redis://redis:6379` | -| `SESSION_LIFETIME_DAYS` | Session cookie lifetime in days (rolling) | `30` | -| `SESSION_SECURE_COOKIE` | Set `false` for local dev (no HTTPS) | `false` | -| `CORS_ORIGIN` | Allowed CORS origin(s) for the backend | `http://localhost:3000` | -| `FEATURE_DAILY_BEHAVE` | Enable daily behaviour sync | `false` | -| `FEATURE_OUT_BEHAVE` | Enable out-of-school behaviour sync | `false` | - -Copy `.env.example` to `.env` and fill in your values. Never commit `.env`. - -## Running Tests (Containers Only) +| Service | URL | Notes | +|---|---|---| +| Frontend (Next.js) | | the app | +| Backend (NestJS) | | health check at `/health` | +| PostgreSQL | `localhost:5432` | | +| Redis | `localhost:6379` | cache + sessions | + +> **Requirements:** Docker + Docker Compose v2. Node 22+ is only needed for host-side tooling; +> `docker compose up` is the supported path. + +### Architecture + +The browser only ever calls the **same-origin** `/api/*`; the Next.js server proxies those to the +NestJS API. The API owns a per-household **sync engine** that pulls from the upstream Mashov API +with your credentials into Postgres, and uses Redis for caching and sessions. + +```mermaid +flowchart LR + UI["Browser ยท Next.js UI
mobile-first ยท RTL"] + Next["Next.js web :3000
App Router + /api proxy"] + Nest["NestJS api :3001
auth ยท sync engine ยท feed"] + PG[("Postgres 16
Prisma ORM")] + RD[("Redis 7
cache ยท sessions")] + MASHOV{{"Mashov API
web.mashov.info"}} + UI -- "same-origin /api/*" --> Next + Next -- "server-side proxy" --> Nest + Nest -- "SQL" --> PG + Nest -- "cache ยท sessions" --> RD + Nest -- "sync ยท your creds" --> MASHOV +``` -```bash -# Backend unit tests with coverage (inside container) -npm run test:unit +``` +. +โ”œโ”€โ”€ frontend/ # Next.js + TypeScript UI (mobile-first, RTL) + /api proxy +โ”œโ”€โ”€ backend/ # NestJS API + per-household sync engine (Prisma) +โ”œโ”€โ”€ docs/ # PRD, ADRs (0001โ€“0022), architecture, API contract +โ””โ”€โ”€ tests/ # integration + Playwright e2e +``` -# Backend API integration tests (inside container) -npm run test:integration +See [`docs/architecture.md`](docs/architecture.md) for the full design. -# Full-stack E2E tests with Playwright (inside container) -npm run test:e2e -``` +### Tech stack -## Local Development (Hot Reload) +| Layer | Tech | +|---|---| +| Frontend | Next.js 15 (App Router) ยท React 19 ยท TanStack Query ยท TypeScript | +| Backend | NestJS 11 ยท per-household sync engine ยท TypeScript | +| Data | PostgreSQL 16 ยท Prisma ORM | +| Cache / sessions | Redis 7 | +| Infrastructure | Docker Compose | -`docker-compose.override.yml` is automatically loaded by `docker compose up` and mounts source directories for live reload โ€” no rebuild needed on code changes. +### Testing + +All suites run inside the containers (`--profile test`): ```bash -docker compose up # hot reload enabled automatically -docker compose down -v # stop and remove volumes +npm run test:unit # backend unit tests +npm run test:integration # backend API integration tests +npm run test:e2e # full-stack Playwright e2e ``` -Service ports: +### Configuration -| Service | Port | -|---------|------| -| Frontend (Next.js) | 3000 | -| Backend (NestJS) | 3001 | -| PostgreSQL | 5432 | -| Redis | 6379 | +Copy `.env.example` to `.env`. The values you **must** set: -## Project Structure +| Variable | What | +|---|---| +| `MASHOV_USERNAME` ยท `MASHOV_PASSWORD` | your Mashov login | +| `MASHOV_SEMEL` ยท `MASHOV_YEAR` | school ID (semel) + academic year | +| `ENCRYPTION_KEY` | 64-char hex key; encrypts stored credentials at rest | -``` -frontend/ Next.js + TypeScript UI -backend/ NestJS + TypeScript API + sync engine -docs/ Architecture, ADRs, API contract, PRD -tests/ Integration and E2E tests -``` +`DATABASE_URL`, `REDIS_URL`, the session/CORS settings, and the `FEATURE_*` flags all ship with +working defaults in [`.env.example`](.env.example). Never commit `.env`. + +### Docs & decisions + +- **Product:** [`docs/prd/PRD-current.md`](docs/prd/PRD-current.md) +- **Architecture:** [`docs/architecture.md`](docs/architecture.md) ยท **API contract:** [`docs/api-contract.md`](docs/api-contract.md) +- **Decisions:** [`docs/adr/`](docs/adr/) โ€” ADR 0001โ€“0022 ([index](docs/adr/README.md))