1. 최상위 엔터티 구조

아래는 **기지국 기반 위성제어 시스템 + 촬영계획시스템 연계 + 위성정보 관리 + 부가서비스 확장**을 전제로 한

카테고리: guide | 읽기시간: 42분 | 원문: 다운로드

아래는 기지국 기반 위성제어 시스템 + 촬영계획시스템 연계 + 위성정보 관리 + 부가서비스 확장을 전제로 한

인공위성(Satellite) 엔터티의 전체 속성 체계 정의안입니다.

단순 물리적 스펙이 아니라,

까지 포함하는 플랫폼 관점의 통합 속성 모델입니다.


1. 최상위 엔터티 구조

위성은 단일 테이블로 끝내면 안 됩니다.

아래와 같은 도메인 분리형 모델로 설계하는 것이 적절합니다.

Satellite
 ├─ Identification
 ├─ Orbit & Dynamics
 ├─ Physical Bus
 ├─ Payload
 ├─ Communication
 ├─ Power
 ├─ ADCS (자세제어)
 ├─ Thermal
 ├─ Onboard Computer
 ├─ Mission Profile
 ├─ Imaging Capability
 ├─ Ground Interface
 ├─ Operation Status
 ├─ Data Product Capability
 ├─ Security
 ├─ Lifecycle
 └─ Service Enablement

2. 식별(Identification) 속성

기본 식별자

분류 정보


3. 궤도 및 동역학(Orbit & Dynamics)

촬영계획 및 가시성 계산의 핵심 영역입니다.


4. 위성 본체(Bus) 사양


5. Payload (탑재체)

촬영계획 시스템과 직결되는 핵심 영역

센서 유형

영상 성능


6. 촬영 Capability (Tasking 관점)

촬영계획시스템에서 반드시 필요한 속성


7. 통신(Communication)

기지국 연동 핵심 영역

링크 정보

지상국 연동


8. 전력(Power)


9. ADCS (자세제어)


10. 열제어(Thermal)


11. 온보드 컴퓨터(OBC)


12. 운영 상태(Operation Status)

실시간 상태 관리


13. 데이터 처리/상품(Data Product Capability)

부가서비스 개발 관점 핵심


14. 보안(Security)


15. 수명주기(Lifecycle)


16. 서비스 확장(Service Enablement)

플랫폼 비즈니스 관점


17. 시스템 설계 관점에서의 핵심 엔터티 분리

실제 시스템 설계 시에는 위성을 단일 객체로 두지 않고 다음과 같이 분리하는 것이 바람직합니다:

1. Satellite Master

→ 식별/기본 정보

2. Satellite Capability

→ 촬영/통신/기술적 스펙

3. Satellite Telemetry

→ 실시간 상태

4. Satellite Mission

→ 임무 정의

5. Imaging Task

→ 촬영 요청 단위

6. Data Product

→ 생성되는 영상 상품

7. Ground Contact Session

→ 지상국 접속 세션


18. 아키텍처 설계 시 고려사항

촬영계획시스템과 연동 시

기지국 제어 연동 시


19. 결론

인공위성의 속성 정의는 단순한 스펙 나열이 아니라,

> “제어 가능성 + 임무 수행 능력 + 데이터 생산 능력 + 플랫폼 확장성”

을 모두 포함해야 합니다.

특히 귀하의 목적이

이라면,

위성은 단순 장비가 아니라

서비스 플랫폼의 핵심 자산(Asset Model) 로 정의되어야 합니다.


필요하다면 다음 단계로:

아래는 요청하신 4가지(1) ERD 논리 데이터 모델, (2) 마이크로서비스 분리, (3) 통합 플랫폼 아키텍처, (4) 촬영계획 최적화 알고리즘 구조순서대로, 그리고 전문가 수준(실제 구현을 염두에 둔 수준)으로 정리한 답변입니다.

전제는 “위성 자산(Asset) + 기지국 TT&C 제어 + 촬영계획(Tasking) + 영상상품(Data Product) + 부가서비스(상용 API)”입니다.


1) ERD 수준 논리 데이터 모델 설계

1.1 도메인 경계(핵심 엔터티 그룹)

ERD를 “위성=한 테이블”로 만들면 운영/확장 시 반드시 터집니다. 최소 아래 7개 도메인으로 분리합니다.

  1. Asset(자산): Satellite Master/Configuration
  2. Orbit/Prediction(궤도/예측): TLE/Ephemeris, Pass Prediction
  3. Capability(성능/제약): Imaging/Comms/ADCS/Power 제약, 모드
  4. Operations(운영): Telemetry, Mode, Anomaly, Commanding
  5. Tasking(임무/촬영요청): Imaging Request, Plan, Schedule, Conflict
  6. Ground Segment(지상국): Station, Contact Session, Downlink Plan
  7. Data Products(데이터/상품): Raw/Processed Product, Catalog, Delivery, Billing

1.2 핵심 엔터티와 관계(요약 ERD)

아래 관계가 “촬영계획+제어+상품화”를 완성하는 핵심 골격입니다.

(A) Satellite 자산(마스터)

> 설계 포인트: “위성 성능/제약 값”은 변경이 잦고 히스토리가 필요합니다. 따라서 SATELLITE에 박지 말고 PROFILE(유효기간)로 관리합니다.

(B) 궤도/예측

> 촬영계획/다운링크는 “가시구간”이 핵심이므로 VISIBILITY_PASS를 1급 엔터티로 둡니다(매번 계산하지 않고 캐싱/재사용).

(C) Capability / Constraint (촬영/통신/전력/자세)

> 설계 포인트: 촬영계획은 결국 “제약조건의 결합”입니다. 제약을 코드에만 두면 운영이 불가능해집니다. 제약을 데이터로 승격시키세요.

