A desktop application for managing passport appointments at Italian Questura offices, built as a university software engineering project.
This project delivers a complete JavaFX plus SQLite appointment-booking system for passport services at a questura, developed by a team of four. The implementation itself is desktop CRUD-style application. The engineering process around it includes: structured requirements, documented MVC architecture, Singleton/Repository/Facade patterns, UML artifacts (use case, activity, sequence, and ER diagrams), JUnit testing, CSV-seeded database bootstrap, Scrum-style sprint execution, and a full technical report.
This repository includes both the implementation and the submitted project report in Documentazione.pdf.
| Screenshot | Screenshot |
|---|---|
![]() |
![]() |
| Citizen login | Questore login |
![]() |
![]() |
| Booking flow: office selection | Booking flow: time selection |
![]() |
![]() |
| Questore panel: add availability | Questore panel: add citizen |
Passport Online streamlines passport-service scheduling between citizens and Questura staff.
- Citizens verify their identity, register, authenticate, and book available slots.
- Questura operators manage availabilities and add new verified citizens.
- Booking coherence is enforced to prevent invalid service states, such as requesting collection before issuance.
The application combines UI, domain rules, persistence, and validation in one production-style JavaFX desktop system.
- Screenshots
- Actors & Use Cases
- Use Case Details
- Architecture & Design
- Implementation
- Sequence Interactions
- Development Process
- Testing & Validation
- Getting Started
- Project Structure
- Documentazione Summary
- Authors
The system has two primary actors, each with a dedicated interface and authentication path.
Authenticated via admin-issued credentials. After login, the questore can:
- Insert new availability slots by providing
sede,tipologia,data, andora. - Insert new citizens into system registry (
Anagrafica) with personal details.
Self-registration is available only if the citizen already exists in the registry. After authentication, a citizen can:
- Book appointments selecting service type, office, date, and time.
- Cancel appointments, with cancellation logic preserving booking order.
- View active bookings, synchronized with current database state.
- A citizen cannot book collection without a prior issuance flow.
- Booking and cancellation logic prevents inconsistent sequencing.
- Availability views reflect real occupancy at calendar/day level.
At startup, the user chooses identity (citizen or questore) and is routed to the corresponding login page.
- Citizen verification checks if personal data exists in
Anagrafica. - If found and not already registered, account creation is allowed.
- If not found, registration is blocked until questore insertion.
Questore inserts a new slot with office, type, date, and hour. The slot immediately becomes available for booking.
- Select type.
- Select office.
- Select day in monthly calendar.
- Select time in day view.
- Confirm booking with requirements summary.
Cancellation follows the enforced lifecycle and targets the latest compatible booking to avoid out-of-order states.
- Java 17
- JavaFX (FXML + CSS)
- SQLite (JDBC)
- Maven Wrapper
- JUnit 5
The project follows MVC with clear role separation:
- Model: src/main/java/it/univr/passaporto/models/Model.java
- Controllers: src/main/java/it/univr/passaporto/controllers
- Views: src/main/resources/it/univr/passaporto
Key view/controller mappings:
loginCittadino.fxml->CitizenLogInloginQuestura.fxml->QuesturaLogIncitizenHome.fxml->CitizenHomequestHome.fxml->QuesturaHomecitizenVerify.fxml->CitizenVerifycitizenRegister.fxml->CitizenRegisterselectTipo.fxml->SelectTiposelectSede.fxml->SelectSedecalendar.fxml->CalendarcalendarDay.fxml->CalendarDayconfirmReservation.fxml->ConfirmReservationaddCitizen.fxml->AddCitizenaddDisponibilita.fxml->AddDisponibilita
- Singleton-style session coordination through
SessionandSessionManager. - Repository-like centralized data access through
Modelquery/update APIs. - Facade-style methods that hide complexity behind intent-focused operations (
populateDatabase(), availability queries, booking updates).
Main SQLite tables:
Anagrafica: citizen registryAccount_Cittadino: citizen accountsQuestore: staff credentialsDisponibilita: availability and booking occupancy
Database file and seed data:
- DB file: sqlite/passaporto.db
- Mock CSV sources: sqlite/mockup
The controllers validate input before data persistence:
- Email format validation
- Password strength checks
- Required-field checks
- Booking coherence constraints on issuance/collection flow
User -> LoginController -> Model authentication query
<- session data
-> route to CitizenHome / QuesturaHome
User -> CitizenVerifyController -> Model registry check
<- found / not found
-> CitizenRegisterController (if found and not registered)
User -> SelectTipo -> SelectSede -> Calendar -> CalendarDay -> ConfirmReservation
-> Model slot assignment update
Questore -> AddDisponibilitaController -> Model insert
<- success / validation error
The project followed an Agile/Scrum-inspired incremental workflow with short sprints.
- Sprint planning to define short-term goals and divide tasks.
- Iterative implementation with frequent integration.
- End-of-sprint verification rounds against use-case requirements.
- Continuous refinement of interaction flows and UI behaviors.
This approach improved visibility, accelerated feedback, and reduced integration risk.
- Authentication and registration checks with valid/invalid input.
- Input validation checks for empty/invalid formats.
- Booking and cancellation consistency checks.
- Data freshness verification against current database state.
Current JUnit classes:
- src/test/java/it/univr/passaporto/controllers/CitizenVerifyTest.java
- src/test/java/it/univr/passaporto/controllers/CalendarTest.java
Run tests:
./mvnw test- JDK 17+
- macOS, Linux, or Windows
./mvnw -DskipTests javafx:runIf Java is not detected in your shell, set JAVA_HOME to your JDK 17 path before running mvnw.
Seeded local credentials:
- Citizen:
asd/asd - Citizen:
claudiabianchi@hotmail.com/claudia - Questore:
asd/asd
.
├── .mvn/
├── mvnw
├── mvnw.cmd
├── pom.xml
├── Documentazione.pdf
├── sqlite/
│ ├── mockup/
│ └── passaporto.db
└── src/
├── main/
│ ├── java/
│ │ ├── module-info.java
│ │ └── it/univr/passaporto/
│ │ ├── Application.java
│ │ ├── controllers/
│ │ └── models/
│ └── resources/
│ ├── images/
│ └── it/univr/passaporto/
└── test/
└── java/it/univr/passaporto/controllers/
Documentazione.pdf includes:
- General scope and requirements for passport booking support.
- Use-case specifications for both actors.
- Activity diagrams for authentication, citizen flow, and questore flow.
- Architecture and implementation rationale (MVC, data-access strategy, sequencing).
- Development-process notes (iterative Scrum-based planning and delivery).
- Validation activities, including user testing and JUnit excerpts.
- Xiao Simone
- Zhou Flavio
- Wang William
- Zhou Jia Ye
- Giorgio
Project description submitted: Documentazione.pdf





