메인 μ½˜ν…μΈ λ‘œ κ±΄λ„ˆλ›°κΈ°
Sonamu UI의 Entity 관리 κΈ°λŠ₯을 μ‚¬μš©ν•˜λ©΄ μ‹œκ°μ  μΈν„°νŽ˜μ΄μŠ€λ‘œ Entityλ₯Ό μ‰½κ²Œ μƒμ„±ν•˜κ³  νŽΈμ§‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. CLI둜 νŒŒμΌμ„ 직접 μˆ˜μ •ν•˜λŠ” 것보닀 훨씬 λΉ λ₯΄κ³  μ§κ΄€μ μž…λ‹ˆλ‹€.

Entity νƒ­ ꡬ쑰

Entity 관리 ν™”λ©΄
Entity 탭은 두 κ°€μ§€ μ£Όμš” μ˜μ—­μœΌλ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€:
  • μ™Όμͺ½ Sidebar: Entity λͺ©λ‘κ³Ό μƒˆ Entity μΆ”κ°€ λ²„νŠΌ
  • 였λ₯Έμͺ½ Content: μ„ νƒν•œ Entity의 상세 정보 (Properties, Indexes, Relations, Subsets, Enums)

Entity μƒμ„±ν•˜κΈ°

1. New Entity λ²„νŠΌ 클릭

μ‚¬μ΄λ“œλ°” ν•˜λ‹¨μ˜ [+ New Entity] λ²„νŠΌμ„ ν΄λ¦­ν•©λ‹ˆλ‹€.

2. Entity 정보 μž…λ ₯

λͺ¨λ‹¬μ΄ 열리면 λ‹€μŒ 정보λ₯Ό μž…λ ₯ν•©λ‹ˆλ‹€:
ν•„λ“œμ„€λͺ…μ˜ˆμ‹œ
Entity IDEntity μ‹λ³„μž (PascalCase)Product, OrderItem
Titleν•œκΈ€ 제λͺ©μƒν’ˆ, μ£Όλ¬Έ ν•­λͺ©
Parent EntityλΆ€λͺ¨ Entity (선택)Order
Parent Entityλ₯Ό μ§€μ •ν•˜λ©΄ λΆ€λͺ¨ Entity의 ν•˜μœ„ Entityκ°€ λ©λ‹ˆλ‹€. 예: Order β†’ OrderItem

3. κΈ°λ³Έ Properties μΆ”κ°€

μƒμ„±λœ EntityλŠ” 기본적으둜 λ‹€μŒ ν•„λ“œλ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€:
{
  properties: [
    { name: "id", type: "int", primaryKey: true, autoIncrement: true },
    { name: "title", type: "string", length: 255 },
    { name: "created_at", type: "datetime", default: "CURRENT_TIMESTAMP" },
  ];
}

Properties νŽΈμ§‘

Property μΆ”κ°€

  1. [+ Add Property] λ²„νŠΌ 클릭
  2. Property 정보 μž…λ ₯:
ν•„λ“œν•„μˆ˜μ„€λͺ…μ˜ˆμ‹œ
Nameβœ…ν•„λ“œλͺ… (snake_case)email, phone_number
Typeβœ…λ°μ΄ν„° νƒ€μž…string, int, decimal
Lengthμ‘°κ±΄λΆ€λ¬Έμžμ—΄ 길이255
NullableNULL ν—ˆμš© μ—¬λΆ€true
DefaultκΈ°λ³Έκ°’0, CURRENT_TIMESTAMP
Commentμ„€λͺ…μ‚¬μš©μž 이메일
μ§€μ›ν•˜λŠ” 데이터 νƒ€μž…:
  • λ¬Έμžμ—΄: string, text, mediumtext, longtext
  • 숫자: int, bigint, float, double, decimal
  • λ‚ μ§œ: date, datetime, timestamp
  • 기타: boolean, json, enum

Property μˆ˜μ •

  1. Property 행을 ν΄λ¦­ν•˜μ—¬ νŽΈμ§‘ λͺ¨λ“œλ‘œ μ „ν™˜
  2. 값을 μˆ˜μ •
  3. λ‹€λ₯Έ 곳을 ν΄λ¦­ν•˜κ±°λ‚˜ Enterλ₯Ό 눌러 μ €μž₯

Property μ‚­μ œ

