An open-source operating system for student life — learning, productivity, and career growth, unified in one workspace.
StudentOS is a full-stack web application purpose-built for the student lifecycle. It brings academic organization, project tracking, internship management, career planning, and AI-assisted workflows into a single authenticated platform — replacing the spreadsheets, sticky notes, and disconnected apps most students rely on.
The project is in active development. The security infrastructure, data model, and authentication foundation are production-ready. Application features are being built on top of that foundation.
Repository: github.com/RahilAlam929/StudentOs
- What is StudentOS?
- Why StudentOS?
- Features
- How StudentOS Works
- Architecture
- Tech Stack
- Current State
- Prerequisites
- Local Development
- Authentication Design
- Database
- API Documentation
- Project Structure
- Environment Variables
- Contributing
- Roadmap
- License
Most students manage their academic life through a patchwork of tools: a calendar for deadlines, a spreadsheet for internship applications, a notes app for study material, a job board for opportunities, and a document editor for their resume. None of these tools share context, and none are designed with students in mind.
StudentOS is built to change that.
It is an open-source platform that models the entire student lifecycle in one data model and exposes it through one authenticated workspace. A student logs in once and gets access to their academic profile, study planning tools, project tracker, internship pipeline, career roadmap, and AI assistance — all connected, all aware of each other.
The platform is designed for undergraduate and postgraduate students who want structure, and for developers who want to contribute to or extend a well-architected open-source project.
Unified workspace. Learning, projects, internships, and career planning share a single data model and a single authenticated session. Your study plan knows what course you are in. Your internship tracker knows what stage of your degree you are at. Everything is connected.
AI as infrastructure, not a feature. The AI provider layer is designed from the start to be swappable: OpenAI, Gemini, or a local mock. Development works offline with mock responses. Production switches to a real provider with a single environment variable.
Open and extensible. The entire codebase is open source. The backend follows a consistent controller → service → repository pattern. New feature modules follow the same structure. Contributors can add a new domain without touching existing code.
Developer-first setup. Infrastructure is fully Dockerized. All configuration is environment-variable driven with sane local defaults. The API is self-documenting via OpenAPI/Swagger. You can have the backend running in under five minutes.
Honest by design. This README only documents what is real in the code. Planned features are clearly labeled as planned.
Features are organized by domain. Each item shows whether it is implemented, in progress, or planned.
| Feature | Status |
|---|---|
| User registration (email, password, academic profile) | Planned — DTOs and security layer ready |
| Login with email and password | Planned — security layer ready |
| JWT access token (Bearer header, 15 min TTL) | Infrastructure done |
| JWT refresh token (HttpOnly cookie, 7 day TTL) | Infrastructure done |
| Token refresh endpoint | Planned |
| Logout (cookie clear) | Planned |
| Role-based access control (STUDENT, ADMIN) | Infrastructure done |
| BCrypt password hashing | Done |
| Feature | Status |
|---|---|
| Academic profile (college, course, year, CGPA) | Planned — entity and DTOs ready |
| View and update profile | Planned |
| Feature | Status |
|---|---|
| Study planner | Planned |
| AI-generated study schedules | Planned |
| AI doubt solver for academic questions | Planned |
| Feature | Status |
|---|---|
| Task management | Planned |
| Deadline tracking | Planned |
| Notifications | Planned |
| Feature | Status |
|---|---|
| Career roadmap with skill tracking | Planned |
| Internship tracker (Kanban and table views) | Planned |
| Resume builder with AI feedback | Planned |
| Feature | Status |
|---|---|
| Project tracking and progress management | Planned |
| Feature | Status |
|---|---|
| Admin dashboard | Planned |
| User management | Planned |
When the full application is built, the intended student journey is:
Student visits StudentOS
|
v
Register or Log in
(email + password + academic details)
|
v
Authenticated Dashboard
(JWT access token in header, refresh token in cookie)
|
+-----+-----+----------+---------+
| | | | |
v v v v v
Study Tasks Career Internships Projects
Planner Roadmap Tracker Tracker
| | | | |
+-----+-----+----------+---------+
|
v
AI Assistant
(doubt solver, schedule generator, resume feedback)
|
v
Progress visible across all modules
Today, the authentication layer and data model are in place. The dashboard and feature modules are actively being built.
Browser
|
Next.js Frontend
(React 19 / TypeScript / Tailwind CSS)
|
HTTP + REST JSON
Authorization: Bearer <token>
|
Spring Boot REST API
(Java 21)
|
+------------+-------------+
| |
PostgreSQL 16 Redis 7
(primary data store) (planned: token
port 5432 blocklist, cache)
Backend is a stateless REST API. Spring Security enforces authentication on every request via a JWT filter. No server-side session is maintained — all state lives in the database and in the JWT payload.
Authentication uses a dual-token model. A short-lived access token (15 min) is sent as a Bearer header on every API request. A long-lived refresh token (7 days) is stored in an HttpOnly, SameSite=Lax cookie and is used only to issue new access tokens.
Frontend communicates exclusively via REST. The API base URL is injected via the NEXT_PUBLIC_API_URL environment variable.
Database schema is managed entirely by Flyway. No manual DDL is needed — running the backend applies all migrations automatically.
Redis is provisioned by Docker Compose and its Spring dependency is declared. Application code using Redis (token blocklist, caching) has not been written yet.
| Layer | Technology | Version |
|---|---|---|
| Frontend framework | Next.js (App Router) | 16.3.0 |
| Frontend language | TypeScript (strict) | 5 |
| UI styling | Tailwind CSS | v4 |
| Form handling | React Hook Form + Zod | 7 / 3 |
| Icons | lucide-react | latest |
| Backend framework | Spring Boot | 3.4.1 |
| Backend language | Java | 21 |
| Security | Spring Security + JJWT | 6 / 0.12.6 |
| Persistence | Spring Data JPA / Hibernate | — |
| Database migrations | Flyway | — |
| API documentation | springdoc-openapi | 2.7.0 |
| Database | PostgreSQL | 16-alpine |
| Cache / message | Redis | 7-alpine |
| Build tool | Maven Wrapper (./mvnw) |
— |
| Layer | Component | Status |
|---|---|---|
| Backend | Spring Boot 3.4.1 application entry point | Done |
| Backend | JWT infrastructure: JwtTokenProvider, JwtAuthenticationFilter |
Done |
| Backend | Spring Security: stateless filter chain, BCrypt, method security | Done |
| Backend | Role-based access control (STUDENT, ADMIN roles seeded by Flyway) | Done |
| Backend | User entity with UUID PK, JPA auditing, eager role + profile loading |
Done |
| Backend | StudentProfile entity (1:1 with User) |
Done |
| Backend | Role entity and RoleName enum |
Done |
| Backend | Repositories: UserRepository (EntityGraph), RoleRepository, StudentProfileRepository |
Done |
| Backend | DTOs (Java records): RegisterRequest, LoginRequest, AuthResponse, UserResponse, StudentProfileResponse, UpdateProfileRequest, RefreshTokenRequest |
Done |
| Backend | UserMapper: maps User entity → UserResponse DTO |
Done |
| Backend | GlobalExceptionHandler: ApiException, validation errors, bad credentials, generic 500 |
Done |
| Backend | OpenAPI/Swagger UI with Bearer JWT security scheme | Done |
| Backend | AI provider config: AiProperties (mock / openai / gemini, isMockMode()) |
Done |
| Backend | CORS config: configurable allowed origins via environment variable | Done |
| Backend | CookieUtil: set/clear/extract HttpOnly refresh token cookie |
Done |
| Backend | Flyway V1: creates roles, users, user_roles, student_profiles |
Done |
| Backend | Spring Actuator: /actuator/health exposed |
Done |
| Infrastructure | PostgreSQL 16-alpine via Docker Compose (healthcheck, named volume) | Done |
| Infrastructure | Redis 7-alpine via Docker Compose (healthcheck, named volume) | Done |
| Infrastructure | .env.example with all required variables and sensible local defaults |
Done |
| Component | Notes |
|---|---|
AuthController + AuthService |
/api/auth/** is permitted in SecurityConfig; no implementation exists |
UserController + UserService |
DTOs and entities are ready; no API layer |
| Redis application code | Dependency declared in pom.xml; no code uses it yet |
| AI service / client | AiProperties is wired; no service or HTTP client exists |
| All feature modules | Study planner, task manager, internship tracker, career roadmap, resume builder, etc. |
| Frontend application | Next.js scaffold only — no pages, components, or API client |
| Tests | No tests written; JUnit 5 and spring-security-test are on the classpath |
| CI/CD | .github/workflows/ant.yml uses Ant + JDK 11 — wrong build tool and Java version |
| Dockerfiles | No Dockerfile for backend or frontend; Docker Compose manages infrastructure only |
- JDK 21 — the Maven wrapper handles Maven itself, but the JDK must be installed
- Node.js 18+ and npm
- Docker and Docker Compose
Install on macOS:
brew install openjdk@21
brew install node
brew install --cask dockerVerify:
java -version # 21.x.x
node -v # 18.x.x or higher
docker --versiongit clone https://github.com/RahilAlam929/StudentOs.git
cd StudentOs
cp .env.example .envFor local development the defaults in .env.example work out of the box. Change JWT_SECRET to any long random string — the default is intentionally weak.
docker compose up -dWait for both containers to become healthy:
docker compose ps
# studentos-postgres running (healthy)
# studentos-redis running (healthy)cd backend
# Export the .env file so the JVM picks up the variables
set -a && source ../.env && set +a
./mvnw spring-boot:runFlyway applies migrations automatically on startup. The API is available at http://localhost:8080.
Verify:
curl http://localhost:8080/actuator/health
# {"status":"UP"}cd frontend
npm install
npm run devCreate frontend/.env.local to point at the backend:
NEXT_PUBLIC_API_URL=http://localhost:8080
The frontend starts at http://localhost:3000.
StudentOS uses a stateless dual-token model.
Client Server
| |
| POST /api/auth/register |
| { fullName, email, password, ... }|
|----------------------------------->|
| | BCrypt hash password
| | Create user + profile
| | Seed STUDENT role
| 200 { accessToken, user } |
| Set-Cookie: refreshToken=... |
|<-----------------------------------|
| |
| GET /api/users/me |
| Authorization: Bearer <token> |
|----------------------------------->|
| | JwtAuthenticationFilter validates token
| | Checks: signature, expiry, token type=access
| 200 { id, email, profile, roles } |
|<-----------------------------------|
| |
| POST /api/auth/refresh |
| Cookie: refreshToken=... |
|----------------------------------->|
| | Validates refresh token (type=refresh)
| | Issues new access token
| 200 { accessToken } |
|<-----------------------------------|
Access token
- JWT signed with HMAC-SHA
- Sent as
Authorization: Bearer <token>on every authenticated request - TTL: 15 minutes (configurable via
JWT_ACCESS_EXPIRATION_MS) - Claims:
sub(email),token_type="access",iat,exp
Refresh token
- JWT, same signing key
- Delivered as
HttpOnly,SameSite=Laxcookie namedrefreshToken - TTL: 7 days (configurable via
JWT_REFRESH_EXPIRATION_MS) - The
JwtAuthenticationFilterexplicitly rejects refresh tokens — token type is validated
Roles (STUDENT, ADMIN) are seeded by Flyway on first startup. @EnableMethodSecurity allows fine-grained @PreAuthorize checks on individual endpoints.
PostgreSQL runs on port 5432. Flyway applies migrations at every startup — no manual schema management needed.
Local development credentials (do not use in production):
| Parameter | Value |
|---|---|
| Host | localhost |
| Port | 5432 |
| Database | studentos |
| Username | studentos |
| Password | studentos |
Schema — V1
-- Seeded roles
roles (id UUID PK, name VARCHAR UNIQUE) -- 'STUDENT', 'ADMIN'
-- Core user record
users (id UUID PK, email VARCHAR UNIQUE, password_hash, full_name, enabled, created_at, updated_at)
-- Many-to-many join
user_roles (user_id → users, role_id → roles)
-- Academic profile (1:1 with user)
student_profiles (id UUID PK, user_id → users UNIQUE, college, course, year INT, cgpa NUMERIC(4,2), timestamps)Indexes
idx_users_email ON users(email)
idx_student_profiles_user_id ON student_profiles(user_id)Data persists across container restarts via the postgres_data named volume. To wipe all data:
docker compose down -v
docker compose up -dWhen the backend is running, Swagger UI is available at:
- Swagger UI: http://localhost:8080/swagger-ui.html
- OpenAPI JSON: http://localhost:8080/v3/api-docs
The spec includes a Bearer JWT security scheme. Once the auth endpoints are implemented, you can authenticate directly in the UI.
Public endpoints (no token required):
| Path | Notes |
|---|---|
POST /api/auth/register |
Register a new student account |
POST /api/auth/login |
Authenticate and receive tokens |
POST /api/auth/refresh |
Issue a new access token via refresh cookie |
POST /api/auth/logout |
Clear the refresh token cookie |
GET /actuator/health |
Service health check |
GET /swagger-ui.html |
API documentation |
GET /v3/api-docs |
Raw OpenAPI spec |
All other endpoints require a valid Authorization: Bearer <token> header.
StudentOS/
├── .env.example # all environment variables with local defaults
├── docker-compose.yml # PostgreSQL 16 + Redis 7
├── README.md
│
├── backend/
│ ├── pom.xml
│ ├── mvnw / mvnw.cmd # Maven wrapper
│ └── src/main/
│ ├── java/com/studentos/
│ │ ├── StudentOsApplication.java
│ │ ├── config/
│ │ │ ├── AppConfig.java # @EnableConfigurationProperties
│ │ │ ├── AiProperties.java # AI provider: mock / openai / gemini
│ │ │ ├── CorsProperties.java # configurable CORS allowed origins
│ │ │ ├── JwtProperties.java # JWT secret + TTL values
│ │ │ └── OpenApiConfig.java # Swagger/OpenAPI + Bearer scheme
│ │ ├── dto/
│ │ │ ├── RegisterRequest.java
│ │ │ ├── LoginRequest.java
│ │ │ ├── RefreshTokenRequest.java
│ │ │ ├── AuthResponse.java
│ │ │ ├── UserResponse.java
│ │ │ ├── StudentProfileResponse.java
│ │ │ ├── UpdateProfileRequest.java
│ │ │ └── UserMapper.java
│ │ ├── entity/
│ │ │ ├── User.java
│ │ │ ├── StudentProfile.java
│ │ │ ├── Role.java
│ │ │ └── RoleName.java # enum: STUDENT, ADMIN
│ │ ├── exception/
│ │ │ ├── ApiException.java
│ │ │ ├── ErrorResponse.java
│ │ │ └── GlobalExceptionHandler.java
│ │ ├── repository/
│ │ │ ├── UserRepository.java # EntityGraph eager-loads roles + profile
│ │ │ ├── RoleRepository.java
│ │ │ └── StudentProfileRepository.java
│ │ ├── security/
│ │ │ ├── SecurityConfig.java # filter chain, CORS, stateless session
│ │ │ ├── JwtAuthenticationFilter.java
│ │ │ ├── JwtTokenProvider.java
│ │ │ └── UserDetailsServiceImpl.java
│ │ └── util/
│ │ └── CookieUtil.java # HttpOnly cookie helpers
│ └── resources/
│ ├── application.yml
│ └── db/migration/
│ └── V1__init.sql
│
├── frontend/
│ ├── package.json
│ ├── tsconfig.json
│ ├── next.config.ts
│ └── src/app/
│ ├── layout.tsx # root layout (Next.js scaffold)
│ ├── page.tsx # home page (Next.js scaffold)
│ └── globals.css
│
└── .github/
└── workflows/
└── ant.yml # BROKEN: uses Ant + JDK 11 — needs replacement
Copy .env.example to .env. All variables have safe defaults for local development.
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
jdbc:postgresql://localhost:5432/studentos |
PostgreSQL JDBC URL |
DATABASE_USERNAME |
studentos |
PostgreSQL username |
DATABASE_PASSWORD |
studentos |
PostgreSQL password |
REDIS_HOST |
localhost |
Redis hostname |
REDIS_PORT |
6379 |
Redis port |
JWT_SECRET |
(weak default — change this) | HMAC signing key — must be a long random string in production |
JWT_ACCESS_EXPIRATION_MS |
900000 |
Access token TTL in ms (15 min) |
JWT_REFRESH_EXPIRATION_MS |
604800000 |
Refresh token TTL in ms (7 days) |
CORS_ALLOWED_ORIGINS |
http://localhost:3000 |
Comma-separated list of allowed CORS origins |
AI_PROVIDER |
mock |
AI backend: mock, openai, or gemini |
OPENAI_API_KEY |
(empty) | Required only when AI_PROVIDER=openai |
GEMINI_API_KEY |
(empty) | Required only when AI_PROVIDER=gemini |
NEXT_PUBLIC_API_URL |
http://localhost:8080 |
Backend API base URL (read by the frontend) |
Never commit real values for JWT_SECRET, OPENAI_API_KEY, or GEMINI_API_KEY. The .gitignore excludes .env.
The project is in its early phase and there is substantial work to be done. Contributions of all kinds are welcome — implementation, tests, documentation, and bug fixes.
- Fork the repository on GitHub.
- Clone your fork:
git clone https://github.com/<your-username>/StudentOs.git
cd StudentOs- Create a feature branch:
git checkout -b feature/auth-endpoints- Follow the Local Development guide to get the project running.
- Make your changes, then open a pull request against
main.
These are the most impactful items to work on right now, in order of priority:
- Implement
AuthController+AuthService— register, login, token refresh, logout. The security filter, DTOs, entities, and repositories are all ready. - Fix the GitHub Actions workflow — replace
.github/workflows/ant.ymlwith a Maven + JDK 21 workflow. - Implement
UserController+UserService— get profile, update profile (UpdateProfileRequestDTO is ready). - Write unit tests for
JwtTokenProvider— token generation, validation, expiry, type checking. - Write integration tests for the security filter chain — protected vs public endpoints.
- Set up the frontend API client — a fetch or axios wrapper that injects the Bearer token and handles 401 responses.
- Implement login and registration pages in the frontend.
Backend
- Package structure:
controller→service→repository. No business logic in controllers. - Configuration must use
@ConfigurationPropertiesclasses. No@Valueannotation. - DTOs must be Java records.
- All API error responses go through
GlobalExceptionHandlerusingApiExceptionandErrorResponse. - New database schema changes must be new Flyway migration files (
V2__description.sql,V3__description.sql). Never edit an existing migration file.
Frontend
- TypeScript strict mode — no
anytypes. - All components and hooks must be typed.
- Form validation uses React Hook Form + Zod.
.github/workflows/ant.ymluses Ant and JDK 11. The project uses Maven and JDK 21. The workflow has never been correct — it is the default GitHub template and has never been updated.spring-boot-starter-data-redisis declared inpom.xmlbut no application code uses Redis. The dependency should either be wired (token blocklist, caching) or removed until it is needed.
| Phase | Focus | Status |
|---|---|---|
| 1 | Foundation: security, JWT, entities, Flyway, Docker infrastructure | Done |
| 2 | Auth API: register, login, refresh, logout endpoints | Next |
| 3 | User profile API: read and update student profile | Planned |
| 4 | Frontend auth flow: login, registration, session management | Planned |
| 5 | Core features: study planner, task management | Planned |
| 6 | Career features: internship tracker, roadmap, resume builder | Planned |
| 7 | AI integration: doubt solver, schedule generation, resume feedback | Planned |
| 8 | Admin dashboard, notifications, production Dockerfiles, CI/CD | Planned |
This project does not yet have a license file. Until one is added, all rights are reserved by the author.
To discuss licensing for contribution or use, please open a GitHub issue.