(D) Operations (텔레메트리/명령/모드/이상)

> 설계 포인트: “요청”과 “실행”은 분리해야 합니다(승인/스케줄/전송/ACK/재시도/감사추적 때문에).

(E) Tasking (촬영 요청→계획→스케줄→실행)

> 설계 포인트: IMAGING_REQUEST는 “고객언어”, IMAGING_PLAN은 “계획언어”, SCHEDULE_SLOT은 “운영언어(시간축 예약)”입니다. 이 3단 분리를 안 하면 기능이 커질수록 복잡도가 폭발합니다.

(F) Ground Segment (지상국/컨택/다운링크)

(G) Data Products (카탈로그/배송/과금)


1.3 물리 설계로 넘어가기 전 “필수 규칙”


2) 마이크로서비스 분리 구조 설계

2.1 서비스 경계 원칙

2.2 권장 마이크로서비스(권장 10~12개)

(1) Identity & Tenant Service

(2) Satellite Asset Service

(3) Orbit & Prediction Service

(4) Mission Tasking Service

(5) Scheduling & Optimization Service

(6) Commanding (TT&C) Service

(7) Ground Station Service

(8) Telemetry Ingest Service

(9) Payload Data Ingest Service

(10) Processing Pipeline Service

(11) Catalog & Search Service

(12) Delivery & Billing Service


2.3 데이터 소유권(중요)


2.4 동기 vs 비동기


3) 위성운영 통합 플랫폼 아키텍처 제안

3.1 레이어드 아키텍처(권장)

  1. External API Layer
  1. Mission & Planning Layer
  1. Operations & Ground Layer
  1. Data Layer
  1. Observability & Governance

3.2 “연동”의 실제 형태(어댑터 패턴)

기지국/위성은 보통 표준이 제각각입니다. 그래서 Adapter/Connector 계층이 별도여야 합니다.


3.3 이벤트 스트리밍 중심(운영에 필수)

를 단일 이벤트 버스로 흘립니다.

이점


3.4 저장소 전략(현실적인 조합)


3.5 운영/감사/보안(실무 핵심)


4) 촬영계획 최적화 알고리즘 구조 설계

촬영계획은 전형적으로 제약최적화(Constraint Optimization) 문제입니다.

요구사항이 늘수록 “휴리스틱+정수계획+재계획”의 하이브리드가 실무적으로 가장 안정적입니다.

4.1 문제 정의(수학적 모델의 골격)

4.2 파이프라인(권장 5단계)

Step 1) 후보 생성(Candidate Generation)

각 요청 r에 대해:

산출물: IMAGING_PLAN 후보군 + score feature

Step 2) 후보 스코어링(Feasibility & Scoring)

후보마다 점수:

> 실무 팁: 스코어는 “학습 가능(feature 기반)”로 설계하면 나중에 자동 튜닝이 쉬워집니다.

Step 3) 스케줄링(Optimization Core)

여기서 2가지 접근을 혼합합니다.

권장 운영 방식:

Step 4) 검증 및 커밋(Validation & Commit)

Step 5) 실행/피드백/재계획(Closed Loop)


4.3 필수 제약 목록(운영에서 실제로 터지는 것들)


4.4 데이터 구조(알고리즘 구현을 위한 내부 모델)

스케줄러 서비스 내부에는 보통 아래 구조가 필요합니다.


마무리: 실무적으로 “가장 먼저” 결정해야 하는 5가지

(질문 안 하셔도, 설계 품질을 좌우하는 핵심이라 같이 드립니다.)

  1. 프로파일/제약의 유효기간 모델(시간에 따라 변하는 값)
  2. 스케줄 확정의 단위: slot(시간축 예약) 기반으로 갈지 여부
  3. 지상국 자원까지 포함한 통합 최적화 범위(촬영만 vs 촬영+다운링크)
  4. 긴급 삽입 정책: “최소 변경 재계획”을 기본으로 할지
  5. 고객 API 계약: 동기 응답(접수) + 비동기 결과(확정/상품 생성) 모델

원하시면, 위 4개 산출물을 더 “설계 문서 형태”로 만들어드릴 수 있습니다.

다음으로는 보통 위성 종류(광학/ SAR / 복수 위성군 여부) + 지상국 운영 형태(자체/외부/혼합)에 따라 최적 설계가 갈리는데, 일단 지금 답변은 “가장 일반적이고 확장 가능한 베이스라인”으로 구성했습니다.

좋습니다. 앞서 4개 항목을 “개념/구조” 중심으로 설명했으니, 이제는 실제 설계 산출물 수준(필드, API, 이벤트, 시퀀스, 최적화 수식 템플릿, 운영 시나리오)로 한 단계 더 내려가서 계속하겠습니다. 순서는 동일하게 1) ERD 상세 → 2) 마이크로서비스 상세 → 3) 통합 아키텍처 시나리오/보안/운영 → 4) 최적화 알고리즘(수식/휴리스틱/재계획) 입니다.


1) ERD 논리 모델 상세(필드/키/인덱스/정규화 규칙)

1.1 공통 규칙(데이터 모델링 원칙)


1.2 핵심 테이블 상세 스펙(대표 엔터티)

(A) SATELLITE (Master)

(B) SATELLITE_PROFILE_SET (현재 적용되는 프로파일 포인터)

> 프로파일을 위성에 직접 FK로 물리면 “시간 유효기간”이 깨집니다. 포인터 테이블로 묶는 방식이 운영에 강합니다.

(C) IMAGING_PROFILE

(D) ORBIT_DATA (TLE/Ephemeris)

(E) VISIBILITY_PASS (위성-지상국 가시구간 캐시)