Property ν–‰μ˜ [Γ—] λ²„νŠΌμ„ ν΄λ¦­ν•©λ‹ˆλ‹€.
데이터 손싀 주의: Propertyλ₯Ό μ‚­μ œν•˜λ©΄ ν•΄λ‹Ή 컬럼의 λͺ¨λ“  데이터가 μ‚­μ œλ©λ‹ˆλ‹€. λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ„ μ‹€ν–‰ν•˜κΈ° 전에 λ°˜λ“œμ‹œ 데이터λ₯Ό λ°±μ—…ν•˜μ„Έμš”.

Indexes 관리

Index μΆ”κ°€

  1. Indexes μ„Ήμ…˜μœΌλ‘œ 슀크둀
  2. [+ Add Index] λ²„νŠΌ 클릭
  3. Index 정보 μž…λ ₯:
ν•„λ“œμ„€λͺ…μ˜ˆμ‹œ
Fields인덱슀 λŒ€μƒ ν•„λ“œ (볡수 선택 κ°€λŠ₯)email, created_at
Type인덱슀 νƒ€μž…index, unique, fulltext
Index νƒ€μž…:
  • index: 일반 인덱슀 (검색 μ„±λŠ₯ ν–₯상)
  • unique: μœ λ‹ˆν¬ 인덱슀 (쀑볡 λ°©μ§€)
  • fulltext: μ „λ¬Έ 검색 인덱슀 (ν…μŠ€νŠΈ 검색)

볡합 Index

μ—¬λŸ¬ ν•„λ“œλ₯Ό μ„ νƒν•˜μ—¬ 볡합 인덱슀λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€:
indexes: [
  { fields: ["user_id", "created_at"], type: "index" },
  { fields: ["email"], type: "unique" },
];

Relations 관리

belongsTo (N:1 관계)

의미: β€œμ΄ EntityλŠ” λ‹€λ₯Έ Entity에 μ†ν•œλ‹€β€ μ˜ˆμ‹œ: PostλŠ” User에 속함
  1. belongsTo μ„Ήμ…˜μ˜ [+ Add] λ²„νŠΌ 클릭
  2. 정보 μž…λ ₯:
ν•„λ“œμ„€λͺ…μ˜ˆμ‹œ
Entityμ°Έμ‘°ν•  EntityUser
As관계 별칭author
Foreign Keyμ™Έλž˜ν‚€ ν•„λ“œλͺ… (선택)author_id
μƒμ„±λ˜λŠ” μ½”λ“œ:
belongsTo: [{ entityId: "User", as: "author" }];

hasMany (1:N 관계)

의미: β€œμ΄ EntityλŠ” μ—¬λŸ¬ 개의 λ‹€λ₯Έ Entityλ₯Ό 가진닀” μ˜ˆμ‹œ: UserλŠ” μ—¬λŸ¬ Postλ₯Ό 가짐
  1. hasMany μ„Ήμ…˜μ˜ [+ Add] λ²„νŠΌ 클릭
  2. 정보 μž…λ ₯:
ν•„λ“œμ„€λͺ…μ˜ˆμ‹œ
EntityλŒ€μƒ EntityPost
As관계 별칭posts
μƒμ„±λ˜λŠ” μ½”λ“œ:
hasMany: [{ entityId: "Post", as: "posts" }];

Enums 관리

νŠΉμ • ν•„λ“œκ°€ μ œν•œλœ κ°’λ§Œ κ°€μ§ˆ 수 μžˆμ„ λ•Œ Enum을 μ‚¬μš©ν•©λ‹ˆλ‹€.

Enum μΆ”κ°€

  1. Enums μ„Ήμ…˜μ˜ [+ Add Enum] λ²„νŠΌ 클릭
  2. Enum 정보 μž…λ ₯:
ν•„λ“œμ„€λͺ…μ˜ˆμ‹œ
NameEnum 이름UserRole
Valuesκ°’ λͺ©λ‘ (μ‰Όν‘œλ‘œ ꡬ뢄)admin, user, guest
μƒμ„±λ˜λŠ” μ½”λ“œ:
enums: [
  {
    name: "UserRole",
    values: ["admin", "user", "guest"],
  },
];
Propertyμ—μ„œ μ‚¬μš©:
{
  name: "role",
  type: "enum",
  enum: "UserRole",
  default: "user"
}

