docs(project): record feature JPA milestone evidence

This commit is contained in:
sechmachine
2026-08-15 00:27:35 +07:00
parent 25a855ea90
commit 7acd525205
4 changed files with 228 additions and 5 deletions
@@ -0,0 +1,75 @@
# Test Evidence: Atomic Project workflows
- **Test type:** Integration
- **Requirement IDs:** `PRJ-001``PRJ-007`, `PRJ-017`, `AUTH-001``AUTH-004`, `DB-003`, `DB-007`
- **Scenario IDs:** `AC-PRJ-001``AC-PRJ-003`, `AC-PRJ-009`
- **Test class/method:** `com.lab.labtimesheet.feature.project.service.ProjectServiceIntegrationTest`
- **Implementation commit:** `25a855e`
## Protected behavior
PostgreSQL transactions persist a planned Project with its initial membership and leadership term, reject unauthorized or duplicate direct additions, change exactly one Leader without moving Task assignments, and enforce role/membership visibility without ID disclosure.
## Test method
A Spring Boot integration test uses the platform-owned PostgreSQL 18.4 Testcontainer and Flyway V1 schema. It calls the public Project service and verifies committed-shape rows and negative-case non-mutation with independent SQL.
## Hand-derived expected result
Creation yields one Project, one active membership, and one current leadership term. Direct addition yields one membership per Project/Intern pair while allowing the same Intern in a second Project. Leader change yields one closed and one current term while the Task assignee ID remains unchanged. Admin, owner, and historical member visibility is allowed; unrelated IDs are denied uniformly.
## RED
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
./mvnw -Dtest=ProjectServiceIntegrationTest test
```
**Observed result**
```text
[ERROR] cannot find symbol: class CreateProjectCommand
[ERROR] cannot find symbol: class ProjectService
[INFO] BUILD FAILURE
```
## GREEN
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
./mvnw -Dtest=ProjectServiceIntegrationTest test
```
**Observed result**
```text
[INFO] Running com.lab.labtimesheet.feature.project.service.ProjectServiceIntegrationTest
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## Affected suite
**Command and result**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
./mvnw test
[INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## External-test boundaries
This test does not prove MockMvc authorization, Thymeleaf rendering, browser accessibility, real concurrent transaction races, Iteration 2 invitations/removals/completion, or Task-module business rules beyond preserving stored assignment IDs. `I1-PRJ-04` remains `IN_PROGRESS`: the activation Task-assignee guard will be implemented only after the Task feature exposes its concrete query service.
+5 -5
View File
@@ -3,8 +3,8 @@
- **Test type:** Unit - **Test type:** Unit
- **Requirement IDs:** `PRJ-001``PRJ-007`, `PRJ-012`, `PRJ-017`, `AUTH-001``AUTH-004` - **Requirement IDs:** `PRJ-001``PRJ-007`, `PRJ-012`, `PRJ-017`, `AUTH-001``AUTH-004`
- **Scenario IDs:** `AC-PRJ-001`, `AC-PRJ-003`, `AC-PRJ-006`, `AC-PRJ-009` - **Scenario IDs:** `AC-PRJ-001`, `AC-PRJ-003`, `AC-PRJ-006`, `AC-PRJ-009`
- **Test class/method:** `com.lab.labtimesheet.projects.domain.ProjectTest` - **Test class/method:** `com.lab.labtimesheet.feature.project.model.entity.ProjectEntityTest`
- **Implementation commit:** `3483347` - **Implementation commit:** `25a855e`
## Protected behavior ## Protected behavior
@@ -43,13 +43,13 @@ export PATH="$JAVA_HOME/bin:$PATH"
```text ```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25 export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH" export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectTest test ./mvnw -Dtest=ProjectEntityTest test
``` ```
**Observed result** **Observed result**
```text ```text
[INFO] Running com.lab.labtimesheet.projects.domain.ProjectTest [INFO] Running com.lab.labtimesheet.feature.project.model.entity.ProjectEntityTest
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0 [INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS [INFO] BUILD SUCCESS
``` ```
@@ -61,7 +61,7 @@ export PATH="$JAVA_HOME/bin:$PATH"
```text ```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25 export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH" export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectTest test ./mvnw -Dtest=ProjectEntityTest test
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0 [INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS [INFO] BUILD SUCCESS
@@ -0,0 +1,75 @@
# Test Evidence: Project layer and JPA structure
- **Test type:** Unit
- **Requirement IDs:** `ARC-002`, `ARC-005``ARC-007`, `OPS-018``OPS-020`, `TST-001``TST-010`
- **Scenario IDs:** `I1-PRJ-01``I1-PRJ-05`
- **Test class/method:** `com.lab.labtimesheet.feature.project.repository.ProjectPersistenceStructureTest#projectPersistenceUsesTheRequiredLayerPackagesAndSpringDataJpa`
- **Implementation commit:** `25a855e`
## Protected behavior
Project-owned production code follows the authoritative feature-first package layout, persists aggregate entities through Spring Data JPA, keeps JDBC operations out of Project business services, and does not shadow Account or Task persistence.
## Test method
Plain JUnit inspects the public Project entity, repository, and service types. It verifies their exact feature/layer packages, the entity's JPA mapping, the repository's `JpaRepository` contract, the absence of JDBC service dependencies, and the absence of foreign-table Account/Task shadow entities.
## Hand-derived expected result
The Project aggregate is under `feature.project.model.entity`, persistence under `feature.project.repository`, business logic under `feature.project.service`, the service has zero JDBC collaborators, and Account/Task persistence remains owned by those features.
## RED
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectPersistenceStructureTest test
```
**Observed result**
```text
[ERROR] cannot find symbol: class ProjectUserRepository
[ERROR] cannot find symbol: class ProjectInternProfileRepository
[ERROR] cannot find symbol: class ProjectTaskRepository
[INFO] BUILD FAILURE
```
The RED was observed after removing Project-owned shadow mappings of Account and Task tables. It proves the service still required cross-feature dependencies and could not be made green by retaining forbidden repositories.
## GREEN
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectPersistenceStructureTest test
```
**Observed result**
```text
[INFO] Running com.lab.labtimesheet.feature.project.repository.ProjectPersistenceStructureTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## Affected suite
**Command and result**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=LayerStructureTest,ProjectPersistenceStructureTest,ProjectEntityTest test
[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## External-test boundaries
This check does not prove database mappings, transaction behavior, MVC routing, or runtime authorization; those remain covered by PostgreSQL and MockMvc tests.
+73
View File
@@ -0,0 +1,73 @@
# Test Evidence: Authorized Project pages
- **Test type:** Web
- **Requirement IDs:** `AUTH-001`, `AUTH-002`, `AUTH-006`, `PRJ-001`, `PRJ-004``PRJ-006`, `SEC-001`, `ERR-001`
- **Scenario IDs:** `AC-AUTH-001`, `AC-AUTH-002`, `AC-AUTH-007`, `I1-PRJ-05`
- **Test class/method:** `com.lab.labtimesheet.feature.project.controller.ProjectControllerTest`
- **Implementation commit:** `25a855e`
## Protected behavior
Authenticated users receive only authorized Project routes; guessed IDs return a non-disclosing not-found response; valid Mentor create requests use the authenticated identity; invalid forms do not mutate; state changes require CSRF.
## Test method
MockMvc exercises the real controller, binding, Bean Validation, exception mapping, view selection, redirect, Spring Security authentication, and CSRF filter. Only application/query services are mocked.
## Hand-derived expected result
An authorized list request renders `projects/list`. An unauthorized direct ID returns 404. Member and leadership routes authorize through actor plus Project ID. A valid create redirects to the created detail ID; a blank name and zero Leader ID render field errors and make no service call. POST without CSRF returns 403.
## RED
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectControllerTest test
```
**Observed result**
```text
[ERROR] cannot find symbol: class ProjectController
[ERROR] cannot find symbol: class ProjectPageService
[INFO] BUILD FAILURE
```
## GREEN
**Command**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
./mvnw -Dtest=ProjectControllerTest test
```
**Observed result**
```text
[INFO] Running com.lab.labtimesheet.feature.project.controller.ProjectControllerTest
[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## Affected suite
**Command and result**
```text
export JAVA_HOME=/opt/homebrew/opt/openjdk@25
export PATH="$JAVA_HOME/bin:$PATH"
export DOCKER_HOST=unix:///Users/sechmachine/.orbstack/run/docker.sock
./mvnw test
[INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
## External-test boundaries
This slice does not prove PostgreSQL query correctness, a real login flow, shared-shell navigation, browser accessibility, or Iteration 2 invitation/exit/completion pages. The activation route remains deferred with `I1-PRJ-04` until the Task feature query dependency is available.