AcademicAcademic Project · Full-Stack Dev · 2023

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.

35%Reporting efficiency improvement
3-tierRole-based access control
0 emailsFor standard crew onboarding

Tech Stack

JavaSpring BootHibernateMySQLREST APIsThymeleaf

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.

  1. 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.

  2. 02

    Service Layer

    Business logic — scheduling conflict detection, inventory availability checks, CSV parsing for bulk student import. Transactional boundaries managed with @Transactional.

  3. 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.

  4. 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.

  5. 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)
bash — setup
$git clone https://github.com/zafransakowi/tvpss-mis && cd tvpss-mis
$mysql -u root -p < src/main/resources/schema.sql

# Creates tvpss_db and initial schema

$cp src/main/resources/application.example.properties src/main/resources/application.properties

# Set spring.datasource.url, username, password

$mvn spring-boot:run

# App runs on localhost:8080

$# Default admin login: admin@tvpss.edu.my / Admin1234!

Challenges

  1. 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.

  2. 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.