Skip to main content

PMB 2025 Backend - Documentation

Document Status
Document OwnerProduct Engineering 2026Product Engineering 2026
Contributors
Project Linkshttps://github.com/RistekCSUI/pmb2025-backendhttps://github.com/RistekCSUI/pmb2025-backend
Project Linkshttps://pmb.cs.ui.ac.idhttps://pmb.cs.ui.ac.id
Project LinksSentry (https://o1164500.ingest.sentry.io)Sentry (https://o1164500.ingest.sentry.io)
TeamTheodore Kevin Himawantheodore.kevin@ristek.cs.ui.ac.id
TeamAri Darrell Muljonodarrell@ristek.cs.ui.ac.id
TeamGrace Karinagracekarin@ristek.cs.ui.ac.id
TeamYeshua Marco G. Manurungmarco@ristek.cs.ui.ac.id

πŸ”Ž Background

Overview​

The PMB 2025 Backend is the core API service powering the RISTEK PMB (Penerimaan Mahasiswa Baru) platform. It manages the entire new-student onboarding experience including SSO-based authentication, user profiles, group assignments (kelompok besar), peer matching ("pansos"/friendship puzzles), assignment submissions, leaderboards, badges, events, QR code interactions, and an admin panel for committee members to manage all entities.

Stakeholders​

Scope & Boundaries​

  • In Scope: User authentication (SSO/LDAP/SSO Proxy), user profile management, kelompok besar grouping, friendship/invitation system, puzzle matching, senior review, assignment & submission CRUD, leaderboards (individual & group), badge system, events & carousel management, QR code generation/matching, admin panel APIs, S3 file uploads, Data Science integration for interest recommendations.
  • Out of Scope: Frontend applications, email delivery, Data Science model training, infrastructure provisioning.

βš™οΈ Architecture & Design

System Diagram​

Architecture Decisions (ADRs)​

  • Language/Framework: TypeScript / Node.js (β‰₯12) / Express 4.x
  • ORM: Prisma 4.x with PostgreSQL
  • Database: PostgreSQL 13.3 (relational data), Redis 6.2.4 (caching & sessions), Redis DS (Data Science service communication)
  • Communication: Synchronous RESTful API over HTTP with JWT-based authentication (Authorization: JWT <token>)
  • File Storage: AWS S3 with presigned URLs for uploads/downloads
  • Error Monitoring: Sentry with tracing integration
  • Template Engine: EJS (for SSO callback token handoff via window.postMessage)
  • Infrastructure: Docker + Docker Compose (dev), AWS ECR + Pusilkom (staging/production), Elastic Beanstalk (legacy deploy)

πŸ’»Technical Specifications

API Documentation​

All routes are prefixed under /api. Authentication uses Authorization: JWT <token> headers.

Public Endpoints (No Auth)​

MethodPathbDescription
GET/Health check (returns ok)
GET/api/auth/loginSSO UI login (redirects to CAS, returns token via EJS callback)
POST/api/auth/ldapLDAP / SSO Proxy login (username + password)
POST/api/auth/addUserRegisterRegister user by NPM
GET/api/auth/selfGet current user from Bearer token
GET/api/eventsList all events
GET/api/events/:idGet event detail
GET/api/carouselList carousel items

User Endpoints (JWT Auth)

MethodPathDescription
GET/api/common/generate-put-urlGenerate S3 presigned upload URL
GET/api/common/generate-get-urlGenerate S3 presigned download URL
GET/api/token/checkCheck token validity
POST/api/token/generateGenerate user token
POST/api/token/postStore token
GET/api/assignmentList user assignments
GET/api/assignment/:idGet assignment detail
POST/api/assignment/:id/submissionSubmit assignment
PUT/api/assignment/submission/:idUpdate submission
POST/api/assignment/createassignmentCreate assignment
PUT/api/assignment/updateassignment/:idUpdate assignment
GET/api/profile/:usernameGet user profile
POST/api/profile/onboardingComplete user onboarding (with authorization check)
PUT/api/profile/update/:usernameUpdate user profile
GET/api/leaderboardGet leaderboard
GET/api/leaderboard/:idGet leaderboard entry by username
GET/api/leaderboard_kelompokGet group leaderboard
GET/api/leaderboard_kelompok/:idGet group leaderboard entry
GET/api/invitation/is_friend/:usernameCheck friendship status
GET/api/invitation/invitation_request/:usernameCheck invitation request
GET/api/invitation/sent_listList sent invitations
GET/api/invitation/received_listList received invitations
POST/api/invitation/create_invitationCreate friendship invitation
POST/api/invitation/accept_invitationAccept friendship invitation
GET/api/puzzleList puzzles
GET/api/puzzle/:idGet puzzle detail
POST/api/puzzle/submitSubmit puzzle answer
PUT/api/puzzle/updateUpdate puzzle
GET/api/seniorList seniors
GET/api/senior/:idGet senior detail
PUT/api/senior/:idUpdate senior
GET/api/interestList interests
GET/api/interest/recomendationGet interest recommendations (DS integration)
POST/api/interest/registerRegister user interests
GET/api/badgeList all badges
GET/api/badge/ownedList owned badges
GET/api/badge/detail/:badgeIdGet badge detail
GET/api/messageGet user messages
POST/api/qr/match/:idMatch QR code
POST/api/qr/generateQRGenerate QR code
POST/api/qr/generateTokenGenerate QR token
POST/api/qr/refreshRefresh QR token

Admin Endpoints (Admin JWT Auth)

MethodPathDescription
POST/api/admin/loginAdmin login
POST/api/admin/registerAdmin registration
POST/api/admin/verifyVerify admin account
GET/POST/api/admin/messageAdmin message CRUD
GET/POST/PUT/DELETE/api/admin/user(/:id)User management (filter, sort, paginate)
GET/POST/PUT/DELETE/api/admin/assignment(/:id)Assignment management
GET/POST/PUT/DELETE/api/admin/kelompok_besar(/:id)Kelompok besar management
GET/POST/PUT/DELETE/api/admin/friends(/:id)Friends management
GET/POST/PUT/DELETE/api/admin/senior(/:id)Senior review management
GET/POST/PUT/DELETE/api/admin/puzzle(/:id)Puzzle management
GET/POST/PUT/DELETE/api/admin/maba_review(/:id)Maba review management
GET/POST/PUT/DELETE/api/admin/question(/:id)Question management
GET/POST/PUT/DELETE/api/admin/question_for_maba(/:id)Question for maba management
GET/POST/PUT/DELETE/api/admin/user_interest(/:id)User interest management
GET/POST/PUT/DELETE/api/admin/kelompok_besar_mapping(/:id)Kelompok mapping management
GET/POST/PUT/DELETE/api/admin/submission(/:id)Submission management
GET/POST/DELETE/api/admin/owned_badge(/:id)Owned badge management
GET/api/admin/badgeBadge list/detail
GET/POST/PUT/DELETE/api/admin/events(/:id)Events management
GET/api/admin/events/generate-put-urlS3 upload URL for events
GET/POST/PUT/DELETE/api/admin/carousel(/:id)Carousel management
GET/api/admin/carousel/generate-put-urlS3 upload URL for carousel
GET/POST/PUT/DELETE/api/admin/leaderboard(/:id)Leaderboard management
GET/POST/PUT/DELETE/api/admin/leaderboard_kelompok(/:id)Group leaderboard management

Data Model/Schema​

Core entities managed via Prisma ORM. All models reside in prisma/schema.prisma.

ModelPurposeKey Fields
AdminCommittee/admin usersusername, password, role, is_verified
UserStudent profilesusername, nama_lengkap, jurusan, angkatan, kelompok_id, foto_profil, domicile, social links
AssignmentAssignments with deadlinesnamaAssignment, dueDate, startDate, description, link
SubmissionUser submissions for assignmentsfileAWSKey, submitTime, submitLink, feedback, FK to Assignment + User
Kelompok_BesarLarge groups with scoresnama, skor
Kelompok_Besar_MappingNPM β†’ group assignmentnpm (PK), username, FK to Kelompok_Besar
FriendsMaba–maba / maba–senior friendshipssender, receiver, liked, is_puzzle, unique constraint on sender+receiver
Senior_ReviewSenior review on friendshipsend, received, status, message, feedback, status_code
PuzzleFriendship puzzle pairsmaba_sender, maba_receiver, is_same_group, FK to Friends
Maba_ReviewMaba review for puzzlestatus, photo, feedback, submitted_at, FK to Puzzle
QuestionReview questionsquestion
Question_For_MabaAnswers to review questionsanswer, is_correct, FK to Question + Maba_Review
InterestInterest categoriesnama_interest, is_it (IT-related flag)
User_InterestUser–interest mappingFK to User + Interest
PMB_BadgeBadge definitionsname, description, logo, preview
Owned_BadgeUser–badge ownershipComposite PK (userId, badgeId), created_at
MessageAdmin β†’ user messagescontent, created_at, FK to Admin (sender) + User (recipient)
User_QRQR code tokensqr_token, token, FK to User
EventEvents listingnamaEvent, namaOrganizer, location, isInternal, dateTime, image
CarouselHomepage carousel itemsdescription, image
LeaderboardPer-user monthly scoresusername, score, month (unique on username+month)
Leaderboard_KelompokPer-group monthly scoresnama_kelompok, score, month (unique on nama_kelompok+month)

Project Structure​

pmb2025-backend/
β”œβ”€β”€ .github/
β”‚ └── workflows/
β”‚ └── build.yml # CI/CD: manual dispatch β†’ AWS ECR (prod/staging)
β”œβ”€β”€ prisma/
β”‚ β”œβ”€β”€ migrations/ # 33 Prisma migration files
β”‚ β”œβ”€β”€ schema.prisma # Database schema definition
β”‚ β”œβ”€β”€ schema.sql # Raw SQL schema export
β”‚ └── seed.ts # Database seeding script
β”œβ”€β”€ views/
β”‚ └── index.ejs # SSO callback template (token handoff via postMessage)
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ server.ts # Express app setup, CORS, Sentry, routes, port binding
β”‚ β”œβ”€β”€ sso.ts # Custom Passport strategy for UI SSO CAS
β”‚ β”œβ”€β”€ orgcode.ts # Faculty/major mapping by UI org code
β”‚ β”œβ”€β”€ controller/ # Request handlers
β”‚ β”‚ β”œβ”€β”€ admin/ # 17 admin controllers (user, assignment, puzzle, etc.)
β”‚ β”‚ β”œβ”€β”€ auth.ts # SSO login, LDAP login, self, register
β”‚ β”‚ β”œβ”€β”€ assignment.ts # Assignment & submission logic
β”‚ β”‚ β”œβ”€β”€ profile.ts # Profile CRUD + onboarding
β”‚ β”‚ β”œβ”€β”€ invitation.ts # Friendship invitation system
β”‚ β”‚ β”œβ”€β”€ puzzle.ts # Puzzle matching
β”‚ β”‚ β”œβ”€β”€ senior.ts # Senior review
β”‚ β”‚ β”œβ”€β”€ interest.ts # Interest registration + DS recommendations
β”‚ β”‚ β”œβ”€β”€ badge.ts # Badge system
β”‚ β”‚ β”œβ”€β”€ leaderboard.ts # Individual leaderboard
β”‚ β”‚ β”œβ”€β”€ leaderboard_kelompok.ts # Group leaderboard
β”‚ β”‚ β”œβ”€β”€ message.ts # User messaging
β”‚ β”‚ β”œβ”€β”€ qr.ts # QR code generation/matching
β”‚ β”‚ β”œβ”€β”€ carousel.ts # Carousel items
β”‚ β”‚ β”œβ”€β”€ events.ts # Events listing
β”‚ β”‚ β”œβ”€β”€ file.ts # S3 file operations
β”‚ β”‚ └── token.ts # Token management
β”‚ β”œβ”€β”€ service/ # Business logic layer
β”‚ β”‚ β”œβ”€β”€ admin/ # 17 admin services
β”‚ β”‚ └── (user-facing services matching controllers)
β”‚ β”œβ”€β”€ repository/ # Data access layer (Prisma queries)
β”‚ β”‚ β”œβ”€β”€ admin/ # 17 admin repositories
β”‚ β”‚ └── (user-facing repositories matching controllers)
β”‚ β”œβ”€β”€ routes/ # Express route definitions
β”‚ β”‚ β”œβ”€β”€ admin/ # 18 admin route modules
β”‚ β”‚ β”œβ”€β”€ route.ts # Root router aggregating all sub-routes
β”‚ β”‚ └── (user-facing route modules)
β”‚ β”œβ”€β”€ middleware/
β”‚ β”‚ β”œβ”€β”€ auth.ts # User JWT verification middleware
β”‚ β”‚ β”œβ”€β”€ admin/auth.ts # Admin JWT verification middleware
β”‚ β”‚ β”œβ”€β”€ admin.ts # Role check (panitia)
β”‚ β”‚ └── authorization.ts # Username ownership verification
β”‚ β”œβ”€β”€ libs/
β”‚ β”‚ └── zod/
β”‚ β”‚ β”œβ”€β”€ schema/profile.ts # Zod schema for profile validation
β”‚ β”‚ └── validator/validator.ts # Zod validation middleware
β”‚ └── util/
β”‚ β”œβ”€β”€ const.ts # DS service URLs and token from env
β”‚ β”œβ”€β”€ headers.ts # Content-Range / X-Total-Count headers (React Admin)
β”‚ β”œβ”€β”€ listrouter.ts # Dev-time route listing utility
β”‚ β”œβ”€β”€ prisma.ts # Prisma client singleton
β”‚ β”œβ”€β”€ redis.ts # Redis client for general caching
β”‚ └── redis-ds.ts # Redis client for Data Science service
β”œβ”€β”€ Dockerfile # Multi-stage Node 16 build
β”œβ”€β”€ docker-compose.yml # PostgreSQL 13.3 + Redis 6.2.4 for local dev
β”œβ”€β”€ deploy.sh / deploy.bat # Elastic Beanstalk deploy scripts
β”œβ”€β”€ nodemon.json # Dev server config (ts-node)
β”œβ”€β”€ tsconfig.json # TypeScript configuration
β”œβ”€β”€ .eslintrc # ESLint configuration
β”œβ”€β”€ .prettierrc # Prettier configuration
β”œβ”€β”€ .env.example # Environment variable template
└── package.json # Dependencies and scripts

Components​

LayerPathsResponsibility
Express Serversrc/server.tsSets up the Express application with CORS (whitelisted origins for PMB frontend, admin panel, gamble, and pansos subdomains), Passport initialization, Sentry error monitoring with tracing, Morgan request logging, and mounts all routes under /api.
SSO Authenticationsrc/sso.ts, src/controller/auth.tsCustom Passport strategy that integrates with UI SSO CAS (sso.ui.ac.id/cas2). Validates CAS tickets, extracts student data (name, NPM, faculty/major via org code mapping), and issues JWT tokens. Supports three auth flows: SSO UI (CAS redirect), LDAP (direct POST to sso.ristek.cs.ui.ac.id), and SSO Proxy (POST to proxy.sso.ristek.cs.ui.ac.id). Can block non-maba logins via BLOCK_NON_MABA env var.
User JWT Middlewaresrc/middleware/auth.tsExtracts and verifies JWT from Authorization: JWT <token> header using SECRET. Decodes payload containing username, nama_lengkap, angkatan, and id.
Admin JWT Middlewaresrc/middleware/admin/auth.tsSame JWT pattern but verifies against SECRET_ADMIN. Decodes payload containing username and role.
Authorization Middlewaresrc/middleware/authorization.tsEnsures the authenticated user can only modify their own profile by matching req.user.username against route params/query/body.
Controller β†’ Service β†’ Repository Layerβ€”Follows a clean three-layer architecture. Controllers handle HTTP request/response, services contain business logic, and repositories encapsulate Prisma database queries. Both user-facing and admin modules follow this pattern across 17+ feature domains.
Admin Panel Supportsrc/util/headers.tsGenerates Content-Range and X-Total-Count response headers to support React Admin's data provider pagination interface.
S3 File Operationssrc/controller/file.tsGenerates presigned PUT/GET URLs using AWS SDK v3 for secure file uploads and downloads to S3.
Data Science Integrationsrc/util/const.ts, src/util/redis-ds.tsCommunicates with the DSAI recommendation service via a dedicated Redis instance and HTTP endpoints for interest-based recommendations.
QR Code Systemsrc/controller/qr.tsGenerates QR codes and tokens for in-person event interactions using the qrcode and nanoid libraries.

☁️ Operational Playbook

Infrastructure​

  • Cloud Provider: AWS (ECR for container registry) + Pusilkom instance
  • CI/CD: GitHub Actions (.github/workflows/build.yml), manual workflow dispatch for production (stable tag) and staging (latest tag) builds, pushed to AWS ECR (638207107223.dkr.ecr.ap-southeast-1.amazonaws.com/pmb-backend)
  • Container: Docker (Node 16 multi-stage build), runs prisma migrate deploy on startup
  • Legacy Deploy: Elastic Beanstalk via deploy.sh / deploy.bat
  • Link: https://pmb.cs.ui.ac.id

Environment Variables​

(example)

KeyDescriptionDefault (Dev)Sensitive?
PORTServer listening port8000No
DATABASE_URLPostgreSQL connection stringβ€”Yes
BASE_URLBase URL for SSO callbackhttp://localhost:8000No
REDIS_URLMain Redis connection stringβ€”Yes
SECRETJWT secret for user tokensβ€”Yes
SECRET_ADMINJWT secret for admin tokensβ€”Yes
AWS_ACCESS_IDAWS S3 access key IDβ€”Yes
AWS_SECRET_KEYAWS S3 secret access keyβ€”Yes
AWS_S3_BUCKETS3 bucket nameβ€”No
NODE_ENVEnvironment (development / production)developmentNo
PMB_YEARCohort year for maba filtering2025No
BLOCK_NON_MABABlock non-maba SSO login (yes/no)β€”No
AUTH_PROVIDERAuth provider (ldap / sso-proxy)β€”No
DEADLINE_MAMaba deadline timestampβ€”No
DEADLINE_MMMaba matching deadline timestampβ€”No
DS_POST_URL_PRODData Science POST URL (production)β€”No
DS_POST_URL_DEVData Science POST URL (development)β€”No
DS_FETCH_URL_PRODData Science fetch URL (production)β€”No
DS_FETCH_URL_DEVData Science fetch URL (development)β€”No
DS_TOKENData Science API tokenβ€”Yes
REDIS_DS_URL_PRODDS Redis URL (production)β€”Yes
REDIS_DS_URL_DEVDS Redis URL (development)β€”Yes
POSTGRES_USERDocker Compose PostgreSQL userβ€”Yes
POSTGRES_PASSWORDDocker Compose PostgreSQL passwordβ€”Yes
POSTGRES_DBDocker Compose PostgreSQL database namepmbNo
REDIS_PASSWORDDocker Compose Redis passwordβ€”Yes

πŸ™‹Questions

πŸ—’ List of frequently asked questions or question that need to be answered that is related to this initiative ..