☰ 분류

요구사항에서 테이블 구조 뽑는 프롬프트

기능 설명을 받아 엔티티와 관계를 세웁니다. 애매한 부분을 묻고 넘어가지 않습니다.

분류개발 › 데이터·DB
태그초안작성분석개발자
프롬프트 (영어 본문 · 답은 한국어로 옵니다)
Derive a data model from these requirements.

Step 1 — **Ambiguities first. Do not model yet.**
List every place the requirements do not settle a cardinality, an optionality, or a lifetime. Phrase each as a question with a recommended default. Typical ones: can this have more than one, can it be empty, what happens when the parent is deleted, is this value historical or current, can it change after creation.

Step 2 — Entities. One line each on what a row represents. *If you cannot say what one row is, it is not an entity yet.*

Step 3 — Relationships with cardinality, and which side holds the key.

Step 4 — Attributes, with the ones that are derived rather than stored marked as such.

Step 5 — What the model makes hard. Every model makes some question expensive; name the queries that will be awkward here.

Step 6 — Two or three decisions you made that a reasonable person would make differently, and what the alternative costs.

Rules:
- *Do not invent requirements to resolve an ambiguity.* Put it in step 1.
- Model what the requirements say, not what similar products usually do.
- No DDL yet. Structure first; syntax is a separate step.
붙여 넣으면 맨 아래에 채울 칸(요구사항 · 제약 조건)이 나옵니다

어떤 프롬프트인가

요구사항에는 항상 "한 명이 여러 개를 가질 수 있나"가 안 적혀 있다. 이 프롬프트는 그 모호함을 먼저 목록으로 뽑아 묻고, 그다음에 구조를 세운다.

모델 비교

ChatGPT가 모호성 식별과 구체성에서 가장 우수하지만 다소 과도하고 일부 관계가 모순된다. Gemini는 더 응집력 있으나 미확정 사항을 단정했고, [C]는 답이 제시되지 않았다.

ChatGPT종합 1위
39/ 50

+ 모호성을 폭넓게 짚고 이력·스냅샷까지 구체화했다.

- 중복 이력 모델과 회차·주문의 FK 방향이 일관되지 않다.

Gemini
37/ 50

+ 주문·결제와 실제 출고를 명확히 분리했다.

- 매출 기준을 paid_at으로 정하고 번들 구조도 단정했다.

기준ChatGPTGemini앞선 모델
지시 준수97ChatGPT +29%
정확성76ChatGPT +17%
구체성98ChatGPT +13%
구성·가독성89Gemini +13%
분량 적정성67Gemini +17%

gpt-5.6-sol가 모델 이름을 가린 채 1~10점으로 채점했습니다 (2026-09-25). 측정값이 아니라 AI 심사 결과입니다.

답 전문 보기

같은 입력을 세 모델에 넣어 받은 답을 그대로 옮겼습니다. 각 CLI(에이전트 하네스)에서 실행했습니다. ChatGPT·Claude 앱이나 웹에서는 답이 다를 수 있습니다.

넣은 입력
요구사항: - 고객은 여러 개의 정기구독을 가질 수 있다 (예: 스킨케어 3종 세트, 클렌징 세트).
- 각 구독은 배송 주기(2주/4주)를 가지며, 고객이 언제든 일시정지·해지할 수 있다.
- 구독 1건당 매 배송 회차마다 실제 발송된 상품 목록과 운송장 번호가 남아야 한다.
- 고객은 구독과 별도로 단건 주문도 할 수 있다.
- 프로모션 쿠폰은 특정 구독 상품에만 적용되는 경우와 전체 주문에 적용되는 경우가 있다.
- 관리자는 회차별로 발송 상품 구성을 바꿀 수 있어야 한다 (예: 이번 달은 A상품 대신 B상품 발송).

제약 조건: PostgreSQL 사용. 기존 users, products 테이블 구조는 그대로 유지. 정산팀이 구독 매출을 월별로 집계하는 리포트를 쓰고 있어 매출 인식 시점은 바꿀 수 없음.
gpt-5.6-luna (codex CLI · 에이전트 하네스) · 실행일 2026-09-24

1단계 — 먼저 확정해야 할 모호성