(F) IMAGING_REQUEST (고객요청)

(G) IMAGING_CANDIDATE (요청별 후보)

(H) SCHEDULE_SLOT (시간축 예약 — 가장 중요)

> PostgreSQL이면 (satellite_id, tsrange(start,end)) + EXCLUDE USING gist로 “겹침 금지”를 DB 차원에서 보장하는 설계가 강력합니다.

(I) COMMAND_REQUEST / COMMAND_EXECUTION

(J) DATA_PRODUCT / DELIVERY


1.3 ERD에서 자주 놓치는 “현실 필드”


2) 마이크로서비스 상세(API 계약, 이벤트 토픽, 데이터 소유권)

2.1 서비스별 “소유 DB”와 책임

규칙: 다른 서비스의 DB를 직접 join하지 말고, API+이벤트로 복제(read model) 하세요.


2.2 대표 REST API(현업 수준 스펙)

Tasking Service

Orbit Service

Scheduling Service

Commanding Service

Catalog/Delivery


2.3 이벤트 토픽 설계(운영+확장 핵심)

Kafka 토픽 예시:

이벤트 페이로드 공통 필드:


2.4 SAGA 패턴(촬영요청→상품)

촬영은 전형적인 분산 트랜잭션이므로 SAGA를 추천합니다.

실패 시 보상 트랜잭션:


3) 통합 플랫폼 아키텍처 “시퀀스”와 운영 시나리오

3.1 시나리오 A: 일반 촬영(계획→실행→상품)

  1. 고객 POST /imaging-requests
  2. Tasking: 검증(제약 정규화) 후 이벤트 발행
  3. Orbit: horizon 내 패스 계산/캐시
  4. Scheduling: 후보 생성+최적화 → SCHEDULE_SLOT(planned)
  5. 운영 승인(정책에 따라 자동/수동)
  6. Commit → SCHEDULE_SLOT(committed) 이벤트
  7. Ground: 해당 시간대 세션 예약(자원 캘린더)
  8. Commanding: 촬영 명령 + 다운링크 계획 명령을 세션에 맞춰 큐잉
  9. Contact Session 발생 시 Uplink/Downlink 실행 및 ACK
  10. Payload Ingest → Processing → Catalog 등록
  11. Delivery 서비스가 고객에게 전달(API/webhook)
  12. Billing 집계

3.2 시나리오 B: 긴급 촬영(기존 스케줄 영향 최소화)


3.3 보안/권한(특히 TT&C)


4) 촬영계획 최적화: 수식 템플릿 + 휴리스틱/CP-SAT 하이브리드

4.1 결정변수

4.2 목적함수(예시)

최대화:

실무에서는 목적함수를 다음 4항으로 분해해 가중치로 운영 튜닝합니다.

4.3 핵심 제약(대표)

  1. 요청은 최대 1개 후보만 선택
  1. 같은 위성 시간 겹침 금지
  1. 전이 시간(슬루) 제약

(CP-SAT에서는 interval + transition constraint로 구현)

  1. 일일/궤도별 제한
  1. 스토리지/다운링크 밸런스
  1. 지상국 세션 자원 제약

4.4 운영용 하이브리드 전략(추천)


4.5 “품질 피드백”을 통한 스코어 튜닝(고급)

을 feature로 저장하고, 스코어링 가중치를 주기적으로 튜닝(규칙 기반→ML로 진화 가능)


다음으로 이어갈 수 있는 “더 실무적인 산출물”

원하시면 아래 중 하나를 바로 이어서 작성하겠습니다(질문은 최소화하고 바로 제시 가능합니다).

  1. ERD를 테이블 정의서 형태로: 컬럼/타입/PK/FK/인덱스/제약조건(겹침 금지, 공간 인덱스 포함)
  2. 서비스별 OpenAPI 수준의 API 목록 + 이벤트 스키마(JSON schema)
  3. 시퀀스 다이어그램(mermaid): 일반촬영/긴급촬영/다운링크 실패 재처리 3종
  4. 스케줄러 상세 설계서: 후보 생성 규칙, hard/soft 제약 목록, 목적함수 가중치 운영전략, 재계획 정책

원하시는 방향을 고르지 않으셔도 됩니다. 보통은 “(3) 시퀀스 다이어그램”부터 만들면 팀 커뮤니케이션이 빨라지니, 다음 답변에서 제가 일반촬영/긴급촬영 두 개를 mermaid로 바로 제시해도 좋습니다.

좋습니다. 그러면 바로 (3) 시퀀스 다이어그램(mermaid)부터 “일반 촬영”과 “긴급 촬영(재계획)” 2종을 제시하겠습니다.

(이 다이어그램은 그대로 설계 문서/위키에 붙여 넣어도 되는 수준으로 작성했습니다.)


