chore: establish iteration 1 development baseline

This commit is contained in:
sechmachine
2026-08-14 23:22:31 +07:00
parent 55a8ce675f
commit 5967f7f70d
12 changed files with 300 additions and 2 deletions
+1
View File
@@ -0,0 +1 @@
25
+23 -1
View File
@@ -1,2 +1,24 @@
# labtimesheet # Lab Timesheet
## Local development
The application targets Java 25 and expects PostgreSQL on
`localhost:55432` when the default `dev` profile is active. Override any local
value with `LAB_DB_URL`, `LAB_DB_USERNAME`, `LAB_DB_PASSWORD`,
`LAB_SMTP_HOST`, or `LAB_SMTP_PORT`.
```bash
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw spring-boot:run
```
Tests use PostgreSQL 18.4 through Testcontainers and do not use the developer
database:
```bash
./mvnw test
```
Every feature test must have a companion Markdown evidence record under
[`docs/tests`](docs/tests/README.md).
+18
View File
@@ -0,0 +1,18 @@
# Test Evidence
TDD is mandatory. Every feature test must have one companion Markdown record
in the directory matching its test type:
- `unit/` — isolated state, calculation, and domain behavior.
- `integration/` — PostgreSQL, Flyway, repository, transaction, and module integration.
- `web/` — MockMvc, Thymeleaf, validation, and security behavior.
- `e2e/` — cross-module, browser, or full user journeys.
Copy that directory's `_TEMPLATE.md` and keep every heading. One evidence file
may cover a cohesive parameterized scenario set, but it must name every
requirement and scenario ID it protects.
An evidence record is complete only when it contains the observed RED failure,
the observed GREEN result, the affected-suite result, and honest external-test
boundaries. Commands and relevant output are copied exactly; prose such as
"passed locally" is not evidence.
+59
View File
@@ -0,0 +1,59 @@
# Test Evidence: <short behavior name>
- **Test type:** E2E
- **Requirement IDs:** `<ID>`
- **Scenario IDs:** `<ID>`
- **Test class/method:** `<fully qualified class and method>`
- **Implementation commit:** `<short SHA or pending>`
## Protected behavior
<Externally observable rule and failure mode protected by this test.>
## Test method
<Setup, action, and assertions. Explain why this is the narrowest production-shaped test.>
## Hand-derived expected result
<Expected values or state derived independently of the implementation.>
## RED
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant failing output and why it failed for the expected missing behavior>
```
## GREEN
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant passing output>
```
## Affected suite
**Command and result**
```text
<exact broader command and result>
```
## External-test boundaries
<What this test deliberately does not prove, including infrastructure or browser boundaries.>
+59
View File
@@ -0,0 +1,59 @@
# Test Evidence: <short behavior name>
- **Test type:** Integration
- **Requirement IDs:** `<ID>`
- **Scenario IDs:** `<ID>`
- **Test class/method:** `<fully qualified class and method>`
- **Implementation commit:** `<short SHA or pending>`
## Protected behavior
<Externally observable rule and failure mode protected by this test.>
## Test method
<Setup, action, and assertions. Explain why this is the narrowest production-shaped test.>
## Hand-derived expected result
<Expected values or state derived independently of the implementation.>
## RED
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant failing output and why it failed for the expected missing behavior>
```
## GREEN
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant passing output>
```
## Affected suite
**Command and result**
```text
<exact broader command and result>
```
## External-test boundaries
<What this test deliberately does not prove, including infrastructure or browser boundaries.>
+59
View File
@@ -0,0 +1,59 @@
# Test Evidence: <short behavior name>
- **Test type:** Unit
- **Requirement IDs:** `<ID>`
- **Scenario IDs:** `<ID>`
- **Test class/method:** `<fully qualified class and method>`
- **Implementation commit:** `<short SHA or pending>`
## Protected behavior
<Externally observable rule and failure mode protected by this test.>
## Test method
<Setup, action, and assertions. Explain why this is the narrowest production-shaped test.>
## Hand-derived expected result
<Expected values or state derived independently of the implementation.>
## RED
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant failing output and why it failed for the expected missing behavior>
```
## GREEN
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant passing output>
```
## Affected suite
**Command and result**
```text
<exact broader command and result>
```
## External-test boundaries
<What this test deliberately does not prove, including infrastructure or browser boundaries.>
+59
View File
@@ -0,0 +1,59 @@
# Test Evidence: <short behavior name>
- **Test type:** Web
- **Requirement IDs:** `<ID>`
- **Scenario IDs:** `<ID>`
- **Test class/method:** `<fully qualified class and method>`
- **Implementation commit:** `<short SHA or pending>`
## Protected behavior
<Externally observable rule and failure mode protected by this test.>
## Test method
<Setup, action, and assertions. Explain why this is the narrowest production-shaped test.>
## Hand-derived expected result
<Expected values or state derived independently of the implementation.>
## RED
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant failing output and why it failed for the expected missing behavior>
```
## GREEN
**Command**
```text
<exact command>
```
**Observed result**
```text
<relevant passing output>
```
## Affected suite
**Command and result**
```text
<exact broader command and result>
```
## External-test boundaries
<What this test deliberately does not prove, including infrastructure or browser boundaries.>
+8
View File
@@ -0,0 +1,8 @@
spring:
datasource:
url: ${LAB_DB_URL:jdbc:postgresql://localhost:55432/labtimesheet}
username: ${LAB_DB_USERNAME:labtimesheet}
password: ${LAB_DB_PASSWORD:labtimesheet_dev}
mail:
host: ${LAB_SMTP_HOST:localhost}
port: ${LAB_SMTP_PORT:1025}
+7
View File
@@ -1,3 +1,10 @@
spring: spring:
application: application:
name: labtimesheet name: labtimesheet
profiles:
default: dev
docker:
compose:
enabled: false
jpa:
open-in-view: false
@@ -3,9 +3,11 @@ package com.lab.labtimesheet;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
@Import(TestcontainersConfiguration.class) @Import(TestcontainersConfiguration.class)
@SpringBootTest @SpringBootTest
@ActiveProfiles("test")
class LabtimesheetApplicationTests { class LabtimesheetApplicationTests {
@Test @Test
@@ -12,7 +12,7 @@ class TestcontainersConfiguration {
@Bean @Bean
@ServiceConnection @ServiceConnection
PostgreSQLContainer postgresContainer() { PostgreSQLContainer postgresContainer() {
return new PostgreSQLContainer(DockerImageName.parse("postgres:latest")); return new PostgreSQLContainer(DockerImageName.parse("postgres:18.4"));
} }
} }
+4
View File
@@ -0,0 +1,4 @@
spring:
docker:
compose:
enabled: false