From 23b943b4e46173e7e5bb8b2f2472d8b11c3e55dc Mon Sep 17 00:00:00 2001 From: Tobias Wietelmann Date: Sun, 26 Jul 2026 18:40:44 +0200 Subject: [PATCH 1/5] Add Java 21 Maven CI --- .github/workflows/ci.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..654f76b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + java-21: + name: Java 21 + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Java 21 + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: "21" + cache: maven + + - name: Ensure Maven Wrapper is executable + run: chmod +x mvnw + + - name: Verify with Maven Wrapper + run: ./mvnw --batch-mode --no-transfer-progress clean verify From d9035bbdca964ddf1b773a90aed581130937f997 Mon Sep 17 00:00:00 2001 From: Tobias Wietelmann Date: Sun, 26 Jul 2026 18:41:39 +0200 Subject: [PATCH 2/5] Expand API integration coverage --- .../ProcessCheckApiIntegrationTests.java | 171 +++++++++++++++++- 1 file changed, 170 insertions(+), 1 deletion(-) diff --git a/src/test/java/de/datatidehh/processapi/processcheck/ProcessCheckApiIntegrationTests.java b/src/test/java/de/datatidehh/processapi/processcheck/ProcessCheckApiIntegrationTests.java index 23bd333..2780bcd 100644 --- a/src/test/java/de/datatidehh/processapi/processcheck/ProcessCheckApiIntegrationTests.java +++ b/src/test/java/de/datatidehh/processapi/processcheck/ProcessCheckApiIntegrationTests.java @@ -12,11 +12,16 @@ import java.time.LocalDateTime; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.everyItem; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -142,4 +147,168 @@ void findByIdReturnsProblemDetailWhenRecordDoesNotExist() is("Process check not found: " + MISSING_ID) )); } -} \ No newline at end of file + + @Test + void createReturnsCreatedRecordAndLocationHeader() throws Exception { + mockMvc.perform(post("/api/process-checks") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson( + "Customer data quality check", + "Data Quality", + "CRITICAL", + "2026-07-11T08:30:00", + 30 + ))) + .andExpect(status().isCreated()) + .andExpect(header().string( + "Location", + containsString("/api/process-checks/") + )) + .andExpect(jsonPath("$.id").isNumber()) + .andExpect(jsonPath( + "$.processName", + is("Customer data quality check") + )) + .andExpect(jsonPath("$.status", is("CRITICAL"))); + + org.assertj.core.api.Assertions.assertThat(repository.findAll()) + .hasSize(3) + .anySatisfy(processCheck -> { + org.assertj.core.api.Assertions.assertThat( + processCheck.getProcessName() + ).isEqualTo("Customer data quality check"); + org.assertj.core.api.Assertions.assertThat( + processCheck.getStatus() + ).isEqualTo(ProcessStatus.CRITICAL); + }); + } + + @Test + void createWithInvalidRequestReturnsBadRequest() throws Exception { + mockMvc.perform(post("/api/process-checks") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson( + " ", + " ", + "OK", + "2026-07-11T08:30:00", + 0 + ))) + .andExpect(status().isBadRequest()); + + org.assertj.core.api.Assertions.assertThat(repository.findAll()) + .hasSize(2); + } + + @Test + void updateChangesAndPersistsExistingRecord() throws Exception { + mockMvc.perform(put( + "/api/process-checks/{id}", + okProcessCheckId + ) + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson( + "Daily sales import - corrected", + "BI Operations", + "WARNING", + "2026-07-11T09:15:00", + 45 + ))) + .andExpect(status().isOk()) + .andExpect(jsonPath( + "$.id", + is(okProcessCheckId.intValue()) + )) + .andExpect(jsonPath( + "$.processName", + is("Daily sales import - corrected") + )) + .andExpect(jsonPath("$.owner", is("BI Operations"))) + .andExpect(jsonPath("$.status", is("WARNING"))) + .andExpect(jsonPath("$.slaMinutes", is(45))); + + ProcessCheck updated = repository.findById(okProcessCheckId) + .orElseThrow(); + + org.assertj.core.api.Assertions.assertThat(updated.getProcessName()) + .isEqualTo("Daily sales import - corrected"); + org.assertj.core.api.Assertions.assertThat(updated.getStatus()) + .isEqualTo(ProcessStatus.WARNING); + org.assertj.core.api.Assertions.assertThat(updated.getSlaMinutes()) + .isEqualTo(45); + } + + @Test + void updateReturnsProblemDetailWhenRecordDoesNotExist() + throws Exception { + mockMvc.perform(put( + "/api/process-checks/{id}", + MISSING_ID + ) + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson( + "Missing process", + "Data Operations", + "OK", + "2026-07-11T09:15:00", + 60 + ))) + .andExpect(status().isNotFound()) + .andExpect(content().contentTypeCompatibleWith( + MediaType.APPLICATION_PROBLEM_JSON + )) + .andExpect(jsonPath("$.status", is(404))); + } + + @Test + void deleteRemovesExistingRecordAndReturnsNoContent() throws Exception { + mockMvc.perform(delete( + "/api/process-checks/{id}", + okProcessCheckId + )) + .andExpect(status().isNoContent()) + .andExpect(content().string("")); + + org.assertj.core.api.Assertions.assertThat( + repository.existsById(okProcessCheckId) + ).isFalse(); + } + + @Test + void deleteReturnsProblemDetailWhenRecordDoesNotExist() + throws Exception { + mockMvc.perform(delete( + "/api/process-checks/{id}", + MISSING_ID + )) + .andExpect(status().isNotFound()) + .andExpect(content().contentTypeCompatibleWith( + MediaType.APPLICATION_PROBLEM_JSON + )) + .andExpect(jsonPath("$.status", is(404))); + } + + private String requestJson( + String processName, + String owner, + String status, + String lastCheckedAt, + int slaMinutes + ) { + return """ + { + "processName": "%s", + "owner": "%s", + "status": "%s", + "lastCheckedAt": "%s", + "slaMinutes": %d + } + """.formatted( + processName, + owner, + status, + lastCheckedAt, + slaMinutes + ); + } +} From f8a425a7055186a4723da3664f82373add43a3d8 Mon Sep 17 00:00:00 2001 From: Tobias Wietelmann Date: Sun, 26 Jul 2026 18:42:03 +0200 Subject: [PATCH 3/5] Complete Maven project metadata --- pom.xml | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 47f4e44..65f8726 100644 --- a/pom.xml +++ b/pom.xml @@ -6,25 +6,33 @@ org.springframework.boot spring-boot-starter-parent 4.1.0 - + de.datatidehh spring-boot-process-api-basics 0.0.1-SNAPSHOT spring-boot-process-api-basics - - + Small Java 21 and Spring Boot REST API for validated process-check records. + https://github.com/DataTideHH/spring-boot-process-api-basics - + + MIT License + https://opensource.org/license/mit + repo + - + + Tobias Wietelmann + DataTideHH + https://datatidehh.de/ + - - - - + scm:git:https://github.com/DataTideHH/spring-boot-process-api-basics.git + scm:git:ssh://git@github.com/DataTideHH/spring-boot-process-api-basics.git + HEAD + https://github.com/DataTideHH/spring-boot-process-api-basics 21 From a7b3f092d20cb1d24e1771e7ccb7de340c8e6267 Mon Sep 17 00:00:00 2001 From: Tobias Wietelmann Date: Sun, 26 Jul 2026 18:43:06 +0200 Subject: [PATCH 4/5] Align README with tested API contract --- README.md | 175 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 142 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index c147424..1257890 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # Spring Boot Process API Basics -**Java 21 · Spring Boot · REST API · Spring Data JPA · H2 · Validation · Maven** +[![CI](https://github.com/DataTideHH/spring-boot-process-api-basics/actions/workflows/ci.yml/badge.svg)](https://github.com/DataTideHH/spring-boot-process-api-basics/actions/workflows/ci.yml) -Small Java 21 / Spring Boot learning project that exposes process-check data through a simple REST API. +**Java 21 · Spring Boot 4.1 · REST API · Spring Data JPA · H2 · Validation · Maven · GitHub Actions** + +Small Java 21 / Spring Boot learning project that exposes validated process-check data through a layered REST API. Project page: https://datatidehh.github.io/spring-boot-process-api-basics/ @@ -19,12 +21,16 @@ It demonstrates: - REST endpoints for a small process-related resource - layered backend structure with controller, service and repository - request validation +- status-based filtering +- explicit HTTP success and error behavior - basic persistence with Spring Data JPA -- an H2 in-memory database for local development -- a local Maven build and test workflow +- an H2 in-memory database for local development and tests +- automated API integration tests with MockMvc +- a reproducible Maven Wrapper workflow +- GitHub Actions CI on Java 21 - synthetic sample data for process-oriented API testing -The goal is not to present a large enterprise backend. The goal is to document a clean first step from Java basics toward a small Spring Boot REST API that handles structured process data. +The goal is not to present a large enterprise backend. The goal is to document a clean first step from Java basics toward a small, tested Spring Boot REST API that handles structured process data. --- @@ -43,12 +49,15 @@ It complements my main Data/BI portfolio projects around SQL, Python, Power BI, | Layer | Tool / Concept | Purpose | |---|---|---| | Language | Java 21 | Main implementation language | -| Framework | Spring Boot | REST API application framework | -| API layer | Spring Web | HTTP endpoints and JSON responses | +| Framework | Spring Boot 4.1 | REST API application framework | +| API layer | Spring Web MVC | HTTP endpoints and JSON responses | | Persistence | Spring Data JPA | Repository abstraction and entity persistence | -| Database | H2 | In-memory local development database | -| Validation | Jakarta Validation | Request validation for incoming data | -| Build tool | Maven Wrapper | Reproducible local build workflow | +| Database | H2 | In-memory local development and test database | +| Validation | Jakarta Validation | Validation for incoming request data | +| Error format | Spring `ProblemDetail` | Consistent `application/problem+json` responses | +| Tests | JUnit 5, Spring Boot Test, MockMvc | API integration and persistence verification | +| Build tool | Maven Wrapper | Reproducible builds on Windows, macOS and Linux | +| CI | GitHub Actions | Automated Java 21 Maven verification | --- @@ -68,17 +77,28 @@ Current package focus: src/main/java/de/datatidehh/processapi/processcheck/ ``` +The API uses request and response records instead of exposing the JPA entity directly. + --- -## API Endpoints +## API Contract -| Method | Endpoint | Purpose | -|---|---|---| -| `GET` | `/api/process-checks` | Return all process-check records | -| `GET` | `/api/process-checks/{id}` | Return one process-check record by ID | -| `POST` | `/api/process-checks` | Create a new process-check record | -| `PUT` | `/api/process-checks/{id}` | Update an existing process-check record | -| `DELETE` | `/api/process-checks/{id}` | Delete a process-check record | +| Method | Endpoint | Success | Purpose | +|---|---|---:|---| +| `GET` | `/api/process-checks` | `200 OK` | Return all process-check records | +| `GET` | `/api/process-checks?status=OK` | `200 OK` | Filter records by `OK`, `WARNING` or `CRITICAL` | +| `GET` | `/api/process-checks/{id}` | `200 OK` | Return one process-check record by ID | +| `POST` | `/api/process-checks` | `201 Created` | Create a record and return its URI in `Location` | +| `PUT` | `/api/process-checks/{id}` | `200 OK` | Replace the editable values of an existing record | +| `DELETE` | `/api/process-checks/{id}` | `204 No Content` | Delete an existing record | + +Typical client errors: + +| Situation | Result | +|---|---:| +| Invalid request body | `400 Bad Request` | +| Invalid status query value | `400 Bad Request` | +| Unknown record ID | `404 Not Found` | --- @@ -95,16 +115,48 @@ src/main/java/de/datatidehh/processapi/processcheck/ } ``` +Request validation requires: + +- a non-blank `processName` +- a non-blank `owner` +- a valid status: `OK`, `WARNING` or `CRITICAL` +- a non-null ISO local date-time value +- `slaMinutes` of at least `1` + +--- + +## Error Response Example + +Requests for unknown IDs return a standard Spring `ProblemDetail` response with media type `application/problem+json`: + +```json +{ + "type": "about:blank", + "title": "Process check not found", + "status": 404, + "detail": "Process check not found: 999999", + "instance": "/api/process-checks/999999" +} +``` + --- ## Run Locally +### macOS or Linux + From the repository root: ```bash ./mvnw spring-boot:run ``` +### Windows PowerShell + +```powershell +.\mvnw.cmd spring-boot:run +``` + Then open: ```text @@ -121,19 +173,53 @@ At first startup, the API returns an empty JSON array because the H2 database is ## Build and Test -Run: +### macOS or Linux ```bash -./mvnw clean package +./mvnw clean verify +``` + +### Windows PowerShell + +```powershell +.\mvnw.cmd clean verify ``` -The project has been built and smoke-tested locally with Java 21 and the Maven Wrapper. +The automated suite verifies: + +- application context startup +- unfiltered and status-filtered list requests +- empty filter results +- invalid status handling +- lookup by ID +- `404` Problem Detail responses +- successful creation with `201 Created` and `Location` +- request validation failures +- update behavior and persisted values +- successful deletion with `204 No Content` +- update and delete behavior for unknown IDs + +--- + +## Continuous Integration + +The workflow under `.github/workflows/ci.yml` runs for pull requests and pushes to `main`. + +It uses: + +- an Ubuntu GitHub-hosted runner +- Eclipse Temurin Java 21 +- Maven dependency caching +- the repository's Maven Wrapper +- `clean verify` as the build and test gate + +The workflow has read-only repository permissions and cancels superseded runs for the same branch or pull request. --- ## Manual API Test Flow -The API was manually tested with curl for the full CRUD flow: +The full CRUD flow can also be exercised manually with curl, an API client or an IDE HTTP client: ```text POST /api/process-checks create a process-check record @@ -148,13 +234,11 @@ Example test data: ```text processName: Daily sales import owner: Data Operations -status: OK / WARNING +status: OK / WARNING / CRITICAL lastCheckedAt: 2026-07-10T00:25:00 slaMinutes: 60 ``` -After deletion, the list endpoint returns an empty JSON array again. - --- ## H2 Database Note @@ -168,12 +252,33 @@ That means: - inserted records are lost when the application stops - this is suitable for a small learning project, not for production persistence -The H2 console is available locally while the application is running: +The H2 console is available while the application is running: ```text http://localhost:8080/h2-console ``` +Connection values: + +```text +JDBC URL: jdbc:h2:mem:processdb +User: sa +Password: +``` + +--- + +## Learning References + +The related official documentation is curated in [`open-learning-resources`](https://github.com/DataTideHH/open-learning-resources): + +- [Spring Boot Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/java/spring-boot-documentation) +- [Spring Data JPA Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/java/spring-data-jpa-documentation) +- [Apache Maven and Maven Wrapper Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/java/apache-maven-and-wrapper-documentation) +- [GitHub Actions Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/git/github-actions-documentation) + +This keeps the project implementation connected to official primary documentation without mirroring dynamic framework documentation locally. + --- ## GitHub Pages Project Site @@ -206,14 +311,18 @@ This repository demonstrates a small but realistic backend foundation: - Java 21 project workflow - Spring Boot application structure -- REST endpoint design +- REST endpoint and HTTP-status design - JSON request and response handling -- CRUD operations +- CRUD operations and status filtering - layered backend organization - request validation -- basic persistence abstraction with Spring Data JPA -- local development with H2 -- Maven build and test workflow +- standard Problem Detail error responses +- explicit transaction boundaries +- persistence abstraction with Spring Data JPA +- local development and testing with H2 +- automated integration testing +- reproducible Maven builds +- GitHub Actions CI - public portfolio documentation for a focused learning project --- @@ -222,9 +331,9 @@ This repository demonstrates a small but realistic backend foundation: This is a learning project. -It does not include production database configuration, Docker deployment, a frontend UI, cloud deployment, monitoring infrastructure or enterprise-scale error handling. +It does not include production database configuration, Docker deployment, authentication and authorization, a frontend UI, cloud deployment, monitoring infrastructure, pagination or enterprise-scale operational error handling. -These omissions are intentional. The current scope is limited to a clean, understandable Spring Boot REST API baseline. +These omissions are intentional. The current scope is limited to a clean, understandable and tested Spring Boot REST API baseline. --- From 111b5e9b59d7d65c9a936a7c6cf1f30b002e9bea Mon Sep 17 00:00:00 2001 From: Tobias Wietelmann Date: Sun, 26 Jul 2026 18:43:36 +0200 Subject: [PATCH 5/5] Update project page for CI and API contract --- docs/index.md | 76 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/docs/index.md b/docs/index.md index e6c7e2e..337ddbb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,9 +5,9 @@ description: Small Java 21 / Spring Boot REST API portfolio project # Spring Boot Process API Basics -**Small Java 21 / Spring Boot REST API project exposing process-check data through a layered backend structure, validation and H2 persistence.** +**Small Java 21 / Spring Boot REST API project exposing validated process-check data through a layered backend structure, automated tests and H2 persistence.** -[View repository](https://github.com/DataTideHH/spring-boot-process-api-basics) · [Read the full README](https://github.com/DataTideHH/spring-boot-process-api-basics/blob/main/README.md) · [DataTideHH portfolio](https://datatidehh.de/) +[View repository](https://github.com/DataTideHH/spring-boot-process-api-basics) · [Read the full README](https://github.com/DataTideHH/spring-boot-process-api-basics/blob/main/README.md) · [View CI](https://github.com/DataTideHH/spring-boot-process-api-basics/actions/workflows/ci.yml) · [DataTideHH portfolio](https://datatidehh.de/) --- @@ -17,7 +17,7 @@ This project is a deliberately compact backend learning project. It demonstrates how process-related records can be represented, validated, persisted and exposed through a small REST API using Spring Boot. -The goal is not to present a production service or an enterprise backend system. The goal is to document a clean first step from Java basics toward a small enterprise-style REST API that supports structured operational data. +The goal is not to present a production service or an enterprise backend system. The goal is to document a clean first step from Java basics toward a small layered REST API with explicit HTTP behavior, persistence and automated verification. --- @@ -25,36 +25,41 @@ The goal is not to present a production service or an enterprise backend system. The project supports a Data/BI and process-analysis learning path by connecting backend API fundamentals with structured process data. -For Data/BI and process analysis work, APIs are an important interface between operational systems and downstream data workflows. This project is useful as a supporting IT foundation because it shows how process-related records can move through a simple backend structure. +For Data/BI and process analysis work, APIs are an important interface between operational systems and downstream data workflows. This project is useful as a supporting IT foundation because it shows how process-related records move through a simple backend structure. -It follows the [IPv4 Subnet Calculator Multilang](https://datatidehh.github.io/ipv4-subnet-calculator-multilang/) in the Java learning progression: the subnet project demonstrates a compact, tested command-line implementation and shared cross-language contract, while this repository adds framework structure, HTTP endpoints, validation and persistence. +It follows the [IPv4 Subnet Calculator Multilang](https://datatidehh.github.io/ipv4-subnet-calculator-multilang/) in the Java learning progression: the subnet project demonstrates a compact, tested command-line implementation and shared cross-language contract, while this repository adds framework structure, HTTP endpoints, validation, persistence and CI. --- ## What the project demonstrates -- Java 21 project setup -- Spring Boot REST API basics +- Java 21 and Spring Boot 4.1 - controller, service and repository separation - Spring Data JPA repository usage -- request validation +- request and response records +- Jakarta Validation - H2 in-memory persistence - CRUD endpoints for process-check data -- local Maven build and run workflow +- optional status filtering +- standard `ProblemDetail` error responses +- integration tests with Spring Boot Test and MockMvc +- reproducible Maven Wrapper builds +- GitHub Actions verification on Java 21 --- -## API scope +## API contract -The API exposes a small process-check resource. +| Method | Endpoint | Result | Purpose | +|---|---|---:|---| +| `GET` | `/api/process-checks` | `200` | List all records | +| `GET` | `/api/process-checks?status=OK` | `200` | Filter by `OK`, `WARNING` or `CRITICAL` | +| `GET` | `/api/process-checks/{id}` | `200` | Read one record | +| `POST` | `/api/process-checks` | `201` | Create a record and return `Location` | +| `PUT` | `/api/process-checks/{id}` | `200` | Update a record | +| `DELETE` | `/api/process-checks/{id}` | `204` | Delete a record | -```text -GET /api/process-checks -GET /api/process-checks/{id} -POST /api/process-checks -PUT /api/process-checks/{id} -DELETE /api/process-checks/{id} -``` +Invalid input returns `400 Bad Request`. Unknown record IDs return `404 Not Found` as `application/problem+json`. --- @@ -75,23 +80,44 @@ DELETE /api/process-checks/{id} ## Local usage -Run the application from the repository root: +### macOS or Linux ```bash ./mvnw spring-boot:run +./mvnw clean verify +``` + +### Windows PowerShell + +```powershell +.\mvnw.cmd spring-boot:run +.\mvnw.cmd clean verify ``` -Then open: +The API is available at: ```text http://localhost:8080/api/process-checks ``` -Build and test locally: +--- -```bash -./mvnw clean package -``` +## Verification + +The integration suite covers list and filter behavior, lookup by ID, creation, validation failures, updates, deletion, persistence effects and `404` Problem Detail responses. + +The GitHub Actions workflow runs `clean verify` with Eclipse Temurin Java 21 for pull requests and pushes to `main`. + +--- + +## Official learning references + +The matching primary documentation is curated in [Open Learning Resources](https://github.com/DataTideHH/open-learning-resources): + +- [Spring Boot Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/java/spring-boot-documentation) +- [Spring Data JPA Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/java/spring-data-jpa-documentation) +- [Apache Maven and Maven Wrapper Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/java/apache-maven-and-wrapper-documentation) +- [GitHub Actions Documentation](https://github.com/DataTideHH/open-learning-resources/tree/main/resources/git/github-actions-documentation) --- @@ -110,4 +136,4 @@ The project uses an H2 in-memory database. Data is reset when the application st The sample data is synthetic and does not contain personal, customer or production data. -This is a learning project with a deliberately limited scope. +This is a learning project with a deliberately limited scope. It does not claim production deployment, authentication, cloud operation or enterprise-scale infrastructure.