추천 기본값은 이후 모델에서 사용할 가정이다.

  1. 한 고객은 구독을 최대 몇 건까지 가질 수 있는가?
    → 여러 건 허용. 같은 상품을 포함한 구독도 허용할지 별도 결정.

  2. 하나의 구독에는 상품이 몇 개까지 포함될 수 있는가?
    → 1개 이상 여러 개 허용.

  3. 구독 생성 시 상품 구성은 반드시 있어야 하는가?
    → 최소 1개 필요.

  4. 구독 상품의 수량은 상품별로 가질 수 있는가?
    → 상품별 수량을 허용.

  5. 구독 주기는 생성 후 변경할 수 있는가?
    → 변경 가능하되 변경 이력을 보존할지 결정 필요. 추천: 변경 이력 보존.

  6. 일시정지 기간은 정해져 있는가, 무기한인가?
    → 무기한 일시정지 허용. 재개 시점은 별도 기록.

  7. 일시정지·해지는 즉시 적용되는가, 다음 배송 회차부터 적용되는가?
    → 다음 미발송 회차부터 적용.

  8. 해지한 구독을 다시 재개할 수 있는가?
    → 재개 불가, 새 구독을 생성. 재개 허용이 필요하면 상태 이력이 필요하다.

  9. 구독 해지 후 기존 배송 회차와 매출 기록은 유지되는가?
    → 유지.

  10. 구독의 한 배송 회차는 실제로 반드시 발송되는가?
    → 취소·스킵·실패 상태도 허용하고, 발송된 회차만 실제 상품 목록을 필수로 둔다.

  11. 하나의 배송 회차가 여러 택배로 나뉠 수 있는가?
    → 추천: 회차당 운송장 1개. 여러 운송장이 필요하면 별도 배송 패키지 엔티티가 필요하다.

  12. 배송 회차의 상품 구성은 발송 전 언제까지 변경할 수 있는가?
    → 발송 확정 전까지 변경 가능, 발송 확정 후 불변.

  13. 관리자가 상품 구성을 변경하면 원래 예정된 구성도 보존해야 하는가?
    → 예정 구성과 실제 발송 구성을 모두 보존. 추천: 변경 이력도 보존.

  14. 상품명·가격이 변경되거나 상품이 삭제되어도 과거 회차의 정보는 그대로 보여야 하는가?
    → 그렇다. 과거 발송 상품에는 상품 참조와 함께 당시 이름·가격을 저장.

  15. 상품 가격은 구독 생성 시 고정되는가, 발송 회차 당시 가격을 사용하는가?
    → 요구사항만으로 결정할 수 없다. 추천: 회차 확정 시 가격을 고정.

  16. 단건 주문도 배송 이력과 운송장 번호를 가져야 하는가?
    → 요구사항에는 구독 배송만 명시되어 있다. 추천: 단건 주문도 같은 배송 구조를 재사용하되, 필수 여부는 별도 결정.

  17. 쿠폰은 한 주문에 여러 개 적용할 수 있는가?
    → 추천: 한 주문당 최대 1개.

  18. 특정 구독 상품용 쿠폰은 구독 전체 기간 동안 재사용 가능한가, 한 회차만 가능한가?
    → 추천: 쿠폰 정책으로 명시하고, 적용된 각 회차에 적용 이력을 남긴다.

  19. 쿠폰이 적용되는 대상은 구독의 예정 상품인가, 실제 발송 상품인가?
    → 추천: 실제 발송·청구된 상품 기준.

  20. 쿠폰 할인 금액이나 적용 규칙이 나중에 변경되면 과거 주문에도 영향을 주는가?
    → 영향을 주지 않음. 적용 당시 할인 규칙과 금액을 주문에 복사.

  21. 쿠폰이 전체 주문에 적용될 때 배송비·세금도 할인 대상인가?
    → 요구사항에 없다. 상품 금액에만 적용하는 것을 기본값으로 제안.

  22. 쿠폰은 만료·사용 횟수·고객별 사용 제한을 갖는가?
    → 미정. 필요한 경우 쿠폰 정책 속성으로 추가.

  23. 매출 인식 시점은 정확히 어떤 이벤트인가?
    → 기존 정산 시스템의 현재 기준을 확인해야 한다. 추천: 회차별 매출 인식 이벤트와 인식 시각을 별도 불변 기록.

  24. 결제 실패·환불·부분 환불이 발생할 수 있는가?
    → 요구사항에 없다. 정산 리포트가 이를 다루면 주문·매출 조정 모델을 추가해야 한다.


