Services & Repos
One-line: six repositories make the product — one API, two web apps, one mobile app, infra, and a marketing site.
Repositories
| Repo | Local path | Stack | Purpose |
|---|---|---|---|
nexchool/server | server/ | Python, Flask, SQLAlchemy 2, Flask-Migrate, Celery | The API and all business logic |
nexchool/school-admin-panel | admin-web/ | Next.js 16, Tailwind 4, React Hook Form, Zod v4, TanStack Query v5 | School admin dashboard (tenant-scoped) |
nexchool/super-admin-panel | panel/ | Next.js, same FE stack | Operator control plane (/api/platform/*) |
nexchool/client | client/ | Expo ~54, React Native, TypeScript | Mobile app (teachers, students, admins) |
nexchool/nexchool-infra | school-erp-infra/ | Docker Compose, Nginx, GitHub Actions | Deploy, TLS, CI/CD |
nexchool/landing-page | landing-page/ | Next.js | Marketing site, Vercel-hosted |
Backend module anatomy
Each domain lives in server/modules/<name>/ and follows the same shape:
server/modules/students/
__init__.py # blueprint registration
routes.py # HTTP controllers (thin) → call services
services.py # business logic (the real work)
models.py # SQLAlchemy models (tenant-scoped via TenantBaseModel)
schemas.py # request/response validation (marshmallow/pydantic-style)Controllers stay thin; the service layer holds logic and is the only layer that touches the database. This keeps business rules testable and out of both the HTTP layer and the DB.
The full module list (37 backend modules) folds into the product domains documented under Product: students, teachers, classes, attendance, fees/finance, timetable/schedule, transport, hostel, notifications/announcements/devices/mailer, academics (academics, academic_programmes, grades, mediums, religions, subjects, subject_contexts, holidays, school_units, school_setup), plus platform, rbac, users, auth, audit, dashboard, search, subscription, sub_admins, student_leaves.
Core infrastructure (server/core/)
| Concern | Where |
|---|---|
| Tenant resolution | core/tenant.py |
| DB base + tenant scoping | core/database.py (TenantBaseModel, loader criteria) |
| Plan feature gating | core/plan_features.py |
| Redis cache layer | core/cache.py |
| RBAC seed | server/scripts/seed_rbac.py |
Frontend service layer
Each client centralises HTTP in one place and unwraps the { success, data } envelope:
admin-web/src/services/api.tspanel/src/services/…(equivalent)client/common/services/api.ts
Data fetching in the web apps uses TanStack Query, and every tenant-scoped query key ends with tenantId so two tenants never share a cache entry (see Multi-tenancy).
Async work
Celery workers (Redis broker) handle background jobs — bulk imports, notification dispatch/fan-out, scheduled sweeps (e.g. stale-draft cleanup). Anything slow or fan-out-shaped runs off the request thread.