이 디렉토리의 목적은 계정 / 조직 / 기사 / 인사문서 / 배송원천기록 / 정산 / 차량 / 배차 / 권역 / 공지 / 지원 / 알림 / 단말 / 텔레메트리 경계를 로컬 Docker Compose 환경에서 실제로 띄워 보는 것이다. 더 이상 boundary skeleton만 있는 상태가 아니라, 현재는 독립 Django 서비스들, telemetry ingress용 Python worker 1개, local MQTT broker 1개, React/Vite 앱 2개까지 포함한 실행형 부트스트랩 구조를 가진다.
현재 compose 파일 위치는 상위 docker-compose.account-driver-settlement.yml이다.
image deploy pilot용 compose 파일은 docker-compose.deploy.account-driver-settlement.yml 이다.
현재 runtime source는 sibling target repo만 참조한다.
surviving frontend repo path는 ../front-web-console이며, compose runtime service도 web-console로 수렴했다.
env template 규칙은 분리된다.
- 로컬 통합 검증 compose는
../infra/env/local/템플릿을 사용한다. - 배포 runtime compose는
../infra/env/deploy/템플릿을 사용한다. seed-runner는 로컬 검증 경로이므로../infra/env/local/만 사용한다.- 로컬 편의 설정은 deploy env로 승격하지 않는다.
현재 MSA API 문서 entry는 api-docs/README.md다.
gatewayweb-consoleaccount-auth-apidriver-profile-apipersonnel-document-registry-apisettlement-payroll-apisettlement-registry-apidelivery-record-apisettlement-ops-apiorganization-master-apivehicle-asset-apidispatch-registry-apiregion-registry-apiregion-analytics-apiannouncement-registry-apisupport-registry-apinotification-hub-apiterminal-registry-apitelemetry-hub-apitelemetry-listenertelemetry-dead-letter-apimqtt-brokerdriver-vehicle-assignment-apivehicle-ops-apidispatch-ops-apidriver-ops-apiaccount-dbdriver-dbpersonnel-document-dbsettlement-dbsettlement-registry-dbdelivery-record-dborg-dbvehicle-dbdispatch-registry-dbregion-registry-dbregion-analytics-dbannouncement-registry-dbsupport-registry-dbnotification-hub-dbterminal-dbtelemetry-dbtelemetry-dead-letter-dbassignment-dbredisseed-runner
vehicle-asset-api는 Vehicle Asset master-only CRUD를 제공한다.- canonical field set은 현재 bootstrap에서는
vehicle_id,company_id,fleet_id?,plate_number,vin,vehicle_status다. - target design에서는
vehicle_master와vehicle_operator_access로 분리되며, 단일company_id/fleet_id테이블로 남지 않는다. driver-vehicle-assignment-api는driver_vehicle_assignment정본을 맡는다.vehicle-ops-api는 leanVehicle Opsquery service다.- current runtime authoritative contract는 05-vehicle-ops-read-model.md의 current runtime / bootstrap Phase 1 section을 따른다.
- post-refactor target contract는 같은 문서의 post-refactor target section을 따른다.
web-console /vehicles는 현재Vehicle Opssummary contract를 사용한다.- current runtime summary contract는
Vehicle Registry + Driver Vehicle Assignment + Telemetry Hub + Terminal Registry + Organization Registry를 읽는다. - current runtime detail은
current_terminalblock을 포함한다. - 이번 범위에서
Vehicle Ops Phase 1의 compose/gateway/env/front 전환이 모두 완료됐다. web-console의 차량 운영은 차량 마스터 관리와 배정 관리로 분리된다.web-console의 차량 write 경로는 계속Vehicle Asset정본 API를 사용한다.
- 서비스별 DB는 분리한다.
- 도메인 간 DB 직접 접근은 금지한다.
- 프런트는 gateway만 바라본다.
- image deploy pilot은 현재
account-auth-api,driver-profile-api두 서비스가 별도 deploy compose를 사용한다. - pilot compose는
ACCOUNT_ACCESS_IMAGE,DRIVER_PROFILE_IMAGE환경변수를 주입받아 ECR 이미지를 pull 한다. seed-runner는 서비스management command만 호출한다.- projection 전용 저장소는 이번 스코프에서 제외한다.
- UI/UX 변경은 frontend 단독 dev server가 아니라 이 로컬 통합 compose 기준으로 검증한다.
- 범용 이벤트 브로커/비동기 워커 확장은 제외하지만, telemetry ingress 검증용
mqtt-broker와telemetry-listener는 포함한다. - 로컬 broker는 deterministic smoke를 위해 고정 listener 계정으로만 publish/subscribe를 허용한다.
Driver Ops는 projection DB 대신 bounded fan-out query service로 시작한다.
Company,Fleet만 제공한다.OrgUnit은 현재 스코프에서 제거됐다.
- 로그인, refresh, logout, me, admin 계정 CRUD를 제공한다.
- Redis 기반 refresh token registry를 가진다.
- Redis 기반 login lockout을 가진다.
POST /api/auth/change-password/를 제공한다.POST /api/auth/account-driver-links/를 admin 전용 helper로 제공한다.
- 기사 기본정보 CRUD만 제공한다.
account_id(optional),company_id,fleet_id,name,ev_id,phone_number,address만 사용한다.check-ev-id중복검사 endpoint를 제공한다.
- 기사 인사문서 메타데이터 CRUD를 제공한다.
driver_id는driver-profile-apireference key로만 검증한다.- 파일 바이너리나 approval workflow는 소유하지 않는다.
- gateway 외부 prefix는
/api/personnel-documents/다.
SettlementRun,SettlementItemwrite owner CRUD를 제공한다.- local compose에서 settlement Postgres를 직접 사용한다.
- seed-runner는 이 서비스의
migrate,seed_settlements만 호출한다. - 실제 payroll calculation engine, policy/config/rate, daily/monthly settlement clone은 구현하지 않는다.
- 관련 참고는 06-settlement-process-note.md에 둔다.
- settlement policy, policy version, policy assignment registry CRUD를 제공한다.
- local compose에서 dedicated
settlement-registry-dbPostgres를 직접 사용한다. company_id,fleet_id는organization-master-apireference key로만 검증한다.- CRUD endpoint는 전부 admin-only management API이고,
health만 공개한다. - gateway 외부 prefix는
/api/settlement-registry/다.
- 배송 원천 기록과 일별 집계 입력 snapshot CRUD를 제공한다.
- local compose에서 dedicated
delivery-record-dbPostgres를 직접 사용한다. company_id,fleet_id는organization-master-api,driver_id는driver-profile-apireference key로 검증한다.- payroll 결과 row는 만들지 않고 calculation 이전 input truth만 소유한다.
- gateway 외부 prefix는
/api/delivery-record/다.
- settlement 운영 조회용 read-only fan-out runtime을 제공한다.
- dedicated Postgres container 없이 sqlite-only runtime으로 동작한다.
- upstream write owner
settlement-payroll-api를SETTLEMENT_PAYROLL_BASE_URL로 읽는다. - gateway 외부 prefix는
/api/settlement-ops/다.
- 기사 단건 운영 화면용 summary query만 제공한다.
- 내부적으로
driver-profile,organization-master,account-auth,personnel-document-registry,settlement-ops를 조회해서 하나의 summary payload로 합친다. - 배송원 정리 현황은 linked account, 회사/플릿 scope, 필수 인사문서 기준으로 계산한다.
- 근태 rule status는
pending_source, 배송이력 rule status는source_input_only로 노출한다. - settlement read consumer env 이름은
SETTLEMENT_OPS_BASE_URL이다. - 이번 단계에서는 materialized projection 저장소를 두지 않는다.
- 차량 자산 CRUD만 제공한다.
- 필드는
company_id,fleet_id(optional),plate_number,vin,vehicle_status로 제한한다. current_driver_id,terminal_id,maintenance_flag,accident_flag는 현재 범위에서 제외한다.
- 기사-차량 배정/반납 CRUD를 제공한다.
- upstream validation은
vehicle-asset-api,driver-profile-api를 읽어 수행한다. - 차량당 활성 배정 1건 제약과 deterministic seed assignment를 가진다.
dispatch_plan,vehicle_schedule,dispatch_assignment1차 계획 truth를 제공한다.service-vehicle-assignment와 다르게 current runtime assignment truth는 소유하지 않는다.- upstream validation은
vehicle-asset-api,driver-profile-api를 읽어 수행한다. operator_company_id는 FK가 아닌 dispatch-context snapshot 컬럼이다.
- 권역 기준 정본 CRUD를 제공한다.
polygon_geojson,difficulty_level,status만 소유한다.- 권역별 통계나 route knowledge는 소유하지 않는다.
- gateway 외부 prefix는
/api/regions/다.
- 권역 일별 통계와 성과 요약 CRUD를 제공한다.
service-region-registry의 기준 마스터를 다시 쓰지 않고 analytics snapshot만 소유한다.- dispatch / delivery 자동 fan-in은 아직 넣지 않는다.
- gateway 외부 prefix는
/api/region-analytics/다.
- 공지 게시 정본 CRUD를 제공한다.
status,exposure_scope,published_at,expires_at만 소유한다.- push send, inbox notifications, support workflow는 소유하지 않는다.
- gateway 외부 prefix는
/api/announcements/다.
- 지원 정본 CRUD를 제공한다.
ticket,response,handling status만 소유한다.- push send, inbox notifications, announcement posting은 소유하지 않는다.
- gateway 외부 prefix는
/api/ticket/다.
- 알림 채널 CRUD를 제공한다.
push token,general inbox,push delivery log만 소유한다.- 공지 게시나 지원 정본은 소유하지 않는다.
- phase 1의 push send는 simulated delivery log로만 동작한다.
- gateway 외부 prefix는
/api/notifications/다.
- 배차 운영 상황판용 read-model runtime을 제공한다.
dispatch-registry-api,driver-vehicle-assignment-api,vehicle-asset-api,driver-profile-api를 fan-out read 한다.- sqlite-only runtime이며 dedicated Postgres container를 두지 않는다.
- 단말 자산과 현재 차량 장착 관계 CRUD를 제공한다.
terminal_registry,terminal_installation만 소유한다.- 위치, diagnostic, MQTT raw payload는 소유하지 않는다.
- raw ingest API, normalized timeseries, latest location snapshot, latest diagnostics를 제공한다.
- 저장은 time-series 전제를 따르지만, 현재 외부 API는 latest snapshot 우선이다.
telemetry-listener가 MQTT payload를 internal ingest endpoint로 전달하면, 저장과 정규화는 계속telemetry-hub-api가 소유한다.vehicle-ops-api가 latest telemetry를 읽는다.telemetry-listener의 direct service-to-service ingest path는/ingest/raw/이며, gateway path/api/telemetry/ingest/raw/를 쓰지 않는다.
- MQTT broker subscribe와 payload forwarding만 담당하는 stateless ingress worker다.
mqtt-broker에서telemetry/#를 구독하고telemetry-hub-api의 internal ingest endpoint로 raw payload를 전달한다.- DB를 직접 쓰지 않고 telemetry 정본을 소유하지 않는다.
- hub ingest가
parse_error,hub_4xx,hub_5xx_retry_exhausted,connection_failure_retry_exhausted,timeout_retry_exhausted로 끝나면telemetry-dead-letter-api의 internal ingest endpoint로 dead-letter row를 전달한다. - smoke publish는
../scripts/publish_sample_telemetry.sh와../../service-telemetry-listener/tests/fixtures/sample_payload.json을 함께 사용한다. - helper는 publish 시점마다 sample payload의
captured_at과 diagnostic timestamp를 새로 주입하고, 이를 현재 UTC 기준 하루 뒤로 밀어서 dirty stack에서도 repeatable하게 재실행할 수 있다. - helper는 local demo MQTT credentials only(
telemetry-listener/local-mqtt-password)로 브로커에 publish한다.
- failed telemetry payload append-only storage와 admin read를 제공한다.
- internal ingest는
X-Telemetry-Dead-Letter-Key기반 producer auth만 허용한다. - phase 1 producer key는
service-telemetry-listener전용 env만 채운다. - replay/status workflow나 telemetry 정본 저장은 소유하지 않는다.
/->web-console/healthz-> gateway self-health (ALB target group probe)/api/auth/->account-auth-api/api/drivers/->driver-profile-api/api/personnel-documents/->personnel-document-registry-api/api/settlements/->settlement-payroll-api/api/settlement-registry/->settlement-registry-api/api/delivery-record/->delivery-record-api/api/settlement-ops/->settlement-ops-api/api/org/->organization-master-api/api/vehicles/->vehicle-asset-api/api/dispatch/->dispatch-registry-api/api/regions/->region-registry-api/api/region-analytics/->region-analytics-api/api/announcements/->announcement-registry-api/api/ticket/->support-registry-api/api/notifications/->notification-hub-api/api/terminals/->terminal-registry-api/api/telemetry/->telemetry-hub-api/api/telemetry-dead-letters/health/->telemetry-dead-letter-api /health//api/telemetry-dead-letters/->telemetry-dead-letter-api //api/telemetry-dead-letters/<uuid>/->telemetry-dead-letter-api /<uuid>//api/driver-vehicle-assignments/->driver-vehicle-assignment-api/api/vehicle-ops/->vehicle-ops-api/api/dispatch-ops/->dispatch-ops-api/api/driver-ops/->driver-ops-api
gateway는 서비스 prefix를 strip해서 upstream으로 전달한다. 예를 들면 /api/auth/login/ -> /login/, /api/org/companies/ -> /companies/, /api/driver-vehicle-assignments/assignments/ -> /assignments/, /api/vehicle-ops/vehicles/ -> /vehicles/, /api/dispatch-ops/board/ -> /board/, /api/telemetry/vehicles/{vehicle_id}/latest-location/ -> /vehicles/{vehicle_id}/latest-location/처럼 동작한다.
dead-letter는 예외적으로 admin-read 경로만 명시 route로 노출한다.
/api/telemetry-dead-letters/ingest/는 gateway에 노출하지 않는다./api/telemetry-dead-letters와/api/telemetry-dead-letters/health는 trailing slash가 붙은 검증 경로로 명시 redirect한다.
- ALB/외부 로드밸런서의 Health Check는
GET /healthz를 사용한다. - gateway의
/healthz는 gateway 컨테이너에서 직접 반환하는 200 응답이다. docker-compose.account-driver-settlement.yml의gateway서비스는healthcheck로/healthz를 사용한다.- ingress는
trusted proxy preservation with local fallback방식으로 header를 전달한다. 현재 dev ingress에 대해trusted_proxy=1로 간주되는 소스는10.20.0.0/24와127.0.0.1/32뿐이며, 이 범위에서 온 요청만X-Forwarded-For,X-Forwarded-Proto,X-Forwarded-Host,X-Forwarded-Port의 수신 값을 보존한다. 그 외 직접 접근(비신뢰 소스)은 8080 대상 서비스의 로컬 기본값($remote_addr,$scheme,$host,$server_port)을 사용한다. (X-Real-IP는 항상$remote_addr에서 생성)
seed-runner는 아래 순서로 동작한다.
- seed-managed 백엔드
health대기 organization-mastermigrate +seed_organizationsettlement-registrymigrate +seed_settlement_registrydriver-profilemigrate +seed_driverspersonnel-document-registrymigrate +seed_personnel_documentsdelivery-recordmigrate +seed_delivery_recordsvehicle-assetmigrate +seed_vehiclesdispatch-registrymigrate +seed_dispatchregion-registrymigrate +seed_regionsregion-analyticsmigrate +seed_region_analyticsannouncement-registrymigrate +seed_announcementssupport-registrymigrate +seed_supportterminal-registrymigrate +seed_terminalstelemetry-hubmigrate +seed_telemetrydriver-vehicle-assignmentmigrate +seed_assignmentssettlement-payrollmigrate +seed_settlementsaccount-authmigrate +seed_accounts
모든 단계는 재실행 가능하도록 idempotent하게 작성돼 있다.
현재 seed 기본값은 아래와 같다.
- admin 계정:
seed-admin@example.com / ChangeMe123! - company:
Seed Company - fleet:
Seed Fleet - driver:
Seed Driver - personnel documents:
contract 1건 + business_registration 1건 - delivery record: seeded 1건 + active daily snapshot 1건
- vehicle:
12가3456 - dispatch schedule:
2026-03-24 / shift A - region:
seo-central,seo-riverside - announcements:
ops-policy-update,driver-app-maintenance - support:
Driver App Inquiry,Settlement Inquiry - terminal:
356123456789012 - telemetry latest location:
37.5665, 126.9780 - assignment: seeded driver-vehicle relation for the same operator company