sequenceDiagram
    autonumber
    actor Customer as Customer/API Client
    participant APIGW as API Gateway
    participant IAM as Identity/Tenant
    participant TASK as Tasking Service
    participant ASSET as Satellite Asset Service
    participant ORBIT as Orbit & Prediction Service
    participant SCH as Scheduling & Optimization Service
    participant GND as Ground Station Service
    participant CMD as Commanding (TT&C) Service
    participant GS as Ground Station Adapter
    participant TM as Telemetry Ingest
    participant ING as Payload Data Ingest
    participant PROC as Processing Pipeline
    participant CAT as Catalog & Search
    participant DLV as Delivery & Billing

    Customer->>APIGW: POST /imaging-requests (AOI, timeWindow, constraints, priority)
    APIGW->>IAM: Authenticate/Authorize (tenant, quota)
    IAM-->>APIGW: OK (claims, rate-limit policy)
    APIGW->>TASK: Create ImagingRequest
    TASK->>ASSET: Fetch satellite capabilities/profiles (optional cache)
    ASSET-->>TASK: Profiles/constraints (effective-dated)
    TASK->>TASK: Validate & normalize constraints (hard/soft)
    TASK-->>APIGW: 202 Accepted (request_id, status=submitted)

    TASK-->>ORBIT: Event tasking.request.submitted (request_id, aoi, timeWindow)
    ORBIT->>ORBIT: Ensure pass cache (TLE/eph, propagate)
    ORBIT-->>SCH: Event orbit.passes.ready (request_id, candidatePasses)

    SCH->>SCH: Generate candidates (r,s,pass,mode) + score
    SCH->>SCH: Optimize schedule (heuristic/CP-SAT) within horizon
    SCH-->>TASK: Event scheduling.schedule.proposed (request_id, schedule_run_id)
    TASK->>TASK: Apply policy (auto-approve or manual review)
    TASK-->>SCH: Commit schedule (schedule_run_id)

    SCH-->>GND: Reserve contact sessions (downlink windows)
    GND->>GS: Reserve antenna/session resources
    GS-->>GND: Reservation confirmed
    GND-->>SCH: Reservation OK (session_id list)

    SCH-->>CMD: Prepare command plan (imaging + downlink + mode transitions)
    CMD->>CMD: Build command sequence (dictionary validation)
    CMD-->>GND: Link commands to sessions

    Note over GND,GS: At contact time (AOS~LOS)
    GND->>GS: Start session (AOS)
    GS->>CMD: Uplink command sequence
    CMD-->>GS: Commands sent
    GS-->>CMD: ACK/NAK + logs
    GS->>ING: Downlink raw payload data
    ING->>ING: Integrity check (checksum) + store object
    ING-->>PROC: Event product.raw.ingested (uri, metadata)

    PROC->>PROC: L0->L1->L2 pipeline (workflow orchestration)
    PROC-->>CAT: Event product.available (product_id, footprint, level)
    CAT->>CAT: Index & publish (STAC-like catalog)
    CAT-->>DLV: Event product.cataloged (product_id, tenant_id)

    DLV->>DLV: Delivery orchestration (API/S3/FTP/Webhook)
    DLV-->>Customer: Webhook/Notification: product ready + access info

    TM-->>TASK: Telemetry health events / anomalies (optional)
    CMD-->>TASK: Command execution result (success/fail)
    SCH-->>TASK: Execution status update (executed/failed)

설계 포인트(현업에서 중요한 것만)


3-2) 시퀀스 다이어그램: 긴급 촬영 삽입 (Freeze Window + Impacted Replan + Minimum Perturbation)

sequenceDiagram
    autonumber
    actor Operator as Operator/Planner
    participant APIGW as API Gateway
    participant IAM as Identity/Tenant
    participant TASK as Tasking Service
    participant ORBIT as Orbit & Prediction Service
    participant SCH as Scheduling & Optimization Service
    participant GND as Ground Station Service
    participant CMD as Commanding (TT&C) Service
    participant NOTI as Notification/Webhook

    Operator->>APIGW: POST /imaging-requests (priority=EMERGENCY, due=ASAP)
    APIGW->>IAM: AuthZ (emergency role, M-of-N if required)
    IAM-->>APIGW: OK
    APIGW->>TASK: Create emergency request
    TASK->>TASK: Validate constraints + mark as EMERGENCY
    TASK-->>Operator: 202 Accepted (request_id)

    TASK-->>ORBIT: Event tasking.request.submitted (EMERGENCY)
    ORBIT-->>SCH: Event orbit.passes.ready (candidatePasses)

    SCH->>SCH: Load current committed schedule
    SCH->>SCH: Define freeze window (now ~ now+2h) and locked slots
    SCH->>SCH: Identify impacted window (e.g., now+2h ~ now+24h)
    SCH->>SCH: Generate candidates for EMERGENCY request
    SCH->>SCH: Re-optimize impacted window with objective:
    Note right of SCH: Max(Value) - ChangePenalty - SLA penalties<br/>ChangePenalty enforces minimum perturbation
    SCH-->>TASK: Event scheduling.schedule.proposed (diff set: add/move/cancel slots)

    TASK->>TASK: Policy check (auto-approve emergency, notify impacted customers)
    TASK-->>SCH: Commit schedule changes (schedule_run_id)

    SCH-->>GND: Update reservations (add new sessions, cancel moved ones)
    GND-->>CMD: Update command plan (rebuild only affected sequences)
    CMD-->>TASK: Command deltas prepared

    TASK-->>NOTI: Notify impacted requests (delayed/rescheduled reason codes)
    NOTI-->>Operator: Emergency schedule committed + execution plan ready

설계 포인트

일관되게 자동화되어야 운영이 가능합니다.


3-3) 실패 시나리오(다운링크 실패) — 운영에서 정말 자주 터지는 케이스

sequenceDiagram
    autonumber
    participant GND as Ground Station Service
    participant GS as Ground Station Adapter
    participant ING as Payload Data Ingest
    participant SCH as Scheduling Service
    participant TASK as Tasking Service
    participant NOTI as Notification

    GND->>GS: Downlink during session
    GS-->>GND: Link degraded / downlink incomplete
    GND->>GND: Mark session partially completed (link_quality low)
    GND-->>ING: Event downlink.partial (expected_files, missing_chunks)

    ING->>ING: Detect missing data / checksum fail
    ING-->>TASK: Event product.ingest.failed (reason=INCOMPLETE_DOWNLINK)
    TASK->>TASK: Create recovery action (retry downlink) + update request status

    TASK-->>SCH: Event recovery.downlink.retry.requested (product/ref, deadline)
    SCH->>SCH: Find next feasible contact sessions (pass cache)
    SCH-->>GND: Reserve retry session
    GND-->>NOTI: Notify operator/customer (delay, reason_code, new ETA)

