Commit Graph
27 Commits
Author SHA1 Message Date
DongHyeonka 21234e38cd feat: grpc 기능 deep 구현 2026-08-31 07:28:39 +09:00
DongHyeonka a24ece9cf7 feat: web, websocket 어댑터 추가 구현 2026-08-28 17:01:27 +09:00
DongHyeonka 0137263441 refactor: 각 어댑터터별 리펙토링 진행 2026-08-24 18:26:40 +09:00
DongHyeonka e98b56eb03 feat: jpa, messaging, notification, mongo, graphql 어댑터터 리펙토링 2026-08-18 10:59:56 +09:00
DongHyeonka 2f5d2fc219 feat: jpa, messaging, notification, mongo, graphql 어댑터터 구현체 추가 2026-08-15 13:01:58 +09:00
DongHyeonka 71c0d2122f Merge branch 'main' into worktree-messaging-platform
# Conflicts:
#	src/config/spotbugs/exclude.xml
2026-08-14 15:15:37 +09:00
DongHyeonka d646c2f12f feat(messaging): 브로커 중립 메시징 플랫폼 24개 leaf 추가
messaging-superpowers-package 설계서/계획서 기반 구현.
registry를 19 → 43 leaf로 확장하고 src/messaging 아래 24개 leaf를 등록.

- core-api: M1 publish/consume + M2 batch·delayed·pause-resume
- policy/transport-spi: 재시도 결정, DLQ orchestration, admission control, lifecycle
- kafka·rabbit(Stable): contiguous commit, confirm/return 상관, 배치, 보안 설정
- pulsar·nats(Experimental): 기본 비활성, live 인증 없음을 코드로 기록
- outbox/inbox/claim-check: 트랜잭션 결합, lease, 무결성 검증
- admin: plan → approve → execute를 타입으로 강제
- 문서 9종, infra compose 7종, JMH 벤치마크 3종

검증: 아키텍처 게이트 3종 통과, 24개 leaf 전부 check 통과,
messaging 테스트 604개 통과/0 실패.

미완: 계획서가 요구한 실 브로커 IT 40개 중 7개만 작성.
Rabbit 13 / Outbox 6 / Inbox 4 / NATS·Pulsar·Share 5 / testkit 2 /
starter·admin 3, 그리고 TLS·ACL 2개가 남음.
2026-08-14 14:55:38 +09:00
DongHyeonka ae85f23dd3 Merge branch 'main' into worktree-jpa-persistence-platform 2026-08-14 14:06:21 +09:00
DongHyeonkaandClaude Opus 5 0e61f86eb5 feat(jpa): implement the JPA relational persistence platform
Implements the Stable and Experimental JPA persistence platform designs
against real PostgreSQL, adapted to this repository's fail-closed 19-leaf
registry.

The design models the platform as 25 Gradle projects. `src/settings.gradle`
throws unless the registry holds exactly 19 leaves, so the plan's modules
become packages inside `:adapter:outbound:persistence-jpa` (starter in
`:app-bootstrap`, testkit in its own source set). The full mapping, the
renames this repository's naming gate required, and every deliberate
substitution are recorded in `docs/jpa/repository-adaptation.md`.

Seven Docker-backed lanes replace the plan's seven JVM test suites. Each
fails closed: a lane that discovers nothing, or a container that cannot
start, is an error rather than a skip.

Three defects the contracts found against a real server:

- `CommitFailureClassifier` treated only SQLSTATE 40003, class 08, and
  transport breaks as completion-unknown. A backend terminated mid-commit
  reports 57P01, and the commit record may already be in the WAL — so a
  possibly-committed transaction could be re-run. 57P01/57P02/57P03 now
  classify as completion-unknown.
- `SchemaTenantMigrationOrchestrator` recorded `MigrateResult`'s target
  version, which is empty for a tenant already current, reporting migrated
  tenants as unmigrated during a partial rollout. It now reads the applied
  version back from the tenant's schema history.
