Skip to content

Insurance category, coverage type, and period baseline (#120)#121

Merged
MasterOfEVNSolution merged 1 commit into
devfrom
cc-114-insurance-category-and-period
May 8, 2026
Merged

Insurance category, coverage type, and period baseline (#120)#121
MasterOfEVNSolution merged 1 commit into
devfrom
cc-114-insurance-category-and-period

Conversation

@tkdgusqkr

Copy link
Copy Markdown
Contributor

Summary

  • insurance_items 에 분류(PRIMARY/ADDON), 보장유형(유상운송종합/책임/시간제/원데이/기타), 기본 기간(unit + value) 컬럼 추가.
  • rider_insurancesstarts_at / ends_at / rider_bike_contract_id 추가 — 보험 라이프사이클 + 계약 연결 표현 가능.
  • 4개 기본 보험 시드 (유상운송종합/책임 12개월 + 시간제 + 원데이). UUID 가 deterministic 이라 Slice A 의 `default_insurance_item_id` 가 향후 가리킬 수 있음.
  • Service 검증: half-supplied default duration 거부, endsAt > startsAt 강제, 기존 unique 정책 유지.

Trace

Scope

Backend-only. Slice A 와 같은 패턴이며 보험 도메인만 건드림. 기존 unique 정책은 유지하고 ADDON 다중 발급(시작시점별 unique)은 후속 슬라이스로 분리.

Included:

  • Flyway V8 + 시드 4개.
  • `InsuranceCategory` / `InsuranceCoverageType` / `InsuranceDurationUnit` enum.
  • `InsuranceItem` / `RiderInsurance` 엔티티 + Create/Update/Read DTO + Service.
  • 통합 테스트 `InsuranceClassificationApiTests` (8 케이스).

Excluded:

  • 자동 보험 발급 로직 (Slice D).
  • ADDON 다중 발급 partial-unique 정책 변경 (후속).
  • 라이더 교육 (Slice C — 별도 PR).
  • 프론트 어드민 폼 (Slice E).

Validation

항목 결과
`./gradlew compileJava compileTestJava` ✅ BUILD SUCCESSFUL (19s)
`./gradlew test --tests ArchitectureBoundaryTests ScaffoldPackageSkeletonTests` ✅ BUILD SUCCESSFUL (24s)
Testcontainers 통합 테스트 (`./gradlew test` 전체) ⚠️ Docker 미설치로 sandbox 미실행. 리뷰어/IDE 환경 검증 필요.

Test plan

  • IDE에서 `./gradlew test` 전체 (Testcontainers PostgreSQL 포함) 실행 → `InsuranceClassificationApiTests` 8개 통과 + 기존 `InsuranceItemCommandApiContractTests` / `RiderInsuranceCommandApiContractTests` / `ReadOnlyApiContractTests` 회귀 없음.
  • V8 시드 4행이 dev DB 에 반영되는지 (`select count(*) from insurance_items where id like 22222222-2222-2222-2222-%` = 4).
  • 기존 보험 행은 `category=PRIMARY` 디폴트로 보존되는지.
  • 라이더-보험 링크 생성 시 `endsAt < startsAt` 가 `409 INVALID_STATE_TRANSITION` 으로 거부되는지.
  • 어드민 웹 어드민 폼이 새 컬럼 없이 `name` / `description` / `enabled` 만 보내는 페이로드도 그대로 동작하는지 (legacy 호환).

Concurrent work gate

Note

Slice A (PR #119) 와 파일 충돌 0 — 다른 도메인. dev 머지 순서 무관. 향후 Slice D 에서 contract template + insurance item 자동 발급 로직을 도입할 때 두 슬라이스가 모두 머지된 상태가 전제.

Slice B of the contract/insurance/education classification work. Introduces a
classification + period model on the insurance domain so the operator can
describe an item as PRIMARY (12개월 메인) or ADDON (시간제/원데이 등 부가),
pin a coverage type aligned with the 유상운송 product line, and stamp each
rider-insurance link with its own starts_at / ends_at lifecycle plus a no-FK
pointer to the rider-bike contract that triggered the insurance.

Schema (Flyway V8):
- insurance_items: category (PRIMARY|ADDON), coverage_type
  (GENERAL_PAID_TRANSPORT|LIABILITY_PAID_TRANSPORT|HOURLY|ONE_DAY|OTHER),
  default_duration_unit, default_duration_value, with check constraints +
  category active index.
- rider_insurances: starts_at, ends_at, rider_bike_contract_id, with period
  check constraint and (rider_id, starts_at, ends_at) period index plus
  contract pointer index.
- 4-row seed: 유상운송종합/책임 (PRIMARY × MONTH × 12) + 시간제 (ADDON ×
  HOUR × 1) + 원데이 (ADDON × DAY × 1). Deterministic UUIDs (`22222222-…`)
  so Slice A's contract_templates.default_insurance_item_id pointer can
  resolve them in a follow-up slice.
- Existing rows default to category=PRIMARY; the unique policy on
  (rider_id, insurance_item_id) WHERE deleted_at IS NULL stays untouched in
  this slice. ADDON multi-issue (issue per starts_at) needs a follow-up
  partial-unique change and is intentionally deferred.

API:
- InsuranceItemCreateRequest accepts both legacy (name/description/enabled)
  and structured (category + coverageType + defaultDuration) shapes.
- InsuranceItemUpdateRequest mirrors the structured fields with per-field
  provided flags.
- RiderInsuranceCreateRequest/UpdateRequest add startsAt, endsAt,
  riderBikeContractId.
- Read response DTOs expose all new fields.
- Service-layer validation: rejects half-supplied default durations
  (`durationUnit`/`durationValue` must come together), enforces
  endsAt > startsAt on rider-insurance links, keeps the existing
  ResourceNotFound / ReferenceNotFound / DUPLICATE_ACTIVE_RESOURCE / INVALID
  STATE_TRANSITION error contract.

Tests:
- New InsuranceClassificationApiTests covers V8 seed presence, structured
  create, legacy compatibility, half-duration rejection, classification
  PATCH, period rejection (endsAt before startsAt), and the contract-pointer
  pass-through on rider-insurance create.
- Existing InsuranceItemCommandApiContractTests / RiderInsurance flows stay
  green via the legacy create paths on the request DTOs.

Trace:
- Target issue: #120
- Change-control issue: EVNSolution/clever-change-control#114

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants