About the Project
Schools run on curriculum paperwork: syllabi, curriculum plans, and the monthly lesson plans that teachers submit and department heads sign off on. IET had been managing all of it by hand, on top of a brittle Power Automate workflow. This platform replaces both with one system. A teacher uploads a document, a routing engine works out exactly who approves it (Teacher → HOD → VP → Principal), and that approver can act from the web app, an email action link, or straight inside Microsoft Teams. Admins own the users, permissions, master data, and the routing rules.
The biggest architectural decision was multi-tenancy. Every tenant-owned record carries a schoolId that scopes every read, and record creation won't compile without a tenant, so a query can't leak data across schools. A tenant-isolation test suite exists to catch it if that ever breaks. Each school resolves its own Azure AD, SharePoint, Teams, and email configuration from its tenant row. Those secrets are AES-256-GCM encrypted at rest and never sent back to the client. New schools are provisioned from a CLI or a developer console that seeds master data, permissions, and bootstrap users in one step.
The backend is a strictly layered TypeScript app: Routes, Controllers, Services, Repositories, then Prisma. Every endpoint is validated with Zod in strict mode, auth is a JWT in an httpOnly cookie, access runs through a dynamic per-role permission matrix, and there are four tiers of rate limiting. Uploaded files are checked by magic bytes rather than their extension, stored under UUID filenames outside the web root, and versioned on every re-upload. Each document moves through a PENDING → APPROVED / REJECTED / REVOKED state machine, and those transitions run inside database transactions that write the audit log in the same commit.
Most of the effort went into the Microsoft 365 side, so the portal sits inside the tooling schools already use. Login is Azure AD SSO through MSAL. Email goes out over Microsoft Graph. Approved documents sync to SharePoint automatically, and change-tracking webhooks (auto-renewed by a cron job) catch anything uploaded straight to SharePoint and pull it back in for review. Teams notifications carry the approve and reject buttons inline. There's also an HR insights module that polls a OneDrive/Forms export through Graph and syncs it into MySQL for a candidate-analytics dashboard.
I built the whole system with Claude Code. The architecture, the tenancy model, the security decisions, and the product calls were mine; Claude Code was the environment I implemented them in, down to the Vitest unit and integration tests. It's deployed and running on my company's internal server behind IIS and PM2, waiting on the school's go-live.