- `JpaStreamExecutor` checked only the declared return type for reactive
  publishers, and `RegisteredPostgreSqlCopyLoader` passed the COPY timeout
  to `SET`, which is parsed before parameter binding.

`JpaModuleBoundaryTest` enforces the plan's module map as package rules;
`verifyCleanArchitectureDependencies` governs edges between leaves and
cannot see these. Its first assertion is that the import is non-empty,
because every rule under it is a `noClasses()` rule and would pass
vacuously on an empty import.

Verified: 128 container tests across all seven lanes, 1183 unit tests,
`:adapter:outbound:persistence-jpa:check`, `:app-bootstrap:check`,
`verifyCleanArchitectureDependencies`, `verifyOneTypePerFile`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 14:06:18 +09:00
DongHyeonka 92744c57de merge: integrate the notification delivery platform 2026-08-14 14:00:07 +09:00
DongHyeonkaandClaude Opus 5 701ba67456 feat(notification): implement the notification delivery platform
Maps the 31-module plan onto the registry's 19 leaves as packages; the two
edges the registry forbids (provider->httpclient, inbox->messaging) are
replaced by application-owned ports. See docs/notification/module-mapping.md.

Acceptance is not delivery: ProviderSubmissionResult refuses to carry a
delivery outcome, and AMBIGUOUS is a first-class terminal state that blocks
automatic retry and fallback until reconciliation resolves it.

Providers: SES (SigV4 + SNS callback), Twilio (X-Twilio-Signature +
reconciliation), FCM (FID-primary batch), APNs, Web Push (RFC 8030/8291/8292),
SMTP and webhook. Contact points are AES-256-GCM encrypted with a separate
HMAC lookup fingerprint; nothing raw reaches a log, metric tag or exception.

Dispatch commits the attempt row, calls the provider with no transaction open,
then records the outcome; the durable queue uses FOR UPDATE SKIP LOCKED.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 13:57:27 +09:00
DongHyeonkaandClaude Opus 5 d57d2f62a0 feat(mongodb): implement the MongoDB document persistence platform
Implements the mongodb-superpowers-package design: Stable Tasks 1-50 and
Advanced Tasks 1-15.

The design assumes 19 Stable + 12 Advanced Gradle projects under
modules/mongodb*. This repository's fail-closed registry declares exactly 19
leaf identities, so those modules become package boundaries inside the
registered leaf :adapter:outbound:persistence-mongo, with the design's module
dependency table enforced by ten ArchUnit rules. The mapping and every
deviation are recorded in docs/mongodb/repository-adaptation.md.

Contract highlights, all enforced by tests rather than convention:

- Transaction body retry and commit retry are separate loops. A new session per
  body attempt; commit-only retry on an unknown commit. The body is never
  replayed after a commit ambiguity, so a failover cannot become a duplicate.
- MongoExecutionOutcome keeps both ambiguous outcomes distinct from success and
  failure, and MongoFailureContext records only the design-permitted fields.
- Failure classification reads server error labels before numeric codes.
- BSON representations come from a pinned manifest, never a library default,
  and a golden type-signature gate fails on any drift.
- Index and validator changes go through the manifest and the admin plane;
  metadata ownership gates every drop.
- Every Advanced capability refuses construction unless its flag is enabled.

Verified against real servers, not only unit tests. Running the lanes for the
first time exposed four defects that a green `check` had hidden:

- Four release lanes passed while executing zero tests; the gate now counts
  executed tests per lane and fails on zero.
- The "single replica set" fixture was a standalone, because Testcontainers 2.x
  needs withReplicaSet(); its test only asserted a connection string.
- The three-node fixture was three independent clusters, so no election could
  occur, and awaitNewPrimary() compared against the post-stop primary.
- The migration lease checked modifiedCount, so a same-millisecond refresh read
  as a lost lease.

