Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Offside — Amateur Football League Management System

A full-stack web application for managing amateur football tournaments: teams, players, matches, results, and standings — with public browsing, user comments, and full admin management.

Originally built as a university project for the Sistemi Informativi su Web (Web Information Systems) course at Roma Tre University, Italy. The academic requirements were in Italian, so the application's UI and database content remain in Italian, while this documentation is in English for portfolio purposes.

Features

  • Browse tournaments, standings, fixtures, and results — no login required
  • Browse teams and squads, with pagination
  • Registered users can post and edit their own comments on matches
  • Full authentication and role-based authorization (public visitor / registered user / admin)
  • Admin dashboard: full CRUD for tournaments, teams, players, referees, and matches
  • Standings computed dynamically from match results
  • A React micro-frontend consuming a REST API for the live standings table
  • Custom UI (no template), consistent design system, responsive layout

Screenshots

Homepage: Home

Team detail: Team

Teams list (paginated): Teams

Tournament detail (standings, fixtures, results): Tournament

Tech Stack

Layer Technology
Backend Spring Boot 4 (Java 17)
Persistence JPA / Hibernate
Database PostgreSQL
Server-side views Thymeleaf
Client-side widget React (Vite)
Security Spring Security (form login, BCrypt password hashing)
Build Maven

Domain Model

Seven entities modeling the tournament domain:

Entity Key attributes Relationships
Tournament name, year, description many-to-many with Team
Team name, foundation year, city many-to-many with Tournament, one-to-many with Player
Player name, surname, date of birth, role, height many-to-one with Team
Referee name, surname, referee code one-to-many with Match
Match date, venue, home/away goals, status (SCHEDULED/PLAYED) many-to-one with Tournament, two teams, and a referee
User username, password (BCrypt), role (USER/ADMIN) one-to-many with Comment
Comment text, date many-to-one with User and Match

The Comment entity emerged during analysis: it wasn't in the original entity list but was required by the use cases "view comments" and "add/edit a comment on a match".

Architecture

Classic layered architecture, following separation of concerns:

Browser -> Controller -> Service -> Repository -> Database

  • Controller — handles HTTP requests, delegates to services, never contains business logic
  • Service — business logic, validation rules, transaction boundaries (@Transactional)
  • Repository — Spring Data JPA interfaces, derived queries plus custom JPQL
  • Security — Spring Security filter chain, role-based access (public / user / admin), UI-level hiding combined with server-side endpoint protection

DTOs are used for all REST API responses to avoid exposing JPA entity internals and bidirectional relationship cycles during JSON serialization.

Performance: LAZY vs EAGER fetching (N+1 problem)

As part of the coursework, I benchmarked two fetching strategies for loading teams with their players (30 teams x 4 players):

Strategy Queries executed Time
LAZY (naive, N+1 problem) 31 218 ms
JOIN FETCH (targeted JPQL) 1 37 ms

JOIN FETCH was about 6x faster. I kept LAZY as the default fetch type across the codebase and used a targeted JOIN FETCH query only for the specific use case that needed it, rather than switching to FetchType.EAGER globally, which would have loaded player data even where it isn't needed.

Getting Started

  1. Create a PostgreSQL database named "offside"
  2. Configure src/main/resources/application.properties with your DB credentials
  3. Run the application:

The app runs on http://localhost:8080.

React widget (optional, for development)

cd frontend npm install npm run dev Runs on http://localhost:5173. The production build is already bundled into src/main/resources/static/app/.

Test Credentials

Role Username Password
Admin admin admin123

Known Limitations

  • No optimistic locking (@Version): concurrent edits by two admins on the same entity are not detected.
  • OAuth login and cloud deployment were considered as optional bonus features but not implemented, in favor of consolidating the core requirements.

Author

Tamer Omar — Computer Engineering and AI student, Roma Tre University

About

Per gestire tornei di calcio amatoriale: squadre, calendari, risultati e classifiche in un unico posto.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages