TVPSS Management Information System
Centralised system for managing school TV station operations across Johor. Role-based access for administrators, teachers, and student crews, covering scheduling, equipment inventory, and automated student onboarding workflows.
Tech Stack
Stakeholders
Johor State Education Dept.
System owner — state-level admin who manages all schools' TVPSS data and generates compliance reports
School Administrators
Per-school admin — manages teacher assignments, equipment inventory, and student crew rosters
Teachers / Crew Advisors
Manage production schedules and supervise student crew activities
Student Crews
End users — view their schedules and assigned roles via the student portal
Development Team (4 members)
Academic group project; Zafran led backend architecture and REST API design
The Problem
The Johor state education department managed dozens of school TV stations (TVPSS) through a fragmented system of emails, Excel sheets, and phone calls. Equipment tracking was unreliable, and student crew management had no audit trail.
The Solution
Designed a layered Java Spring Boot application with Hibernate ORM and a MySQL database. Three distinct role hierarchies (state admin, school admin, teacher/crew) each see tailored dashboards. RESTful API endpoints support scheduling, inventory CRUD, and a bulk-onboarding CSV import for student crews.
Architecture
Classic layered Spring Boot MVC application. Controller layer handles HTTP routing and input validation. Service layer contains business logic. Repository layer abstracts MySQL via Spring Data JPA / Hibernate. Thymeleaf renders server-side HTML views. REST endpoints coexist with MVC controllers for AJAX-powered dashboard widgets.
- 01
Controller Layer
Spring MVC @RestController and @Controller classes. Input validation via Jakarta Bean Validation. Role-based route protection via Spring Security with method-level @PreAuthorize annotations.
- 02
Service Layer
Business logic — scheduling conflict detection, inventory availability checks, CSV parsing for bulk student import. Transactional boundaries managed with @Transactional.
- 03
Repository Layer
Spring Data JPA repositories over Hibernate ORM. Custom JPQL queries for reporting aggregations. Optimistic locking on inventory records to prevent concurrent over-allocation.
- 04
Database (MySQL)
Normalised schema with tables for schools, users, equipment, schedules, and crews. Audit log table captures all state changes. Database migrations managed with Flyway.
- 05
Frontend (Thymeleaf)
Server-rendered HTML templates with Bootstrap 5 for layout. AJAX calls to REST endpoints for dynamic table filtering and dashboard charts (Chart.js).
Dev Setup
Prerequisites
- Java 21 (JDK)
- Maven 3.9+
- MySQL 8+
- IntelliJ IDEA (recommended)
# Creates tvpss_db and initial schema
# Set spring.datasource.url, username, password
# App runs on localhost:8080
Challenges
- 01
Designing a three-tier role hierarchy
State admin, school admin, and teacher/crew roles have overlapping but distinct data visibility. A state admin can see all schools; a school admin only their own; a teacher only their own schedules. Implemented with Spring Security's method-level security and service-layer ownership checks rather than pure database-level filtering, which kept the SQL simpler but required careful test coverage.
- 02
Bulk CSV import reliability
The client required importing 300+ student records from Excel exports. CSV parsing had to handle inconsistent column ordering, BOM characters, and duplicate entries. Built a multi-pass validator that first checks for structural errors, then for duplicates, and only writes to the DB if the entire batch is clean — giving a clear error report before any data is committed.
What I Learned
- 01
Spring Security's method-level @PreAuthorize is more maintainable than URL-based rules for complex role hierarchies.
- 02
Flyway database migrations from day one prevent the 'works on my machine' schema drift problem in team projects.
- 03
Transactional batch imports should validate entirely before writing — partial commits create worse state than a clean failure.
- 04
Optimistic locking is easy to add with JPA and prevents subtle concurrent-update bugs that only appear under real usage.