scripts/verify-mongodb-platform.sh now reports:
  9 lanes, 0 skipped, 0 failed, every evidence category produced.

scripts/verify-mongodb-advanced.sh reports NOT PROMOTABLE: actual-topology
evidence (real sharded cluster, real KMS, real target deployment) is
unobtainable here, so it is named rather than assumed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 13:41:00 +09:00
DongHyeonka 0a6dd0e419 refactor: adapter 구현중.. 2026-08-13 02:21:34 +09:00
DongHyeonkaandClaude Opus 5 0cd959a494 feat(httpclient): close the platform review's P0/P1/P2 findings
The review found one defect shape repeated across the platform: surfaces
that were declared, bound, and documented, but that nothing read. An
operator configuring fullUrlRecording, bodyLogging, retry.policy,
validatedDnsPinning, timeout.dns, or any of ten declared metric names got a
guarantee the code never delivered. Every such surface is now in exactly one
of three states -- wired for real, rejected at startup, or registered in a
test-enforced gap list with its reason. No silent no-ops remain.

P0:
- Activate the platform from bootstrap behind app.httpclient.enabled, with a
  single auto-configuration importing the nine child configurations.
- Give the platform a strict, repository-level ENV contract: 74 leaf fields
  derived from the settings record tree, unknown APP_HTTPCLIENT_* rejected.
- Route typed HTTP service clients through the call kernel via
  KernelHttpExchangeAdapter, so they stop bypassing platform policy.
- Pin dynamic-target DNS resolution to the socket for the life of a call,
  closing the resolve-then-connect TOCTOU / rebinding window.
- Actually transmit the idempotency key, and make retry eligibility depend on
  transmission rather than on merely holding one.
- Reject reactive authentication and reactive redirect at startup instead of
  declaring support that does not function.
- Fix the Reactor-only Stable contract row so the lane stops failing.
- Stop advertising HTTP/3 on a transport that negotiates HTTP/1.

P1 covers execution and retry accounting, redirect security (per-hop target
guarding, sensitive-header stripping, 303 body handling), runtime rotation
and transport resource ownership keyed by generation, dynamic-target
hardening (subdomain matching, global-unicast classification, strict CIDR
parsing), protocol intent, pool and timeout wiring, streaming and body
limits, observability parity, and OAuth single-flight refresh on a bounded
pool with a bounded wait.

P2 covers configuration and documentation drift, the Gradle check wiring for
the four hermetic lanes, and the CI gate matrix.

Two test-quality defects surfaced while closing these: the HTTP/2 stream
saturation test ran against cleartext HTTP/1.1 while asserting nothing about
the protocol, and an OAuth contention test slept on a latch that could fire
before the callers it meant to observe. Both now assert what their names
claim.

Verification run: :adapter:outbound:httpclient:check and :app-bootstrap:check
(checkstyle, spotless, spotbugs, and the four hermetic lanes),
verifyCleanArchitectureDependencies, verifyEnvKeys, verifyOneTypePerFile,
verifyDependencyLocks, the documentation and gate-matrix verifiers, and the
performance lane against a real TLS+ALPN HTTP/2 server.

Not executed, and tracked rather than claimed: Docker/Toxiproxy fault
injection, JMH, a real QUIC/HTTP3 server, a real Spring Framework 6.2
distribution (now a delegated-pending gate), live OAuth/TLS/proxy/DNS
integration, and a whole-repository check.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 16:49:31 +09:00
DongHyeonkaandClaude Opus 5 5f10b791d3 chore: record pre-existing uncommitted repository state
Snapshot of the in-flight state that already existed, identically, in both
this worktree and the main checkout before this session began: the initial
HTTP Client platform implementation (previously untracked), the redis-lab
removal, and the JPA / object-storage / notification integration work.

