Skip to content

SerenePrince/java-dictionary

Repository files navigation

Java Dictionary

CI MIT License Java Spring Boot PostgreSQL Docker

A personal Java interview-prep tool. Build a glossary of Java concepts, track where each definition came from, and work through a structured book-based learning roadmap — all in one place.


What It Does

Java Dictionary is a personal interview-prep tool for building a glossary of Java concepts. Each term stores two definitions — a casual one (your own mental model) and a formal one (the polished, interviewer-ready answer) — because writing both is what builds real understanding, not just memorization. Terms are grouped by name across source books and chapters, so the same concept can appear multiple times as your understanding evolves, and you can add terms manually outside of any book.


Features

  • Create, edit, and delete terms manually
  • Flat term model: each entry has a casual and formal definition, a source (book + chapter), and tags
  • Multiple entries per term name — one per source, grouped together for display
  • Tag entries for categorization and filtering
  • Filter and search terms by keyword, tag, or source book
  • Learning Roadmap — a YAML-driven structured path through Java fundamentals, with curated resources and research hints for each term; submit definitions directly from the roadmap without leaving the page
  • Duplicate protection — manual terms deduplicated by name, book-sourced terms by (name, book, chapter)
  • Smart delete redirect — stays on the group page if other entries exist, returns to index if the last one is deleted
  • REST API with OpenAPI/Swagger UI documentation
  • Thymeleaf-rendered UI
  • Schema version control via Flyway

Getting Started

Prerequisites

  • Java 21
  • Maven (or use the included ./mvnw wrapper — no separate install needed)
  • Docker Desktop

1. Clone the repo

git clone https://github.com/SerenePrince/java-dictionary.git
cd java-dictionary

2. Start PostgreSQL

Make sure Docker Desktop is running. If this is your first project, create the shared container once:

docker run -d \
  --name postgres \
  --restart unless-stopped \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  postgres:18

Then create the database for this project:

docker exec -it postgres psql -U postgres -c "CREATE DATABASE dictionary;"

The container starts automatically with Docker Desktop — no manual restarts needed.

3. Run

./mvnw spring-boot:run

The app starts on http://localhost:8080. Flyway runs the schema migrations automatically — no manual setup needed.

Running Tests

./mvnw test

Tests use Mockito for unit tests and @WebMvcTest for controller slice tests. No database connection required.

Flyway Repairs

If you ever need to repair the schema history (e.g. after editing a migration file that was already applied):

./mvnw flyway:repair

Tech Stack

Layer Technology
Framework Spring Boot 4
Language Java 21
Frontend Thymeleaf + Bootstrap 5
Database PostgreSQL 18
Migrations Flyway
Build Tool Maven
API Docs SpringDoc OpenAPI (Swagger UI)

The decision to use Thymeleaf instead of a separate frontend framework was intentional. This project demonstrates Spring Boot end-to-end — backend, templating, data layer, all of it.


Spring Profiles

The app uses Spring profiles to separate local and production configuration:

Profile File When it's used
dev application-dev.properties Local development
prod application-prod.properties Deployment / production

application.properties holds shared settings common to both profiles. The dev profile is active by default — no flags needed to run locally.

Prod profile — set the following as secrets in your deployment service:

SPRING_PROFILES_ACTIVE=prod
DB_URL=jdbc:postgresql://<host>:<port>/<database>
DB_USERNAME=your_db_username
DB_PASSWORD=your_db_password

API Reference

Base path: /api/v1/terms

Method Endpoint Description
GET /api/v1/terms Get all term groups. Supports ?search=, ?tag=, and ?book= query params
GET /api/v1/terms/slug/{slug} Get a single term group by slug (all entries sharing that name)
GET /api/v1/terms/{id} Get a single term entry by database ID
POST /api/v1/terms Create a new manual term (no source book or chapter)
PUT /api/v1/terms/{id} Update a term entry. Manual terms: all fields. Book-sourced: definitions only
DELETE /api/v1/terms/{id} Delete a single term entry

The full interactive API reference is available at /swagger-ui.html when the app is running. The Thymeleaf views are served under /terms and /roadmap.


Data Model

Terms are stored flat. There is no nested definition or experience-level structure.

Field Type Notes
id Long Primary key
name String Display name (e.g. "Garbage Collection")
slug String URL-safe identifier derived from name (e.g. "garbage-collection")
casualDefinition String Plain-language explanation
formalDefinition String Precise, interview-ready definition
sourceBook String Source book title; null for manual terms
sourceChapter String Chapter within the source book; null for manual terms
tags Set Keyword tags (stored in term_tags table)

A manual term has both sourceBook and sourceChapter set to null. The database enforces uniqueness with two separate constraints: a composite unique on (name, source_book, source_chapter) for book-sourced terms, and a partial unique index on name WHERE both source columns are null for manual terms — because SQL treats NULL != NULL and a standard unique constraint cannot cover this case.

The same term name can appear in multiple rows when sourced from different books or chapters. The service layer groups these rows by slug before returning them to the UI or API.


Learning Roadmap

The learning roadmap is defined entirely in src/main/resources/roadmap.yaml. No code changes are needed to add new volumes, chapters, or terms — just edit the YAML.

Each volume maps to a source book. Each chapter within a volume maps to a chapter in that book. Each entry specifies the term to define, suggested tags, external learning resources, and guided research hints (what, why, how).

When a definition is submitted from the roadmap UI, it is saved as a book-sourced term with sourceBook and sourceChapter set from the YAML config. If a definition already exists for that (term, book, chapter) combination, the UI asks for confirmation before overriding it.


Project Structure

Standard Spring Boot layered architecture:

src/
└── main/
    ├── java/com/noahparknguyen/javadictionary/
    │   ├── config/
    │   │   ├── OpenApiConfig.java            # SpringDoc API metadata
    │   │   └── roadmap/                      # @ConfigurationProperties for roadmap.yaml
    │   ├── controller/
    │   │   ├── TermController.java           # REST API (/api/v1/terms)
    │   │   ├── TermViewController.java       # Thymeleaf UI (/terms)
    │   │   └── RoadmapController.java        # Thymeleaf UI (/roadmap)
    │   ├── dto/
    │   │   ├── request/                      # POST / PUT / roadmap form bodies
    │   │   └── response/                     # Term, group, and roadmap view models
    │   ├── exception/                        # GlobalExceptionHandler + custom exceptions
    │   ├── mapper/
    │   │   └── TermMapper.java               # Entity ↔ DTO conversion + grouping logic
    │   ├── model/
    │   │   └── Term.java                     # JPA entity
    │   ├── repository/
    │   │   └── TermRepository.java           # Spring Data JPA + custom JPQL queries
    │   └── service/
    │       ├── TermService.java              # Term CRUD + uniqueness rules
    │       └── RoadmapService.java           # Config-DB bridge for roadmap views
    └── resources/
        ├── db/migration/                     # Flyway SQL migrations (V1, V2, V3)
        ├── static/                           # CSS + JS assets
        ├── templates/                        # Thymeleaf views (terms, roadmap, fragments)
        ├── application.properties            # Shared config
        ├── application-dev.properties        # Local dev overrides
        ├── application-prod.properties       # Production overrides
        └── roadmap.yaml                      # Roadmap volumes, chapters, entries, and hints

Planned

  • Complete the Core Java Vol I roadmap content
  • Deployment on Render
  • Authentication — currently a single-user personal tool

MIT © Noah Park-Nguyen

About

Personal Java interview-prep tool — build a glossary of terms with dual definitions, track sources, and work through a structured book-based learning roadmap.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Contributors