Sonamu UI์ Entity ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ์๊ฐ์ ์ธํฐํ์ด์ค๋ก Entity๋ฅผ ์ฝ๊ฒ ์์ฑํ๊ณ ํธ์งํ ์ ์์ต๋๋ค. CLI๋ก ํ์ผ์ ์ง์ ์์ ํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ณ ์ง๊ด์ ์
๋๋ค.
Entity ํญ ๊ตฌ์กฐ
Entity ํญ์ ๋ ๊ฐ์ง ์ฃผ์ ์์ญ์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค:
- ์ผ์ชฝ Sidebar: Entity ๋ชฉ๋ก๊ณผ ์ Entity ์ถ๊ฐ ๋ฒํผ
- ์ค๋ฅธ์ชฝ Content: ์ ํํ Entity์ ์์ธ ์ ๋ณด (Properties, Indexes, Relations, Subsets, Enums)
Entity ์์ฑํ๊ธฐ
1. New Entity ๋ฒํผ ํด๋ฆญ
์ฌ์ด๋๋ฐ ํ๋จ์ [+ New Entity] ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
2. Entity ์ ๋ณด ์
๋ ฅ
๋ชจ๋ฌ์ด ์ด๋ฆฌ๋ฉด ๋ค์ ์ ๋ณด๋ฅผ ์
๋ ฅํฉ๋๋ค:
| ํ๋ | ์ค๋ช
| ์์ |
|---|
| Entity ID | Entity ์๋ณ์ (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 ์ถ๊ฐ
- [+ Add Property] ๋ฒํผ ํด๋ฆญ
- Property ์ ๋ณด ์
๋ ฅ:
| ํ๋ | ํ์ | ์ค๋ช
| ์์ |
|---|
| Name | โ
| ํ๋๋ช
(snake_case) | email, phone_number |
| Type | โ
| ๋ฐ์ดํฐ ํ์
| string, int, decimal |
| Length | ์กฐ๊ฑด๋ถ | ๋ฌธ์์ด ๊ธธ์ด | 255 |
| Nullable | | NULL ํ์ฉ ์ฌ๋ถ | true |
| Default | | ๊ธฐ๋ณธ๊ฐ | 0, CURRENT_TIMESTAMP |
| Comment | | ์ค๋ช
| ์ฌ์ฉ์ ์ด๋ฉ์ผ |
์ง์ํ๋ ๋ฐ์ดํฐ ํ์
:
- ๋ฌธ์์ด:
string, text, mediumtext, longtext
- ์ซ์:
int, bigint, float, double, decimal
- ๋ ์ง:
date, datetime, timestamp
- ๊ธฐํ:
boolean, json, enum
Property ์์
- Property ํ์ ํด๋ฆญํ์ฌ ํธ์ง ๋ชจ๋๋ก ์ ํ
- ๊ฐ์ ์์
- ๋ค๋ฅธ ๊ณณ์ ํด๋ฆญํ๊ฑฐ๋ Enter๋ฅผ ๋๋ฌ ์ ์ฅ
Property ์ญ์
Property ํ์ [ร] ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
๋ฐ์ดํฐ ์์ค ์ฃผ์: Property๋ฅผ ์ญ์ ํ๋ฉด ํด๋น ์ปฌ๋ผ์ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ญ์ ๋ฉ๋๋ค.
๋ง์ด๊ทธ๋ ์ด์
์ ์คํํ๊ธฐ ์ ์ ๋ฐ๋์ ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์
ํ์ธ์.
Indexes ๊ด๋ฆฌ
Index ์ถ๊ฐ
- Indexes ์น์
์ผ๋ก ์คํฌ๋กค
- [+ Add Index] ๋ฒํผ ํด๋ฆญ
- 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์ ์ํจ
- belongsTo ์น์
์ [+ Add] ๋ฒํผ ํด๋ฆญ
- ์ ๋ณด ์
๋ ฅ:
| ํ๋ | ์ค๋ช
| ์์ |
|---|
| Entity | ์ฐธ์กฐํ Entity | User |
| As | ๊ด๊ณ ๋ณ์นญ | author |
| Foreign Key | ์ธ๋ํค ํ๋๋ช
(์ ํ) | author_id |
์์ฑ๋๋ ์ฝ๋:
belongsTo: [
{ entityId: "User", as: "author" }
]
hasMany (1:N ๊ด๊ณ)
์๋ฏธ: โ์ด Entity๋ ์ฌ๋ฌ ๊ฐ์ ๋ค๋ฅธ Entity๋ฅผ ๊ฐ์ง๋คโ
์์: User๋ ์ฌ๋ฌ Post๋ฅผ ๊ฐ์ง
- hasMany ์น์
์ [+ Add] ๋ฒํผ ํด๋ฆญ
- ์ ๋ณด ์
๋ ฅ:
| ํ๋ | ์ค๋ช
| ์์ |
|---|
| Entity | ๋์ Entity | Post |
| As | ๊ด๊ณ ๋ณ์นญ | posts |
์์ฑ๋๋ ์ฝ๋:
hasMany: [
{ entityId: "Post", as: "posts" }
]
Enums ๊ด๋ฆฌ
ํน์ ํ๋๊ฐ ์ ํ๋ ๊ฐ๋ง ๊ฐ์ง ์ ์์ ๋ Enum์ ์ฌ์ฉํฉ๋๋ค.
Enum ์ถ๊ฐ
- Enums ์น์
์ [+ Add Enum] ๋ฒํผ ํด๋ฆญ
- Enum ์ ๋ณด ์
๋ ฅ:
| ํ๋ | ์ค๋ช
| ์์ |
|---|
| Name | Enum ์ด๋ฆ | 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๋ฅผ ์์ ํ ํ์๋ ๋ง์ด๊ทธ๋ ์ด์
์ ์์ฑํ๊ณ ์คํํด์ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์๋ฉ๋๋ค.
์ํฌํ๋ก์ฐ
- Entity ํธ์ง: UI์์ Entity ์์
- Migration ์์ฑ: Migration ํญ์์ ๋ง์ด๊ทธ๋ ์ด์
์์ฑ
- Migration ์คํ: ๋ง์ด๊ทธ๋ ์ด์
์คํํ์ฌ DB ๋ฐ์
- Scaffolding: Model๊ณผ ํ
์คํธ ์ฝ๋ ์์ฑ
Entity ํ์ผ(.entity.ts)์ UI์์ ์์ ์ ์๋์ผ๋ก ์ ์ฅ๋ฉ๋๋ค.
๋ค์ ๋จ๊ณ