Kept separate from this session's HTTP Client review response, which lands
in the following commit, so the two bodies of work stay reviewable apart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 16:48:43 +09:00
donghyeon-ka 1a3b560678 merge: integrate object storage production capability 2026-08-01 00:57:40 +09:00
donghyeon-ka 7e610b5219 merge: integrate notification production capability
# Conflicts:
#	docs/superpowers/plans/2026-07-28-notification-production-capability.md
#	src/adapter/outbound/persistence-jpa/build.gradle
#	src/adapter/outbound/persistence-jpa/gradle.lockfile
#	src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/transaction/SpringTransactionPort.java
#	src/app-bootstrap/src/test/java/dev/caskeleton/bootstrap/architecture/CleanArchitectureTest.java
#	src/application-core/src/main/java/dev/caskeleton/application/notification/NotificationCapabilityCompatibilityValidator.java
#	src/application-core/src/main/java/dev/caskeleton/application/notification/NotificationDeliveryStorePort.java
#	src/application-core/src/main/java/dev/caskeleton/application/notification/NotificationDispatchUseCase.java
#	src/application-core/src/main/java/dev/caskeleton/application/notification/NotificationFrozenPlan.java
#	src/application-core/src/main/java/dev/caskeleton/application/notification/NotificationMaintenanceCommand.java
#	src/application-core/src/main/java/dev/caskeleton/application/notification/NotificationMaintenanceResult.java
#	src/application-core/src/main/java/dev/caskeleton/application/notification/NotificationMaintenanceStorePort.java
#	src/application-core/src/test/java/dev/caskeleton/application/notification/NotificationCapabilityCompatibilityValidatorTest.java
#	src/application-core/src/test/java/dev/caskeleton/application/notification/NotificationDispatchUseCaseTest.java
#	src/application-core/src/test/java/dev/caskeleton/application/notification/NotificationMaintenanceUseCaseTest.java
#	src/application-core/src/test/java/dev/caskeleton/application/notification/NotificationPlanningBoundaryTest.java
#	src/application-core/src/test/java/dev/caskeleton/application/notification/NotificationValueContractTest.java
#	src/application-core/src/test/java/dev/caskeleton/application/notification/ReconcileNotificationDeliveriesUseCaseTest.java
2026-08-01 00:11:53 +09:00
donghyeon-ka bbccccc195 merge: integrate messaging R2 polling producer
# Conflicts:
#	docs/superpowers/specs/2026-07-28-messaging-production-capability-design.md
#	src/app-bootstrap/gradle.lockfile
#	src/app-bootstrap/src/test/java/dev/caskeleton/bootstrap/architecture/ArchitectureViolationFixtureTest.java
#	src/build.gradle
2026-08-01 00:04:02 +09:00
donghyeon-ka a05a8ada92 merge: integrate JPA production capability
# Conflicts:
#	.github/ci-gate-matrix.yml
#	.github/scripts/verify-gate-matrix.sh
#	.github/workflows/ci-quality-gates.yml
#	src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/transaction/SpringTransactionPort.java
2026-07-31 23:57:29 +09:00
donghyeon-ka 567422f2e5 feat: add production capability foundations 2026-07-31 23:50:44 +09:00
donghyeon-ka f0a6d1c8c8 feat: add object storage production capability 2026-07-31 23:50:03 +09:00
donghyeon-ka ec4bf105c4 feat: add notification production capability 2026-07-31 23:48:58 +09:00
donghyeon-ka 7eb6af5d5f feat: add JPA production capability 2026-07-31 23:48:51 +09:00
donghyeon-ka e5af291269 feat: add messaging R2 polling producer 2026-07-31 23:48:43 +09:00
donghyeon-ka b3add0162d feat: redis, fileserver, httpclient 런타임 시점 구현 추가 2026-07-28 14:26:54 +09:00
donghyeon-ka 7363b2aa1e chore: plan 파일 업로드 2026-07-26 13:36:32 +09:00
DongHyeonka 821fe00c32 init: 클린 아키텍처 백엔드 2026-07-24 14:29:36 +09:00