2단계 — 엔티티

  • Subscription: 고객과 구독 계약 한 건을 나타낸다.
  • SubscriptionItem: 구독에 포함된 상품과 수량 한 건을 나타낸다.
  • SubscriptionCycle: 구독의 특정 배송 회차 한 건을 나타낸다.
  • SubscriptionCycleItem: 특정 회차에 실제로 발송된 상품과 수량 한 건을 나타낸다.
  • Order: 단건 주문 또는 구독 회차에 대응하는 금전 거래 한 건을 나타낸다.
  • OrderItem: 주문에서 청구된 상품과 수량 한 건을 나타낸다.
  • Coupon: 프로모션 쿠폰 정의 한 건을 나타낸다.
  • CouponApplication: 특정 주문에 쿠폰이 적용된 사실 한 건을 나타낸다.
  • CouponApplicationItem: 쿠폰이 특정 상품에 적용된 경우의 대상 상품 한 건을 나타낸다.
  • SubscriptionStatusHistory: 구독의 상태 변경 한 건을 나타낸다.
  • SubscriptionItemHistory: 구독 상품 구성 변경 한 건을 나타낸다.
  • RevenueRecognition: 기존 정산 기준에 따라 매출이 인식된 사실 한 건을 나타낸다.

기존 users, products 테이블은 그대로 참조한다.


3단계 — 관계와 카디널리티

  • users 1 : N Subscription
    외래 키는 Subscription이 가진다.

  • Subscription 1 : N SubscriptionItem
    외래 키는 SubscriptionItem이 가진다.

  • products 1 : N SubscriptionItem
    외래 키는 SubscriptionItem이 가진다.

  • Subscription 1 : N SubscriptionCycle
    외래 키는 SubscriptionCycle이 가진다.

  • SubscriptionCycle 1 : N SubscriptionCycleItem
    외래 키는 SubscriptionCycleItem이 가진다.

  • products 1 : N SubscriptionCycleItem
    외래 키는 SubscriptionCycleItem이 가진다.

  • SubscriptionCycle 1 : 1 Order
    구독 회차 주문이 존재한다면 Order가 회차를 참조한다. 추천 구조는 구독 회차마다 주문을 하나 만든다.

  • 단건 주문은 Order만 가지며 SubscriptionCycle은 없다.
    따라서 Order의 주문 유형으로 단건 주문과 구독 회차 주문을 구분한다.

  • Order 1 : N OrderItem
    외래 키는 OrderItem이 가진다.

  • products 1 : N OrderItem
    외래 키는 OrderItem이 가진다.

  • Coupon 1 : N CouponApplication
    외래 키는 CouponApplication이 가진다.

  • Order 1 : 0..1 CouponApplication
    추천 기본값은 주문당 쿠폰 하나다.

  • CouponApplication 1 : 0..N CouponApplicationItem
    전체 주문 쿠폰이면 대상 상품이 없고, 특정 상품 쿠폰이면 대상 상품 목록이 존재한다.

  • OrderItem 1 : 0..N CouponApplicationItem
    특정 주문 상품에 대한 쿠폰 적용 대상을 나타낸다.

  • Subscription 1 : N SubscriptionStatusHistory
    외래 키는 이력 테이블이 가진다.

  • Subscription 1 : N SubscriptionItemHistory
    외래 키는 이력 테이블이 가진다.

  • Order 또는 SubscriptionCycle 1 : N RevenueRecognition
    실제 정산 기준이 주문 단위인지 회차 단위인지 확인한 뒤 하나를 기준으로 고정한다.


4단계 — 주요 속성

Subscription

  • 고객 ID
  • 구독 상태: active, paused, cancelled 등
  • 배송 주기: 2주 또는 4주
  • 시작일
  • 일시정지 시작일·종료일
  • 해지일
  • 다음 예정 회차일
  • 생성일·수정일
  • 현재 구성 요약 — 파생 가능

현재 상태는 이력에서 계산할 수도 있지만, 조회 성능을 위해 저장할 수 있다.

SubscriptionItem

  • 구독 ID
  • 상품 ID
  • 수량
  • 적용 시작일
  • 적용 종료일
  • 구독 당시 상품명 스냅샷
  • 구독 당시 가격 스냅샷

SubscriptionCycle

  • 구독 ID
  • 회차 번호
  • 예정 발송일
  • 실제 발송일
  • 상태: 예정, 보류, 취소, 발송 완료 등
  • 운송장 번호
  • 실제 발송 여부
  • 해당 회차의 주문 ID
  • 회차 확정 시각

운송장 번호는 발송 전에는 비어 있을 수 있다.

SubscriptionCycleItem

  • 회차 ID
  • 상품 ID
  • 실제 발송 수량
  • 실제 발송 당시 상품명 스냅샷
  • 실제 발송 당시 단가 스냅샷
  • 관리자 변경 사유 또는 변경 메모
  • 예정 상품인지 여부 — 파생 가능하거나 이력 비교로 계산

이 테이블이 관리자 변경 후의 실제 발송 구성을 보존한다.