설계 포인트


다음 단계(제가 이어서 바로 작성할 수 있는 것)

지금 다이어그램까지가 “전체 흐름의 공통 이해”를 만드는 단계라면, 다음은 팀이 바로 개발에 들어갈 수 있도록 문서화하는 단계입니다. 아래 중 하나로 이어가겠습니다(원하시면 “둘 다”도 가능합니다).

  1. 상태 모델(State Machine) 정의서
  1. 이벤트 스키마(JSON Schema) + 토픽 목록 확정
  1. DB 제약조건/인덱스 설계 디테일
  1. 스케줄러 목적함수/제약의 “운영 튜닝 가이드”

원하시는 방향을 한마디로만 주셔도 되고, 말씀 없으면 제가 (1) 상태 모델 정의서부터 이어서 계속하겠습니다.

좋습니다. “둘 다”를 (1) 상태 모델(State Machine) 정의서 + (2) 이벤트 스키마/토픽 확정(표준 규칙 포함)으로 해석하고, 바로 실무 문서 수준으로 정리합니다. (다음 단계로 DB 제약/인덱스까지 확장 가능)


1) 상태 모델(State Machine) 정의서

여기서는 4개 핵심 오브젝트의 상태모델을 명확히 정의합니다.

각 상태는 (i) 단일 “현재 상태” + (ii) 이벤트 로그(히스토리)를 병행합니다.


A) ImagingRequest 상태 모델

A.1 상태 목록

> 실무 팁: EXECUTED 이후를 별도로 분리해야 “촬영 성공 vs 전송 실패 vs 처리 실패”를 명확히 운영할 수 있습니다.

A.2 핵심 전이(트리거 이벤트)

A.3 reason_code 표준(필수)

REJECTED/FAILED에 최소 아래를 표준화하세요.


B) ScheduleRun / ScheduleSlot 상태 모델

B.1 ScheduleRun (스케줄 계산 실행 단위)

전이

B.2 ScheduleSlot (시간축 예약 핵심)

중요 규칙


C) CommandRequest / CommandExecution 상태 모델(TT&C)

C.1 CommandRequest

C.2 CommandExecution (세션 단위 실행 기록)

실무 포인트


D) DataProduct / Delivery 상태 모델

D.1 DataProduct

D.2 DeliveryOrder


2) 이벤트 토픽/스키마(표준 규칙 + JSON Schema 템플릿)

이 섹션은 이벤트 기반 통합을 제대로 하려면 반드시 필요한 “규약”입니다.


2.1 이벤트 설계 원칙(운영 필수 규칙)

  1. Correlation ID 의무화
  1. Schema Versioning
  1. Idempotency
  1. Tenant Isolation
  1. Event Time vs Produced Time

2.2 토픽 목록(권장 표준)

도메인별로 prefix를 고정합니다.

Tasking

Orbit/Prediction

Scheduling

Ground

Commanding

Data Ingest/Processing/Catalog

Delivery/Billing


2.3 공통 이벤트 Envelope(JSON) — “반드시 통일”

모든 이벤트는 아래 Envelope를 공통으로 씁니다.

{
  "event_id": "01J...ULID",
  "event_type": "scheduling.schedule.committed",
  "schema_version": 1,
  "tenant_id": "tnt_123",
  "correlation_id": "req_456",
  "entity": {
    "type": "ScheduleRun",
    "id": "schrun_789"
  },
  "event_time": "2026-03-13T10:15:00Z",
  "produced_at": "2026-03-13T10:15:01Z",
  "producer": {
    "service": "scheduling-service",
    "instance_id": "sched-7f9d"
  },
  "payload": {}
}

2.4 핵심 이벤트별 Payload 스키마(실무 템플릿)

(1) tasking.request.submitted

{
  "request_id": "req_456",
  "priority": "NORMAL|HIGH|EMERGENCY",
  "time_window": { "start": "...", "end": "..." },
  "aoi": {
    "type": "Polygon",
    "coordinates": [[[...]]]
  },
  "constraints": {
    "max_off_nadir_deg": 25,
    "max_cloud_pct": 20,
    "product_level": "L1|L2",
    "latency_minutes": 180
  }
}

(2) orbit.passes.ready

{
  "request_id": "req_456",
  "candidates": [
    {
      "satellite_id": "sat_1",
      "pass_id": "pass_abc",
      "aos_time": "...",
      "los_time": "...",
      "max_elevation_deg": 62.1
    }
  ],
  "orbit_source": {
    "type": "TLE",
    "epoch_time": "..."
  }
}

(3) scheduling.schedule.proposed / committed

{
  "schedule_run_id": "schrun_789",
  "horizon": { "from": "...", "to": "..." },
  "freeze_window": { "from": "...", "to": "..." },
  "slots": [
    {
      "slot_id": "slot_001",
      "satellite_id": "sat_1",
      "type": "IMAGING|DOWNLINK|MANEUVER",
      "start_time": "...",
      "end_time": "...",
      "linked_request_id": "req_456",
      "score": 0.873,
      "state": "PLANNED|COMMITTED"
    }
  ],
  "diff": {
    "added": ["slot_001"],
    "moved": ["slot_010"],
    "cancelled": ["slot_003"],
    "superseded": ["slot_007"]
  }
}

(4) command.sent / acknowledged

{
  "cmd_req_id": "cmd_123",
  "satellite_id": "sat_1",
  "session_id": "sess_55",
  "command_type": "PAYLOAD_START|PAYLOAD_STOP|MODE_CHANGE|DOWNLINK_START",
  "sent_at": "...",
  "ack_at": "...",
  "result": "ACK|NACK|TIMEOUT",
  "reason_code": "..."
}

