Software Engineer
Java & Backend Projects
Java projects evolving from console workflows into a packaged desktop application with persistence (SQLite), search/sort UX, unit tests, and packaging.
Navigate by software-engineering skill:
Back to ProjectsMore Java & backend work
This tracker is built in stages (1–5). Each stage adds a concrete feature: persistence, UI, database, tests, and packaging.
- Job Application Tracker (Stages 1–5) — console → Swing UI → SQLite → Search/Sort + tests + packaging.
- Other Java / backend experiments
Job Application Tracker
A staged Java project that progresses from a console tracker to a packaged desktop application.
- Stage 1: Console CRUD + status workflow + CSV export.
- Stage 2: CSV load/save persistence.
- Stage 3: Swing desktop UI (Add/Update/Delete + filter + CSV controls).
- Stage 4: SQLite persistence (JDBC + schema/init).
- Stage 5: Search + sort controls, basic unit tests (JUnit 5).
- Architecture: UI/Entry → Service → Repository → Persistence (CSV → SQLite via JDBC).
- Core stack: Java 17+, Maven, Swing UI, SQLite (sqlite-jdbc).
- Data model:
JobApplication+ApplicationStatusenum (typed workflow). - Quality: validation + clearer UI messaging; JUnit 5 tests for service/repository behavior.
- Distribution: packaged for macOS using
jpackage(DMG).
Helpdesk Ticket Triage System
A staged helpdesk ticketing project focused on backend fundamentals: a structured ticket lifecycle, repository patterns, and API design. Built in phases to evolve from a console workflow into a REST-backed system.
- Stage 1: Console CRUD + ticket workflow + basic search + SQLite persistence.
- Stage 2: Spring Boot REST API + Swagger/OpenAPI docs + in-memory repository + Bean Validation + centralized error handling + Bruno API testing.
- Stage 3: Spring Data JPA persistence + H2 database + H2 Console + Actuator health endpoint (DB-backed CRUD).
- API Layer: Spring MVC
TicketControllerexposes CRUD endpoints under/api/tickets. - OpenAPI: Swagger UI generated via springdoc OpenAPI for interactive endpoint documentation and testing.
- DTO Mapping: Request/response DTOs mapped via
TicketMapperto keep the domain model clean. - Workflow: Status + priority modeled with typed enums (
TicketStatus,Priority). - Storage (Stage 2):
TicketRepository+InMemoryTicketRepositoryfor memory-backed storage. - Persistence (Stage 3): Spring Data JPA repository backed by an H2 database for real CRUD persistence.
- H2 Console: Inspect the database directly at
/h2-console(confirm rows exist / updates persist). - Validation: Bean Validation on request DTOs to reject invalid payloads early.
- Error Handling: Centralized exception mapping via
GlobalExceptionHandlerreturning consistentApiErrorJSON. - API Testing: Bruno collection for repeatable local CRUD requests using a
{{baseUrl}}environment variable. - Observability: Spring Boot Actuator health endpoint at
/actuator/health.
OAuth2 Bookmark API
A self-contained Spring Boot service that both issues and validates its own JWTs, built in stages from an open REST API into a secured, multi-user app — focused on OAuth2, the Bruno API client, and IntelliJ IDEA Ultimate.
- Stage 1: REST API (CRUD) + in-memory store + Bean Validation + Bruno collection + JUnit/MockMvc tests.
- Stage 2: Self-contained OAuth2 — Spring Authorization Server issues JWTs (client_credentials) + Resource Server protects the API by scope.
- Stage 3: Spring Data JPA + H2 persistence (file mode) + bulk-create endpoint.
- Stage 4: User login — authorization_code + PKCE, login page + users, per-user bookmark ownership.
- Stage 5: Ship it — multi-stage Docker image, Kubernetes manifests, a Helm chart, and a live deploy to GKE Autopilot on Google Cloud.
- Stage 6: The same container on Cloud Run — a public HTTPS service that scales to zero, so the demo below is permanently live.
Live demo sign-in: john / password (demo accounts, no real data).
It scales to zero, so the first request may take a few seconds to wake.
- Authorization Server: Spring Authorization Server issues signed JWT access tokens at
/oauth2/token. - Resource Server: validates JWTs and maps scopes to authorities (
SCOPE_bookmark.read/write). - Grants:
client_credentials(app-to-app) andauthorization_code+ PKCE (browser user login). - Security chains: separate filter chains for the auth server, the stateless JWT API (
/api/**), and browser form login. - Per-user ownership: each bookmark is owned by the token
sub; every query is scoped to the caller (another user's id returns 404). - Persistence: Spring Data JPA + H2 (file mode), idempotent seeding, and a bulk-create endpoint with per-element validation.
- API testing: git-versioned Bruno collection — token request, Bearer calls, and the authorization-code login flow.
- Containerisation: multi-stage
Dockerfile(Maven+JDK builds the jar, a slim Alpine JRE ships it), non-root numeric UID, andMaxRAMPercentageso the JVM respects the container's memory limit. - Kubernetes: raw Deployment/Service manifests first, then the same resources as a Helm chart —
values.yaml, named-template helpers, and conditional Secret/HPA/Ingress templates. - Health probes: startup / liveness / readiness wired to Spring Boot Actuator's Kubernetes probe endpoints (
/actuator/health/livenessand/readiness). - Deployed to GKE: image pushed to Artifact Registry and released to a GKE Autopilot cluster with
helm upgrade --install; rollout and rollback verified viahelm history. - Also on Cloud Run: the identical image runs as a public HTTPS service that scales to zero — chosen for the permanent demo because a Kubernetes cluster bills continuously while Cloud Run costs nothing idle.
- Running behind a proxy: Cloud Run terminates TLS at the edge, so
server.forward-headers-strategyis required — without it the OAuth2 issuer and discovery document advertisehttp://on anhttps://site and the browser login flow breaks. - Environment-driven OAuth: redirect URIs come from configuration rather than being hard-coded, so the same build serves localhost, Kubernetes, and Cloud Run.
- Tooling: built and run in IntelliJ IDEA Ultimate (Maven, bundled JDK, Database tool for H2).