Skip to the content.

Architecture

A JavaFX desktop app in one Java module (com.bsmi.attendancesystem), with three layers: screens, services and DAOs. Each layer only calls the one below it.

The layers: FXML screens, controllers, services, DAOs and the H2 database, plus the phone scanner and startup

Startup and data folder

dao

The only code that runs SQL. Each DAO opens a connection through Database.open(), uses PreparedStatement with ? placeholders (so typed text can never become SQL), and closes everything with try-with-resources. An SQLException becomes an unchecked DataAccessException whose message names the operation, such as “delete course BCA”.

service

The rules, kept out of the controllers so they can be tested without a screen:

scanner

Lets a phone act as a card reader:

Controllers and FXML

The screens are FXML files in src/main/resources/com/bsmi/attendancesystem/fxml, styled by theme.css (color tokens) plus one stylesheet per screen. LoginController and DashboardController read the form fields, call a service, and show the result. They hold no SQL and no business rules.

Errors

Thrown by Type What the user sees
service ValidationException subclasses (MissingFieldException, AlreadyExistsException, StillInUseException, …) An error alert with the exception’s message, written for the user
scan field UnknownCardException, other ValidationExceptions The message in red under the scan field, no alert
scanner Bad token, a file that isn’t a photo, no QR code, too large 404, 415, 422 or 413 with a plain message on the phone
dao DataAccessException A “database error” alert; the app keeps running
startup DatabaseSetupException JavaFX stops the launch and prints the cause. A friendlier dialog is a known gap

Tests

Run all of them with ./mvnw verify.

Suite Covers
dao/*Test Each DAO against its own in-memory H2 with the real migrations: CRUD, not-found, duplicates, injection strings stored as plain text, closed connections
service/*Test Every validation rule and exception, every login outcome, photo copy and rejection, scan in/out/repeat, QR cards drawn and read back
scanner/*Test The phone server over real http: page, typed ID, card photo, wrong token, bad and oversized uploads, stop; address choice
AppPathsTest, DatabaseSettingsTest, DatabaseMigrationsTest, … Folder choice per OS, env variables, a fresh and an already-current database, a broken one
ui/*Test (TestFX, tagged ui) Login success and failure, form errors, course delete confirm/cancel, logout, the sidebar highlight, scanning a card, the phone pairing panel