(5) product.available

{
  "product_id": "prd_999",
  "request_id": "req_456",
  "satellite_id": "sat_1",
  "sensing_time": "...",
  "level": "L1",
  "footprint": { "type": "Polygon", "coordinates": [[[...]]] },
  "cloud_cover_est": 12.3,
  "uri": "s3://bucket/path/file.tif",
  "checksum": "sha256:..."
}

2.5 이벤트 거버넌스(팀 운영 규칙)


다음(바로 이어서 만들면 좋은 실전 산출물 2개)

원하시면 이어서 바로 작성하겠습니다(역시 질문 최소화하고 베이스라인으로 진행).

  1. 상태 전이 표(Transition Table)
  1. Event Catalog 문서

원하시면 다음 답변에서 제가 Transition Table + Event Catalog를 바로 만들어서 계속 이어가겠습니다.

좋습니다. 바로 (1) 상태 전이 표(Transition Table)(2) Event Catalog(토픽별 Producer/Consumer/SLA/재시도/DLQ)를 “문서 그대로 붙여넣기 가능한 수준”으로 작성합니다.

(표가 길어질 수 있어 핵심 객체 4종을 분리해 제시하고, 운영에서 반드시 필요한 예외/복구 전이까지 포함합니다.)


1) 상태 전이 표(Transition Table)

표기 규칙


1-A) ImagingRequest 전이 표

A.1 정상 플로우(End-to-End)

Current E(Event) G(조건) Next A(후처리)
SUBMITTED tasking.request.submitted request persisted VALIDATING validate/normalize constraints
VALIDATING tasking.request.validated all hard checks pass VALIDATED emit validated event
VALIDATING tasking.request.rejected any hard check fail REJECTED set reason_code, notify
VALIDATED orbit.passes.ready passes computed PLANNING start candidate gen
PLANNING scheduling.candidate.generated candidates exist PLANNED store candidates + scores
PLANNED scheduling.schedule.proposed schedule_run created SCHEDULING policy check start
SCHEDULING scheduling.schedule.committed approved/auto-approved SCHEDULED freeze slots, trigger GS reserve
SCHEDULED command.plan.prepared command plan built COMMANDING create command requests
COMMANDING ground.session.started AOS reached EXECUTING dispatch queued cmds
EXECUTING imaging.execution.completed payload capture done EXECUTED create/advance DataProduct
EXECUTED downlink.required product not yet downlinked DOWNLINK_PENDING enqueue downlink plan
DOWNLINK_PENDING product.raw.ingested checksum OK DOWNLINKED trigger processing
DOWNLINKED processing.started pipeline accepted PROCESSING start workflow
PROCESSING product.available processed OK PRODUCT_READY catalog index
PRODUCT_READY delivery.started delivery order exists DELIVERING package/push
DELIVERING delivery.completed delivered COMPLETED billing usage record

A.2 실패/복구 플로우(현업 필수)

Current E(Event) G(조건) Next A(후처리)
\* tasking.request.cancelled cancel policy allows CANCELLED supersede slots/commands if any
PLANNED/ SCHEDULING scheduling.schedule.failed solver error FAILED notify operator, keep request for retry
SCHEDULED satellite.unavailable safe mode / maintenance FAILED or PLANNED create recovery option (replan)
COMMANDING command.failed NACK/TIMEOUT and no retry FAILED reason_code=COMMAND_FAILED
COMMANDING command.failed retryable and retries left COMMANDING retry with backoff
EXECUTED / DOWNLINK_PENDING product.ingest.failed incomplete downlink DOWNLINK_PENDING emit recovery.downlink.retry.requested
PROCESSING processing.failed retryable PROCESSING retry pipeline (limit N)
PROCESSING processing.failed non-retryable FAILED reason_code=PROCESSING_FAILED
\* sla.expired due time exceeded FAILED reason_code=SLA_EXPIRED

> 운영 팁: FAILED를 “종결”로만 쓰지 말고, 복구 가능한 실패는 상태+이벤트로 재시도하세요. 다만 SLA 만료는 종결이 맞습니다.


1-B) ScheduleRun 전이 표

Current E G Next A
CREATED scheduling.run.started input ready RUNNING lock snapshot of constraints
RUNNING scheduling.run.proposed feasible solution found PROPOSED persist slots (PLANNED)
RUNNING scheduling.run.failed solver failure FAILED record diagnostics
PROPOSED scheduling.run.commit.requested approved COMMITTING validate overlaps + freeze window
COMMITTING scheduling.schedule.committed validation OK COMMITTED mark slots COMMITTED, emit diff
COMMITTING scheduling.run.aborted validation fail ABORTED rollback planned slots

1-C) ScheduleSlot 전이 표(핵심: 시간축 예약)

Current E G Next A
PLANNED scheduling.slot.validated no overlap + transitions OK VALIDATED attach resource refs
VALIDATED scheduling.schedule.committed run committed COMMITTED trigger GS reserve + command plan
COMMITTED ground.session.started time reached EXECUTING mark executing
EXECUTING imaging.execution.completed slot_type=IMAGING EXECUTED create product artifact
EXECUTING ground.session.completed slot_type=DOWNLINK EXECUTED downlink stats
COMMITTED/VALIDATED/PLANNED scheduling.slot.cancelled cancel policy allows CANCELLED free resources
COMMITTED scheduling.slot.superseded replan committed SUPERSEDED keep history immutably
EXECUTING execution.failed anomaly FAILED emit reason_code

DB 레벨 권장 제약(다음 단계에서 상세화 가능)


