Skip to content

[Budget/Notification] atomic accounting lifecycle에 threshold 알림 연결 #48

Description

@HuitaePark

배경

기존 #28은 missing pricing과 budget notification 연결을 한 이슈에 묶었다. 그러나 notification은 Week 3 atomic reservation/reconciliation의 domain event를 소비해야 하며, Week 1 legacy evaluator에 먼저 연결하면 lifecycle 구현 후 다시 작성하게 된다.

이 이슈는 pricing resolution과 분리하여 실제 budget/accounting 상태 전이에 notification을 연결한다.

목표

atomic accounting transition
→ threshold decision
→ notification event
→ deduplicated best-effort handler

notification 실패는 회계 결과와 provider 응답을 바꾸지 않는다.

구현 범위

  • #27의 typed BudgetKeyBudgetWindow를 그대로 사용한다.
  • #37의 commit/block/reconciliation 결과에서 threshold decision을 만든다.
  • 같은 policy/target/window/threshold event를 중복 발행하지 않는다.
  • threshold가 HALF → WARNING → EXCEEDED로 상승하면 각 단계는 한 번씩 발행한다.
  • 새 window에서는 같은 threshold를 다시 발행할 수 있다.
  • BudgetThreshold.NONE은 발행하지 않는다.
  • 동일 idempotency key의 duplicate commit은 알림을 다시 만들지 않는다.
  • handler마다 실패를 격리하고 다음 handler를 계속 실행한다.
  • handler 실패는 accounting 상태를 rollback하거나 provider 응답을 실패시키지 않는다.
  • bounded/sanitized error hook을 제공한다.

전달 보장

  • MVP delivery는 best-effort다.
  • 회계 상태와 notification 전송을 하나의 durable transaction으로 묶지 않는다.
  • durable outbox가 없으므로 exactly-once delivery를 주장하지 않는다.
  • 재시작 뒤 재전송, Slack/email adapter는 후속 범위다.

필수 테스트

  • NONE은 알리지 않는다.
  • 같은 key/window의 같은 threshold 반복은 한 번만 전달된다.
  • HALF, WARNING, EXCEEDED 상승은 각각 한 번 전달된다.
  • 새 window에서는 threshold를 다시 알릴 수 있다.
  • duplicate commit/reconcile은 중복 알림을 만들지 않는다.
  • handler 하나가 실패해도 다음 handler가 실행된다.
  • handler 실패가 commit/block 결과를 뒤집지 않는다.
  • 병렬 요청에서도 dedup key가 원자적으로 동작한다.

Acceptance criteria

  • legacy evaluate() 호출이 아니라 atomic accounting 결과를 소비한다.
  • budget key/window 계산을 notification에서 다시 구현하지 않는다.
  • dedup key와 보존 기간이 문서화된다.
  • 실패 격리와 전달 보장 수준이 [ADR] 단일 accounting writer와 unresolved liability·event 실패 정책 정의 #46 Accounting lifecycle ADR과 일치한다.
  • notification event에 prompt, raw provider response, API key가 포함되지 않는다.

제외 범위

  • durable outbox
  • Slack/email/webhook 실제 전송 adapter
  • 재시작 후 자동 replay
  • 사용자별 임의 notification rule language

의존관계

Source

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmvpTokenPilot 0.1.0 MVP scope

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions