- Get Started
- Localhost
- Architecture
- Structure
- Pattern
- Page
- Layout
- Content
- Types
- Config
- Actions
- Queries
- Authorization
- Validation
- Form
- Table
- Detail
- Card
- Util
- Hooks
- List Params
- Views
- README.md
- ISSUE.md
- Technology Stack
- Database
- File
- CDN Assets
- Entry Points
- Dashboard
- Authentication
- Credentials
- OAuth
- Flow Diagrams
- Multi-Tenancy
- Offline
- Onboarding
- Onboarding Videos
- Add Values
- Admission
- Application
- Attendance
- Compliance
- Profile
- Exams
- Exam Wizard
- Timetable
- Classrooms
- Notifications
- Conference
- LMS (Lumos)
- Finance
- Fee Management
- Invoice
- Wallet
- Salary
- Payroll
- Timesheet
- Expenses
- Budget
- Receipt
- Accounts
- Banking
- Reports
- Dashboard
- Permissions
- Messages
- Integration Flow
- Provision
- AI Document Processing
- Document Intelligence
- Internationalization
- Translation
- Translation Guide
- Icons
- Docs Factory
- Inspiration
- Listings
- Teachers
- Students
- Catalog
- Library
- Contributing
- Code of conduct
- GitHub Workflow
- Database Seeds
- Database Safety
- Test Accounts
- Bulk import
- Playwright
- Prettier
- Block Rebound
- Transportation
Balqalam uses Next.js App Router with feature-based components. Routes mirror components 1:1 — if you know the URL, you know where the code lives. See Pattern for code conventions and Architecture for the mirror pattern explained.
Project root
hogwarts/
├── public/ # Static assets
├── prisma/
│ ├── schema.prisma # Datasource + generator + imports
│ ├── models/ # Multi-file schema
│ └── seeds/ # Seed scripts (run via pnpm db:seed:single)
├── src/
│ ├── app/ # Next.js App Router routes
│ ├── components/ # Feature components (mirror app/)
│ ├── lib/ # Utility modules
│ ├── types/ # Global TypeScript definitions
│ ├── styles/ # Global styles (typography.css)
│ └── proxy.ts # Edge proxy — subdomain detection, URL rewriting
├── content/docs-en/ # MDX documentation (English)
├── content/docs-ar/ # MDX documentation (Arabic mirror)
├── scripts/ # Build + seed scripts
├── tests/ # E2E test suites (Playwright)
├── .env # Central environment — never .env.local
├── next.config.ts
├── package.json # pnpm only
└── tsconfig.json # @/* → ./src/*Routes (src/app/)
All routes live under [lang]/ for locale routing (ar, en). Four entry points, implemented as App Router groups.
Entry points
| Group | URL | Purpose | Access |
|---|---|---|---|
(saas-marketing) | ed.databayt.org/ | SaaS public marketing | Public |
(saas-dashboard) | ed.databayt.org/dashboard | Operator dashboard | DEVELOPER only |
(school-marketing) | school.databayt.org/ | Per-tenant public site | Public |
(school-dashboard) | school.databayt.org/dashboard | Per-tenant platform | Authenticated school roles |
Route tree
src/app/[lang]/
├── (saas-marketing)/ # ed.databayt.org public
│ ├── page.tsx # Landing
│ ├── pricing/
│ ├── features/
│ ├── community/ # Catalog hub
│ └── docs/ # Fumadocs viewer
│
├── (saas-dashboard)/ # Operator (DEVELOPER only)
│ ├── dashboard/
│ ├── tenants/ # School management
│ ├── billing/
│ ├── sales/
│ ├── domains/
│ ├── observability/
│ └── (catalog)/catalog/ # Platform content catalog
│
├── (auth)/ # Login, join, reset, OAuth
├── onboarding/ # School creation wizard
├── settings/
├── my-school/ # School selector
│
└── s/[subdomain]/ # Per-tenant routes (rewrite target)
├── (school-marketing)/ # Tenant public site
│ ├── page.tsx # School homepage
│ ├── admissions/
│ ├── academic/
│ ├── about/
│ ├── tour/
│ └── inquiry/
│
├── application/ # Public 9-step application
│
└── (school-dashboard)/ # Authenticated platform
├── dashboard/
├── admission/ # Admission management
├── attendance/ # Attendance tracking
├── timetable/
├── exams/
├── lumos/ # LMS
├── library/
├── finance/
├── billing/
├── messages/
├── notifications/
├── transportation/
├── settings/
└── (listings)/ # CRUD entities
├── announcements/
├── assignments/
├── classes/
├── classrooms/
├── events/
├── grades/
├── lessons/
├── parents/
├── staff/
├── students/
├── subjects/
└── teachers/The s/[subdomain]/ segment is internal only. Middleware rewrites school.databayt.org/dashboard → /[lang]/s/school/dashboard. Client code uses clean tenant-relative paths.
Components (src/components/)
Routes mirror components 1:1. The page file is thin — it imports and renders the feature's content.tsx.
// src/app/[lang]/s/[subdomain]/(school-dashboard)/(listings)/students/page.tsx
import { Content } from "@/components/school-dashboard/listings/students/content"
export default function StudentsPage() {
return <Content />
}Top-level component dirs
| Directory | Purpose |
|---|---|
ui/ | shadcn/ui primitives (button, input, card, dialog, …) |
atom/ | 2+ primitives composed into reusable patterns |
template/ | Full-page layouts (header, sidebar, footer) |
auth/ | Authentication (login, join, reset, OAuth, role gates) |
onboarding/ | 15-step school creation wizard |
school-dashboard/ | School platform features |
saas-dashboard/ | Operator dashboard features |
saas-marketing/ | SaaS marketing components |
school-marketing/ | School public-site components |
lumos/ | LMS (courses, dashboard, payment) |
library/ | Digital library |
internationalization/ | i18n (language switcher, RTL, dictionaries) |
theme/ | Theme provider + toggles |
providers/ | React contexts |
tenant/, school-switcher/ | Multi-tenant UI |
profile/ | User profile (per role) |
docs/, mdx/ | Documentation rendering |
file/ | Upload, browse, export, import, print, generate |
crud-modal/, view-toggle/ | Generic CRUD + view patterns |
rich-text-editor/, chatbot/ | Rich-text + AI chat |
monitoring/, offline/ | Observability + PWA |
billingsdk/, sales/ | Billing + CRM |
School dashboard (src/components/school-dashboard/)
| Sub-feature | What it covers |
|---|---|
listings/ | CRUD entities (announcements, assignments, classes, classrooms, events, grades, lessons, parents, staff, students, subjects, teachers) |
dashboard/ | Role-specific dashboards (admin / teacher / student / parent / staff / accountant / principal) |
attendance/ | 11 capture modes + gamification + AI insights |
timetable/ | Visual builder + conflict detection + generation |
admission/ | 9-step application + AI document review + merit ranking |
exams/ | Exams + mock + quizzes + qbank + certificates + report cards |
finance/ | Double-entry bookkeeping + 6 payment gateways + Plaid + Dwolla + payroll + invoicing |
library/ | Catalog + circulation |
transportation/ | Drivers + vehicles + routes + trips + geofence boarding |
messaging/ | 1:1 + group + reactions + read receipts + WhatsApp bridge |
notifications/ | In-app + email + push |
school/ | School configuration + branding + academic + bulk + reports + security |
analytics/, reports/ | Cross-feature analytics |
Listings entities
CRUD entities for announcements, assignments, classes, classrooms, events, grades, lessons, parents, staff, students, subjects, and teachers — each follows the canonical feature file pattern.
See /docs/listings for per-entity contracts and notable extras.
Templates (src/components/template/)
| Template | Use |
|---|---|
platform-sidebar/ | School dashboard sidebar |
platform-header/ | School dashboard header |
platform-footer/ | School dashboard footer |
dashboard-sidebar/, dashboard-header/ | Generic dashboard surfaces |
marketing-header/, marketing-footer/ | SaaS marketing surfaces |
saas-header/, saas-sidebar/ | Operator dashboard |
site-header/, site-footer/ | School marketing |
docs-sidebar/ | Documentation |
mobile-nav/ | Mobile navigation |
listing.tsx | Generic listing-page template |
Standard feature file pattern
See /docs/pattern for the canonical file contract.
Prisma schema (prisma/)
prisma/
├── schema.prisma # Datasource + generator + multi-file imports
├── models/ # Multi-file schema (one .prisma per domain)
│ ├── school.prisma
│ ├── auth.prisma
│ ├── students.prisma
│ ├── staff.prisma
│ ├── academic.prisma
│ ├── timetable.prisma
│ ├── attendance.prisma
│ ├── catalog.prisma
│ ├── exam.prisma
│ ├── finance-core.prisma
│ ├── subscription.prisma
│ ├── stream.prisma
│ ├── transportation.prisma
│ └── …
└── seeds/ # Seed scripts
├── index.ts # Orchestrator — never run directly
├── single.ts # Single seed runner — always use this
└── …Run seeds via pnpm db:seed:single <name>. Never pnpm db:seed. See Safe seeds.
Lib utilities (src/lib/)
Key utilities you'll touch often.
| File | Purpose |
|---|---|
db.ts | Prisma client singleton |
tenant-context.ts | Multi-tenant context resolution — source of truth for schoolId |
google-translate.ts | Google Translate API client |
translate.ts | Translation with DB caching |
content-display.ts | getText() for on-demand translation |
auto-translate.ts | Auto-translation utilities |
stripe.ts | Stripe payments |
cloudfront.ts | CloudFront CDN signing |
rate-limit.ts | API rate limiting |
oauth-redirect.ts | OAuth callback handling |
school-access.ts | School access control |
mapbox.ts | Mapbox geocoding |
format-date.ts | Date formatting |
join-code.ts | School join-code generation |
payment/providers/ | 6 payment gateways (stripe, bankak, tap, bank-transfer, cash, mobile-money) |
email-templates/ | React Email templates |
Key rules
| Rule | Detail |
|---|---|
| Package manager | pnpm only (Vercel requirement) |
| Environment | Single .env — never .env.local, .env.development, etc. |
| Multi-tenant isolation | Every DB query includes schoolId |
| Mirror pattern | app/ routes map 1:1 to components/ directories |
| Semantic HTML | No hardcoded text-* / font-* classes |
| Locale routing | All routes under [lang]/ for ar / en |
| Subdomain routing | School routes under s/[subdomain]/ (internal only) |
| Logical CSS | ms-*, me-*, ps-*, pe-* — never ml-*, mr-*, pl-*, pr-* |
| Import alias | @/* → ./src/* |
| Port | Always 3000 in dev |
| Seeding | Always pnpm db:seed:single <name> — never pnpm db:seed |
Common imports
import { auth } from "@/auth"
import { db } from "@/lib/db"
import { getTenantContext } from "@/lib/tenant-context"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { PageHeader } from "@/components/atom/page-header"
import { Content } from "@/components/school-dashboard/listings/students/content"
import { PlatformSidebar } from "@/components/template/platform-sidebar"
import { getText } from "@/components/translation/display"See also
- Architecture — mirror pattern explained
- Pattern — code conventions per feature
- Multi-tenancy — subdomain routing + tenant context
- Database — Prisma models + isolation rules
- Stack — full technology choices
On This Page
Project rootRoutes (src/app/)Entry pointsRoute treeComponents (src/components/)Top-level component dirsSchool dashboard (src/components/school-dashboard/)Listings entitiesTemplates (src/components/template/)Standard feature file patternPrisma schema (prisma/)Lib utilities (src/lib/)Key rulesCommon importsSee also