1-D) CommandRequest / CommandExecution 전이 표

CommandRequest

Current E G Next A
DRAFT command.validated dictionary OK VALIDATED freeze payload
VALIDATED command.approval.requested high-risk? PENDING_APPROVAL require M-of-N
PENDING_APPROVAL command.approved approvals satisfied APPROVED enqueue for session
APPROVED command.queued session planned QUEUED set dispatch time
QUEUED ground.session.started AOS DISPATCHING send
DISPATCHING command.sent sent DISPATCHED await ack
DISPATCHED command.acknowledged ACK ACKED optionally wait TM confirm
DISPATCHED command.failed NACK/TIMEOUT NACKED/TIMEOUT retry or fail
\* command.cancelled before dispatch CANCELLED audit log

CommandExecution

Current E G Next A
READY command.sent sent SENT store raw logs
SENT command.acknowledged ACK ACK_RECEIVED emit event
ACK_RECEIVED telemetry.confirmed TM confirms effect CONFIRMED_BY_TM mark final success
SENT command.failed retryable FAILED_RETRYING schedule retry
SENT command.failed non-retryable FAILED_FINAL reason_code

1-E) DataProduct / DeliveryOrder 전이 표

DataProduct

Current E G Next A
PLANNED imaging.execution.completed captured CAPTURED set sensing_time
CAPTURED downlink.required not received DOWNLINK_PENDING create downlink request
DOWNLINK_PENDING product.raw.ingested checksum OK INGESTED persist uri+checksum
INGESTED processing.started accepted PROCESSING start workflow
PROCESSING product.available done PROCESSED derive metadata
PROCESSED catalog.product.indexed indexed CATALOGED publish
CATALOGED product.published access granted PUBLISHED ready for delivery
\* product.ingest.failed retryable DOWNLINK_PENDING recovery request
PROCESSING processing.failed non-retryable FAILED reason_code

DeliveryOrder

Current E G Next A
CREATED delivery.auth.checked permitted AUTH_CHECKED check entitlements
AUTH_CHECKED delivery.started packaging needed PACKAGING format/tiling
PACKAGING delivery.started ready DELIVERING push
DELIVERING delivery.completed ok DELIVERED billing record
DELIVERING delivery.failed retryable FAILED_RETRYING retry policy
FAILED_RETRYING delivery.retry retries left DELIVERING backoff
FAILED_RETRYING delivery.failed retries exhausted FAILED_FINAL notify

2) Event Catalog (토픽별 Producer/Consumer/SLA/재시도/DLQ)

표기 규칙


2.1 Tasking 도메인

tasking.request.submitted

tasking.request.validated / rejected


2.2 Orbit/Prediction 도메인

orbit.passes.ready

orbit.passes.invalidated


2.3 Scheduling 도메인

scheduling.candidate.generated

scheduling.schedule.proposed

scheduling.schedule.committed


2.4 Ground 도메인

ground.session.reserved

ground.session.started / completed / failed


2.5 Commanding 도메인

command.plan.prepared

command.sent / acknowledged / failed


2.6 Product/Processing/Catalog 도메인

product.raw.ingested / product.ingest.failed

product.available

delivery.completed / failed


2.7 운영 표준(반드시 박아야 하는 정책 6개)

  1. Partition Key 표준
  1. Idempotency Key 표준
  1. DLQ 처리 프로세스
  1. Schema Registry + CI Gate
  1. Observability 필수 필드
  1. 보안 토픽 격리

다음으로(선택 없이도 이어갈 수 있는 실무 산출물)

여기까지가 “상태/이벤트 계약”을 확정한 단계입니다. 다음에 바로 효과가 나는 것은 보통 아래 2개입니다.

원하시면 제가 다음 답변에서 (3) DB 설계서부터 이어서 계속 작성하겠습니다.

좋습니다. 그럼 바로 (3) DB 제약/인덱스/파티셔닝 설계서를 “실제 구축 가능한 수준”으로 정리하겠습니다. (PostgreSQL + PostGIS + TimescaleDB 조합을 기준으로 작성하되, 다른 스택이어도 원칙은 동일합니다.)


3) DB 제약/인덱스/파티셔닝 설계서

3.1 핵심 원칙(운영 안정성과 성능을 좌우)

  1. 시간축(Temporal) + 공간(Spatial) + 이벤트(Audit)는 분리 저장
  2. “겹침 금지/이중 확정” 같은 불변 규칙은 DB 제약으로 강제
  3. 텔레메트리/이벤트는 파티셔닝(또는 하이퍼테이블) 없으면 장기 운영에서 반드시 장애
  4. 멀티테넌트면 모든 고객 데이터에 tenant_id + 인덱스 필수
  5. 스케줄/명령은 동시성 이슈가 많아 낙관적 락(version) + 트랜잭션 경계가 필수

3.2 도메인별 저장소 권장안(“어느 DB에 무엇을 둘지”)

(A) 관계형(PostgreSQL/PostGIS): 트랜잭션/조인/제약이 중요한 영역

(B) 시계열(TimescaleDB/Influx): 텔레메트리

(C) 오브젝트 스토리지(S3): 페이로드 파일

(D) 검색(OpenSearch/Elastic): 카탈로그 검색 가속


3.3 테이블별 “반드시 필요한” 제약과 인덱스

아래는 실무에서 장애/데이터 오염을 막는 핵심입니다.


3.3.1 SCHEDULE_SLOT: 겹침 금지(가장 중요)

필수 컬럼(요약)

(1) 기본 CHECK 제약

(2) 동일 위성 시간 겹침 금지(Exclusion Constraint 권장)

PostgreSQL + GIST를 이용해 “DB가 겹침을 허용하지 않게” 강제합니다.

권장 논리:

