Skip to content

Architecture

flowchart LR
    Console[React Vite management console] --> ReactClient[React client library]
    ReactClient --> Api[Spring Boot API /api/v1/domaintemplate]
    JavaClient[Java client library] --> Api
    DartClient[Dart client library] --> Api
    Api --> Service[DomainTemplateService]
    Service --> Repository[DomainTemplateRepository]
    Repository --> Database[(PostgreSQL domain_templates)]
    Docs[MkDocs] -. documents .-> Api
    Slides[Marp presentation] -. explains .-> Docs

The repository demonstrates one vertical CRUD feature. HTTP controllers validate transport requests and delegate business operations to DomainTemplateService. The service owns timestamps and upsert behavior, while DomainTemplateRepository isolates Spring Data JPA access. The Java, TypeScript, and Dart clients depend on the public HTTP contract, not on persistence classes.

Public Object and Persistence Entity

DomainTemplate is the public business object returned by controllers and represented by each client. It is an immutable Java record with id, code, label, description, createdDate, and lastModifiedDate. This is the model API consumers should understand.

DomainTemplateEntity is the internal mutable JPA representation. It maps to the PostgreSQL table domain_templates and exists to satisfy persistence concerns such as a protected no-argument constructor, generated identity, column constraints, and dirty tracking. Controllers never expose the JPA entity.

The service maps between these types. This boundary keeps the public contract stable when persistence details change and prevents JPA behavior from leaking into client code.

Invariants and Ownership

Concern Owner Behavior
Persistent identity Server and database id is a generated Long.
Business identity Service and database code is required, unique, and immutable.
Mutable business data Client request label is required; description may be null.
Audit timestamps Service Both dates are Instant values assigned by the server.
Bulk reconciliation Service Seed and import upsert by code and ignore imported IDs and dates.

Schema Evolution

Hibernate is configured with spring.jpa.hibernate.ddl-auto: update for this runnable application. It can add or adjust the domain_templates schema, but it does not remove tables that are no longer mapped. In particular, an existing demo volume may retain the obsolete domain_records table. The application does not use that table.

This convenience setting is not a migration strategy for production. Use versioned database migrations in a real service. For the demo, reset the Compose volume when a clean schema is required, as described in the deployment guide.