Order

  • 주문 유형: 단건 주문 또는 구독 회차 주문
  • 고객 ID
  • 구독 회차 ID — 구독 회차 주문일 때만 존재
  • 주문 상태
  • 주문 생성일
  • 결제 완료일
  • 주문 금액 합계 — 항목 합계로 파생 가능하지만 정산 안정성을 위해 저장 가능
  • 할인 금액
  • 최종 결제 금액
  • 환불·취소 상태

OrderItem

  • 주문 ID
  • 상품 ID
  • 수량
  • 청구 당시 상품명 스냅샷
  • 청구 당시 단가 스냅샷
  • 할인 금액
  • 최종 금액

Coupon

  • 쿠폰 코드 또는 식별자
  • 적용 방식: 특정 구독 상품 또는 전체 주문
  • 할인 방식과 할인값
  • 유효 시작일·종료일
  • 사용 제한 속성 — 정책 확정 시 추가

CouponApplication

  • 쿠폰 ID
  • 주문 ID
  • 적용 당시 할인 금액
  • 적용 당시 할인 규칙 스냅샷
  • 적용 시각

CouponApplicationItem

  • 쿠폰 적용 ID
  • 주문 상품 ID
  • 적용 할인 금액

SubscriptionStatusHistory

  • 구독 ID
  • 이전 상태
  • 변경된 상태
  • 변경 사유
  • 유효 시작 시각
  • 유효 종료 시각
  • 변경 주체

SubscriptionItemHistory

  • 구독 ID
  • 변경 전 구성
  • 변경 후 구성
  • 적용 회차 또는 적용 시각
  • 변경 관리자
  • 변경 사유

RevenueRecognition

  • 주문 또는 회차 ID
  • 매출 인식 기준 이벤트
  • 매출 인식 시각
  • 인식 금액
  • 정산 기간
  • 기존 리포트와 연결할 식별자

매출 인식 시각은 기존 정산팀의 기준을 그대로 사용하며, 새 모델이 그 시점을 변경하지 않도록 한다.


5단계 — 이 모델이 어렵게 만드는 질문

  • 특정 시점의 모든 구독 상품 구성을 재현하는 질문
    → 현재 구성과 변경 이력을 함께 조회해야 한다.

  • “관리자가 왜 이 회차의 상품을 바꿨는가?”를 정확히 추적하는 질문
    → 변경 이력과 회차 스냅샷을 함께 봐야 한다.

  • 구독 예정 구성과 실제 발송 구성이 다른 회차만 찾는 질문
    → SubscriptionItem과 SubscriptionCycleItem을 시점별로 비교해야 한다.

  • 쿠폰 하나가 구독 전체 기간에 걸쳐 얼마를 할인했는지 계산하는 질문
    → 각 회차 주문의 쿠폰 적용 이력을 합산해야 한다.

  • 상품의 현재 가격과 과거 청구 가격을 비교하는 질문
    → 상품 테이블과 여러 스냅샷 컬럼을 조합해야 한다.

  • 하나의 구독에서 발생한 매출과 단건 주문 매출을 같은 기준으로 비교하는 질문
    → 주문 유형과 회차, 매출 인식 기록을 조인해야 한다.


6단계 — 다르게 결정할 수 있는 선택

  1. 구독 회차마다 Order를 만들지 여부

    • 제안: 회차마다 주문을 하나 만든다.
    • 대안: SubscriptionCycle 자체를 금전 거래로 취급한다.
    • 대안의 비용: 단건 주문과 구독 매출을 통합 집계하기 어렵고, 쿠폰·결제·환불 모델이 별도로 갈라진다.
  2. 배송 회차의 상품 목록을 주문 항목과 별도로 저장할지 여부

    • 제안: OrderItem과 SubscriptionCycleItem을 분리한다.
    • 대안: 주문 항목을 실제 발송 목록으로 재사용한다.
    • 대안의 비용: 발송 전 청구 구성과 실제 발송 구성이 달라지는 경우를 표현하기 어렵다.
  3. 구독 상품 변경 이력을 별도 테이블로 저장할지 여부

    • 제안: 변경 이력을 저장한다.
    • 대안: 현재 SubscriptionItem만 수정한다.
    • 대안의 비용: 과거 회차의 예정 구성, 변경 시점, 관리자 변경 내용을 재현할 수 없다.

같은 분류의 프롬프트

대용량 텍스트 변환기 프롬프트
AI 데이터 추출 도구 기획 프롬프트
AI2sql 자연어 SQL 생성 프롬프트
백엔드 아키텍트 역할을 맡기는 프롬프트
Base R 프로그래밍 프롬프트