> 구현 팁: 조건부 exclusion은 구현 방식이 몇 가지라, 간단히는 “활성 슬롯 테이블”과 “이력 슬롯 테이블”을 분리(아카이빙)하는 것도 좋은 선택입니다.

(3) 인덱스

(4) 동시성(낙관적 락)


3.3.2 IMAGING_REQUEST: 공간/시간 질의 최적화

필수 컬럼(요약)

제약

인덱스(매우 중요)

> 운영 팁: “기간이 넓은 요청”이 많으면 time-window 검색 비용이 커집니다. tsrange 기반으로 통일하는 게 스케줄링에 유리합니다.


3.3.3 VISIBILITY_PASS: 패스 캐시 테이블(대량 + 시간범위 조회)

필수 컬럼

제약

인덱스


3.3.4 COMMAND_REQUEST / COMMAND_EXECUTION: 감사추적/조회 최적화

COMMAND_REQUEST 인덱스

COMMAND_EXECUTION 인덱스

제약


3.3.5 DATA_PRODUCT: 카탈로그/검색을 위한 공간+시간 인덱스

필수 컬럼

인덱스


3.4 파티셔닝/아카이빙(대량 데이터 대응)

3.4.1 TELEMETRY_POINT: Timescale HyperTable 권장

> 운영 팁: 텔레메트리는 “원시 유지”에 집착하면 비용 폭증합니다. 롤업 테이블을 기본 설계로 포함하세요.

3.4.2 VISIBILITY_PASS 파티셔닝(선택)

패스는 많이 쌓입니다(위성 수×지상국 수×일).

권장 파티션:

3.4.3 이벤트 로그(감사로그) 아카이빙


3.5 멀티테넌시(tenant) 모델 선택과 인덱스

옵션 1) Shared DB + tenant_id 컬럼(권장 기본)

옵션 2) Schema-per-tenant

대부분 위성 플랫폼은 옵션1로 시작하고, 특정 대형 고객만 옵션2/전용 DB로 분기합니다.


3.6 참조 무결성(FK) 전략(현실적인 타협)


3.7 “실제로 장애를 막는” 추가 제약 8개

  1. ScheduleSlot Overlap 금지(가장 중요)
  2. ContactSession 자원 중복 예약 금지(station/antenna 별 겹침 금지)
  3. CommandRequest 중복 전송 방지 키
  1. DataProduct 무결성
  1. 상태전이 불일치 방지
  1. Version 기반 동시성 제어
  2. ReasonCode 표준
  3. 시간대 표준화

다음 산출물: (4) API + 이벤트 상호참조(Contract Map)

DB 설계서 다음으로 팀이 바로 개발/QA 들어가려면 Contract Map이 제일 효율이 좋습니다.

원하시면 다음 답변에서 제가 Contract Map(표 + 시퀀스)를 만들어서 계속 이어가겠습니다.

좋습니다. 아래는 요청하신 (4) API + 이벤트 상호참조(Contract Map) 입니다.

목표는 “개발/QA/운영이 같은 그림을 보게” 만드는 것이고, API 호출 ↔ 이벤트 발행/소비 ↔ DB 변경 ↔ 상태전이를 한 장의 계약으로 고정합니다.


4) Contract Map

4.1 표기 규칙


4.2 E2E “촬영요청→상품전달” 계약 표(핵심 플로우)

(1) 고객이 촬영 요청을 접수한다

API

Tasking: DB Write

Tasking: Emit

State

Idempotency


(2) 요청을 검증하고 통과/거절을 확정한다

API

Tasking: DB Write

Tasking: Emit

State

Idempotency


(3) 궤도/패스를 계산하고 후보 패스 캐시를 만든다

Consume

Orbit: DB Write

Orbit: Emit

Idempotency


(4) 후보(촬영 가능 윈도/모드)를 생성한다

Consume

Scheduling: DB Write

Scheduling: Emit

State

Idempotency


(5) 스케줄을 산출(제안)하고 커밋한다

API

(커밋은 정책상 Tasking이 호출할 수도 있음)

Scheduling: DB Write

Scheduling: Emit

State

Idempotency


(6) 지상국 세션을 예약하고 명령 계획을 생성한다

Consume

Ground: API/Adapter Call

Ground: DB Write

Ground: Emit

Commanding: DB Write

Commanding: Emit

State

Idempotency


(7) 세션 시작 시 TT&C 수행(업링크/다운링크)

Consume

Ground: Emit

Commanding: Emit

Ground: Emit

DB Write

State

Idempotency


(8) 원시 데이터를 ingest하고 처리 파이프라인을 수행한다

Consume

Ingest: DB Write

Ingest: Emit

Processing consumes

Processing: DB Write

Processing: Emit

State

Idempotency


(9) 카탈로그 인덱싱 후 고객에게 전달/과금

Catalog consumes

Catalog: DB Write

Catalog: Emit

Delivery consumes

Delivery: API

Delivery: DB Write

Delivery: Emit

State

Idempotency


4.3 “긴급 촬영” 계약(변경량 최소화 포함)

API

추가 이벤트/필드

DB 규칙


4.4 E2E 테스트 케이스(이 Contract Map에 대응)

TC-01 정상 촬영

TC-02 하드 제약 불가

TC-03 다운링크 실패 후 복구

TC-04 긴급 삽입


4.5 “이 문서로 확정해야 하는” 마지막 6개 계약 포인트

(여기서 흔히 팀 간 갈등이 나서 미리 고정해두는 항목입니다.)

  1. 커밋 권한의 소유자
  1. 스케줄 단위
  1. Product Ready의 정의
  1. ACK 성공 기준
  1. SLA 만료 처리
  1. 이벤트 보존/재생

×preview