This repository contains a full-stack starter for a multi-tenant SaaS study app:
Backend/StudySaaS.Api: ASP.NET Core 8 Web API starter with JWT auth, tenant resolution, course/material/test APIs.AndroidApp: Native Android (Kotlin) app with Login, Course List, and Tests screens consuming backend APIs.docs/Architecture.md: in-depth SaaS architecture, scaling, data, and deployment blueprint.
- Shared database strategy.
- Tenant is resolved using
X-Tenantheader (maps to institute subdomain/code). - JWT includes
instituteId, role, and user identity. - Every query is filtered by
InstituteId.
Base URL: http://localhost:5000/
Key endpoints:
POST /api/auth/register-institutePOST /api/auth/loginGET /api/coursesPOST /api/coursesGET /api/courses/{courseId}/materialsGET /api/tests/course/{courseId}POST /api/tests/submit
Use header:
X-Tenant: demo
Authorization: Bearer <jwt>
Demo login:
student@demo.com / Pass@123teacher@demo.com / Pass@123
Update API endpoint in:
AndroidApp/app/build.gradle.ktsviaAPI_BASE_URLandTENANT_CODEbuild config fields.
For Android Emulator, use:
http://10.0.2.2:5000/
- .NET 8 SDK (for backend)
- Android Studio + Android SDK (for app)
- Java 17+
./scripts/run_backend.shBackend starts at http://localhost:5000.
In another terminal:
./scripts/smoke_test_backend.shThis performs login using demo credentials and fetches courses.
- Open
AndroidApp/in Android Studio. - Let Gradle sync.
- Start emulator and run app.
API URL is already configured for emulator loopback (
http://10.0.2.2:5000/).
To generate a release ZIP locally (instead of committing binary artifacts):
./scripts_create_release_zip.sh
This creates:
StudySaaS-FullStack-Starter.zip
- EF Core + PostgreSQL and tenant global query filters.
- Refresh token flow and password hashing.
- Payments/subscriptions with Razorpay/Stripe.
- Redis caching and background jobs.
- Blob storage + CDN for videos/PDFs.
- Push notifications, analytics dashboards, and offline sync.
If you cannot open a GitHub PR directly from this environment, use this flow:
- Commit changes locally.
- Push your branch to your remote repo.
- Open a PR from that branch in GitHub.
If you're using an automated agent environment, the PR title/body can also be generated via an integrated PR tool and then pasted into GitHub.