refactor: 각 어댑터터별 리펙토링 진행

This commit is contained in:
DongHyeonka
2026-08-24 18:26:40 +09:00
parent e98b56eb03
commit 0137263441
439 changed files with 31935 additions and 4719 deletions
@@ -5,41 +5,20 @@
// Flyway migrations live only under the .postgresql subpackage (ArchUnit keeps the base neutral).
// The JPA relational persistence platform (docs/superpowers/specs/2026-08-11-jpa-persistence-
// platform-design.md) models itself as 18 Stable library modules. This repository's fail-closed
// 19-leaf registry outranks that layout, so those modules are packages here and
// module registry outranks that layout, so those modules are packages here and
// JpaModuleBoundaryTest enforces the design's module dependency table. The full mapping is in
// docs/jpa/repository-adaptation.md.
//
// The testkit is its own source set rather than part of `test` because more than one lane consumes
// it and because a source set whose dependencies are declared only on the test configurations gives
// the design's "no production module depends on the testkit" guarantee without a new Gradle project.
sourceSets {
postgresqlIntegrationTest {
java.setSrcDirs(['src/postgresqlIntegrationTest/java'])
resources.setSrcDirs(['src/postgresqlIntegrationTest/resources'])
compileClasspath += sourceSets.main.output
runtimeClasspath += output + compileClasspath
strictTestLanes {
sourceSet('postgresqlIntegrationTest') {
compilesAgainst 'main'
inherits 'implementation', 'compileOnly', 'runtimeOnly', 'annotationProcessor'
}
testkit {
java.srcDir 'src/testkit/java'
compileClasspath += sourceSets.main.output
runtimeClasspath += output + compileClasspath
}
jpaPlatformPerformanceTest {
java.srcDir 'src/jpaPlatformPerformanceTest/java'
compileClasspath += sourceSets.main.output + sourceSets.testkit.output
runtimeClasspath += output + compileClasspath
}
}
configurations {
postgresqlIntegrationTestImplementation.extendsFrom testImplementation
postgresqlIntegrationTestCompileOnly.extendsFrom testCompileOnly
postgresqlIntegrationTestRuntimeOnly.extendsFrom testRuntimeOnly
postgresqlIntegrationTestAnnotationProcessor.extendsFrom testAnnotationProcessor
testkitImplementation.extendsFrom testImplementation
testkitRuntimeOnly.extendsFrom testRuntimeOnly
jpaPlatformPerformanceTestImplementation.extendsFrom testImplementation
jpaPlatformPerformanceTestRuntimeOnly.extendsFrom testRuntimeOnly
sourceSet('testkit') { compilesAgainst 'main' }
sourceSet('jpaPlatformPerformanceTest') { compilesAgainst 'main', 'testkit' }
}
// The testkit as a consumable artifact.
@@ -49,30 +28,9 @@ configurations {
// "domain must not depend on Hibernate" were verified as library code and applied to nothing. The
// composition root is the only place that can see every runtime leaf at once, so it is where the
// production suite belongs — and it needs the rules.
tasks.register('testkitJar', Jar) {
archiveClassifier = 'testkit'
from sourceSets.testkit.output
}
configurations {
jpaTestkit {
canBeConsumed = true
canBeResolved = false
}
}
artifacts {
jpaTestkit(tasks.named('testkitJar', Jar))
}
// Every test lane compiles and runs against the testkit.
sourceSets.test {
compileClasspath += sourceSets.testkit.output
runtimeClasspath += sourceSets.testkit.output
}
sourceSets.postgresqlIntegrationTest {
compileClasspath += sourceSets.testkit.output
runtimeClasspath += sourceSets.testkit.output
testkitPublisher {
consumedBy 'test', 'postgresqlIntegrationTest'
publishAs 'jpaTestkit'
}
ext.jpaPostgreSqlEvidenceImage = 'postgres:16-alpine'
@@ -313,10 +271,12 @@ def jpaPlatformSecurityTest = registerJpaPlatformLane(
// The pool behaviour contract. Named for what it does.
//
// It was `jpaPlatformPerformanceTest`, described as certifying pool and REQUIRES_NEW pressure, and
// gated by `performance.assertions.enabled` — which defaulted to false everywhere, including in the
// nightly workflow that set it explicitly to false. So the release gate depended on a lane whose
// only threshold assertion was that thresholds were not being asserted. "Certified" described a
// run in which no latency or throughput bound was ever compared to anything.
// gated behind a boolean that defaulted to off everywhere it appeared — in this file, and in the
// nightly workflow that set it explicitly to off. So the release gate depended on a lane whose only
// threshold assertion was that thresholds were not being asserted, and "certified" described a run
// in which no latency or throughput bound was ever compared to anything. The property is gone; its
// name is deliberately not repeated here, because a name in a comment is the next thing somebody
// tries to set.
//
// What the lane genuinely verifies is a behaviour contract: a REQUIRES_NEW depth of one needs two
// connections per concurrent thread, a saturated pool reports its pending count, and a caller waits
@@ -349,4 +309,48 @@ tasks.register('jpaPlatformReleaseGate') {
dependsOn jpaPlatformPoolContractTest
}
// The unit lane reads three files that are not Java sources: the release registry and its two
// renderings. Without declaring them, Gradle calls the lane up-to-date after a registry demotion or
// a workflow edit — so the drift check that exists to catch exactly that edit never runs on it.
// The unit lane reads files that are not Java sources: the release registry, its two renderings,
// and the documents that describe the pool lane. Without declaring them, Gradle calls the lane
// up-to-date after a registry demotion or a workflow edit — so the drift checks that exist to catch
// exactly those edits never run on them.
tasks.named('test') {
inputs.file(rootProject.file('config/jpa/release-registry.json'))
inputs.file(new File(rootProject.projectDir.parentFile, 'docs/jpa/support-matrix.md'))
inputs.file(new File(rootProject.projectDir.parentFile, 'docs/jpa/repository-adaptation.md'))
// The whole directory, not the two named workflows: the Experimental-major check asks whether
// *some* lane records that major as its target, so adding or deleting any workflow can change
// its answer. Naming files here would leave the lane that matters outside the up-to-date check.
inputs.dir(new File(rootProject.projectDir.parentFile, '.github/workflows'))
inputs.file(file('build.gradle'))
inputs.dir(file('src/jpaPlatformPerformanceTest/java'))
}
// verifyJpaApiSurface — every public type this leaf exposes is a committed decision.
//
// The GraphQL and Mongo leaves already carried this; the largest of the three did not, so the one
// public surface with the most adopters was the one nothing had an opinion about. The convention
// plugin is opt-in per leaf, and opting in was simply never done here.
//
// This is a record, not a budget, and the distinction matters. A snapshot shrinks nothing on its
// own: the GraphQL surface grew from 373 types to 398 while under one, each addition approved and
// none refused. What the baseline buys is that growth is visible in review at the moment it
// happens and that the number is available to argue with — not that the number cannot rise. A
// ceiling the approval flag cannot lift is a separate decision nobody has taken yet.
// `api` is the surface an adopter is meant to reach; everything else here is a candidate to become
// internal at that point.
apiSurface {
label = 'Jpa'
baseline = rootProject.file('../docs/architecture/jpa-api-surface.txt')
description = 'JPA persistence leaf public API surface — every public top-level type in src/main/java.'
rationale = [
'A public type in a single-jar leaf is reachable from every adopter\'s code, so',
'additions are reviewed rather than discovered. `api` is the intended external',
'surface; the rest is implementation that has not been moved under an internal',
'root yet.',
]
}
apply from: rootProject.file('gradle/jpa-evidence.gradle')