Full-stack board exam analytics and data management system with:
- Frontend: Next.js (App Router), React, TanStack Table/Query
- Backend: ASP.NET Core 8 Web API
- Database: MySQL (XAMPP-compatible)
- Auth: JWT (HttpOnly cookie)
board_exam/
├── frontend/ # Next.js client app
└── backend/ # ASP.NET Core API + EF Core (MySQL)
- Authentication (login/logout/profile)
- Role-based access control (admin-focused management)
- Data management modules:
- Users
- Departments
- Programs
- Regions
- Schools
- Role statuses
- National passing rates
- Statistics data
- Compare data module
- Export/import support for statistics data
- Soft deletes in backend entities
- Lookup table-driven values (status/gender/roles)
- Node.js 18+
- pnpm
- .NET 8 SDK
- MySQL (XAMPP or standalone)
Update backend/appsettings.json:
{
"ConnectionStrings": {
"Default": "server=127.0.0.1;port=3306;database=board_exam;user=root;password="
}
}If your XAMPP MySQL runs on
3307, changeport=3307.
cd backend
dotnet restore
dotnet runAPI base:
http://127.0.0.1:5000/api/v1(based on launch settings)
Swagger (Development):
http://127.0.0.1:5000/swagger
The backend includes a startup seeder and DB self-healing retries. Default seed users include:
admin / admin123editor / editor123viewer / viewer123
Create frontend/.env.local:
NEXT_PUBLIC_API=http://127.0.0.1:5000/api/v1
NEXT_PUBLIC_TURNSTILE_SITE_KEY=Then run:
cd frontend
pnpm install
pnpm devFrontend app:
http://localhost:3000
- Login issues JWT cookie (
jwt) from backend. - Frontend sends credentials with API requests.
- In development, Turnstile can be bypassed if site key is not set.
All backend routes use:
api/v1/...
Examples:
api/v1/auth/loginapi/v1/auth/profileapi/v1/usersapi/v1/statistics-dataapi/v1/lookups
cd backend
dotnet build
dotnet watch runcd frontend
pnpm lint
pnpm dev- 401 on protected endpoints: Login first and ensure cookie-based requests are enabled.
- DB connection error: Verify MySQL host/port in
appsettings.json. - Port conflicts: Update backend launch settings or run with
--urls.
- Refresh tokens are not implemented yet (JWT session only).
- Role and status values are DB-managed via lookup tables.