AI 지원 Entity 생성

μ‚¬μ΄λ“œλ°” ν•˜λ‹¨μ˜ [πŸ’¬ AI] λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ AI μ±„νŒ… μΈν„°νŽ˜μ΄μŠ€κ°€ μ—΄λ¦½λ‹ˆλ‹€.

AI둜 Entity 생성

μ˜ˆμ‹œ ν”„λ‘¬ν”„νŠΈ:
λΈ”λ‘œκ·Έ κ²Œμ‹œκΈ€μ„ μœ„ν•œ Post Entityλ₯Ό λ§Œλ“€μ–΄μ€˜.
제λͺ©, λ‚΄μš©, μž‘μ„±μž, μž‘μ„±μΌ, μ‘°νšŒμˆ˜κ°€ ν•„μš”ν•΄.
AIκ°€ Entity μ •μ˜λ₯Ό μƒμ„±ν•˜κ³  μžλ™μœΌλ‘œ μΆ”κ°€ν•΄μ€λ‹ˆλ‹€.

AI둜 Entity μˆ˜μ •

μ˜ˆμ‹œ ν”„λ‘¬ν”„νŠΈ:
User Entity에 ν”„λ‘œν•„ 이미지 ν•„λ“œλ₯Ό μΆ”κ°€ν•΄μ€˜.
AIκ°€ κΈ°μ‘΄ Entityλ₯Ό λΆ„μ„ν•˜κ³  μˆ˜μ • 사항을 μ μš©ν•©λ‹ˆλ‹€.
ꡬ체적으둜 μš”μ²­ν•˜μ„Έμš”: ν•„λ“œ νƒ€μž…, μ œμ•½ 쑰건, 관계 등을 λͺ…ν™•νžˆ μ„€λͺ…ν• μˆ˜λ‘ 더 μ •ν™•ν•œ κ²°κ³Όλ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

μ‹€μ „ 예제

μ „μžμƒκ±°λž˜ Product Entity

export const ProductEntity = {
  properties: [
    { name: "id", type: "int", primaryKey: true, autoIncrement: true },
    { name: "title", type: "string", length: 255 },
    { name: "description", type: "text", nullable: true },
    { name: "price", type: "decimal", precision: 10, scale: 2 },
    { name: "stock", type: "int", default: 0 },
    { name: "category_id", type: "int" },
    { name: "status", type: "enum", enum: "ProductStatus" },
    { name: "created_at", type: "datetime", default: "CURRENT_TIMESTAMP" },
    { name: "updated_at", type: "datetime", onUpdate: "CURRENT_TIMESTAMP" },
  ],

  indexes: [
    { fields: ["category_id"] },
    { fields: ["title"], type: "fulltext" },
    { fields: ["status", "created_at"] },
  ],

  belongsTo: [{ entityId: "Category", as: "category" }],

  hasMany: [{ entityId: "Review", as: "reviews" }],

  enums: [
    {
      name: "ProductStatus",
      values: ["active", "inactive", "soldout"],
    },
  ],
} satisfies EntityType;

변경사항 적용

Entityλ₯Ό μˆ˜μ •ν•œ ν›„μ—λŠ” λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ„ μƒμ„±ν•˜κ³  μ‹€ν–‰ν•΄μ•Ό λ°μ΄ν„°λ² μ΄μŠ€μ— λ°˜μ˜λ©λ‹ˆλ‹€.

μ›Œν¬ν”Œλ‘œμš°

  1. Entity νŽΈμ§‘: UIμ—μ„œ Entity μˆ˜μ •
  2. Migration 생성: Migration νƒ­μ—μ„œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 생성
  3. Migration μ‹€ν–‰: λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ μ‹€ν–‰ν•˜μ—¬ DB 반영
  4. Scaffolding: Modelκ³Ό ν…ŒμŠ€νŠΈ μ½”λ“œ 생성
Entity 파일(.entity.ts)은 UIμ—μ„œ μˆ˜μ • μ‹œ μžλ™μœΌλ‘œ μ €μž₯λ©λ‹ˆλ‹€.

λ‹€μŒ 단계

Migration νƒ­

λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 생성 및 μ‹€ν–‰

Scaffolding νƒ­

Model μ½”λ“œ μžλ™ 생성