The school portal a busy parent can actually keep up with β glance Β· triage Β· done in 30 seconds
A mobile-first, Hebrew/RTL household dashboard over Israel's Mashov 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.
π Live β mashov.mitya.dev
β οΈ Unofficial companion β not affiliated with or endorsed by Mashov (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 you get Β· How it works Β· Good to know
- For developers β Quick start Β· Architecture Β· Tech stack Β· Testing Β· Configuration Β· Docs & decisions
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.
- π 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.
- βοΈ Clean inbox β read school messages without the legacy clutter, with exact unread counts and attachment indicators.
- π§ Per-child workspace β homework history, a behavior & attendance timeline, subjects & teachers, and the weekly timetable for each child.
- π No new account β sign in with your existing Mashov school credentials; nothing extra to remember.
- π± 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.
- Sign in β pick your school and log in with your Mashov username and password (the school year is detected automatically).
- First sync β the app pulls your household's latest data once in the background.
- 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.
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."
cp .env.example .env # then fill in your Mashov credentials
docker compose up --build # db, redis, backend, frontend (hot reload via the override file)| Service | URL | Notes |
|---|---|---|
| Frontend (Next.js) | http://localhost:3000 | the app |
| Backend (NestJS) | http://localhost:3001 | 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 upis the supported path.
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.
flowchart LR
UI["Browser Β· Next.js UI<br/>mobile-first Β· RTL"]
Next["Next.js web :3000<br/>App Router + /api proxy"]
Nest["NestJS api :3001<br/>auth Β· sync engine Β· feed"]
PG[("Postgres 16<br/>Prisma ORM")]
RD[("Redis 7<br/>cache Β· sessions")]
MASHOV{{"Mashov API<br/>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
.
βββ 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
See docs/architecture.md for the full design.
| 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 |
All suites run inside the containers (--profile test):
npm run test:unit # backend unit tests
npm run test:integration # backend API integration tests
npm run test:e2e # full-stack Playwright e2eCopy .env.example to .env. The values you must set:
| 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 |
DATABASE_URL, REDIS_URL, the session/CORS settings, and the FEATURE_* flags all ship with
working defaults in .env.example. Never commit .env.
- Product:
docs/prd/PRD-current.md(history:docs/prd/) - Architecture:
docs/architecture.mdΒ· API contract:docs/api-contract.md - Decisions:
docs/adr/β ADR 0001β0022 (index)