AIκ° νμ₯ μν μ λμ νμ¬, λͺ¨λ νμμ΄ λλ±νκ² νμ ν μ μλ ν νλ‘μ νΈ κ΄λ¦¬ μλΉμ€
μλΉμ€ λ°λ‘κ°κΈ° Β· λ©μμ΄μ¬μμ²λΌ μμ΄λμ΄ν€ μ 보
- μκ°
- μ£Όμ κΈ°λ₯
- μ€ν¬λ¦°μ·
- κΈ°μ μ€ν
- μμ€ν μν€ν μ²
- λ°μ΄ν° λͺ¨λΈ
- AI νμ΄νλΌμΈ
- μμνκΈ°
- νμ
Teamplan-itμ λ©μμ΄μ¬μμ²λΌ μμ΄λμ΄ν€μμ νμν μλΉμ€μ λλ€.
λνκ΅ ννμμ λ§€λ² λ°λ³΅λλ λ¬Έμ β "λκ° νμ₯ ν κ±°μΌ?", "μΌμ μ μ΄λ»κ² μ§μ§?", "λκ° λ λ§‘μ?" β λ₯Ό AIλ‘ ν΄κ²°ν©λλ€. νλ‘μ νΈ μ 보μ νμμ κ°μ λ§ μ λ ₯νλ©΄, AIκ° κ³Όμ μ λΆν΄νκ³ , μμ‘΄μ±μ λΆμνκ³ , νμλ³ μ΅μ μΌμ μ μλμΌλ‘ λ°°μ ν©λλ€.
λ μ΄μ νμ₯μ΄λΌλ λΆλ΄ μμ΄, λͺ¨λκ° λλ±ν νμμΌλ‘ νλ‘μ νΈμ μ§μ€ν μ μμ΅λλ€.
νλ‘μ νΈ μ€λͺ κ³Ό νμμ κ°μ , κ°μ© μκ°μ κΈ°λ°μΌλ‘ AIκ° κ³Όμ μ λΆν΄νκ³ μ΅μ μ λ΄λΉμλ₯Ό λ°°μ ν©λλ€. μμ‘΄μ± κ·Έλνλ₯Ό μμ±νμ¬ μμ μμλ₯Ό μλμΌλ‘ μ€κ³ν©λλ€.
νμλ³ μμ μΌμ μ νλμ μκ°νν©λλ€. μ΄ μμ μ, μ§ν μν©, μλ£μ¨, λ¨μ μΌμλ₯Ό μ€μκ°μΌλ‘ νμΈν μ μμ΅λλ€.
AI λ§€λμ κ° κ° νμμκ² λ§μΆ€ν μ 무 μλ΄μ λκΈ°λΆμ¬λ₯Ό μ 곡ν©λλ€. μ±ν μΌλ‘ μ§ν μν©μ λ³΄κ³ νλ©΄ μ§μ²λκ° μλμΌλ‘ μ λ°μ΄νΈλ©λλ€.
νλ‘μ νΈ μ§μ²λ, λ΄ μ²΄ν¬λ¦¬μ€νΈ, AI μ‘°μΈμ ν νλ©΄μμ νμΈν©λλ€. ν μ 체μ κ°μΈμ μ§νλ₯ μ λ§ μ°¨νΈλ‘ μ§κ΄μ μΌλ‘ 보μ¬μ€λλ€.
μ΄λ λ§ν¬ λλ μ΄λ©μΌλ‘ νμμ μ΄λν©λλ€. κ° νμμ΄ μμ μ κ°μ , μ νΈ μκ°λ, κ°μ© μκ°μ μ§μ μ λ ₯νλ©΄ AI λΆμμ λ°μλ©λλ€.
| λΆλ₯ | κΈ°μ |
|---|---|
| νλ μμν¬ | Next.js 16 (App Router), React 19 |
| μΈμ΄ | TypeScript |
| μ€νμΌλ§ | Tailwind CSS 4 |
| λ°μ΄ν°λ² μ΄μ€ | Supabase (PostgreSQL) |
| μΈμ¦ | Supabase Auth |
| νμΌ μ μ₯μ | Supabase Storage |
| AI | Google Gemini 2.5 Flash |
| μ΄λ©μΌ | Resend |
| λ°°ν¬ | Vercel |
Client β Next.js API Routes β μΈλΆ μλΉμ€ 3κ³μΈ΅ ꡬ쑰. Supabaseκ° Auth, DB, Storageλ₯Ό λͺ¨λ λ΄λΉνλ©°, Gemini APIλ DBμμ νλ‘μ νΈΒ·νμ λ°μ΄ν°λ₯Ό μ½μ΄ κ³Όμ λΆμμ νμ©ν©λλ€.
μ΄ 9κ° ν μ΄λΈ μ€κ³. νλ‘μ νΈ-νμ-κ³Όμ μ€μ¬μ μ κ·νλ μ€ν€λ§.
erDiagram
profiles ||--o{ projects : "owns"
profiles ||--o{ project_members : "joins"
projects ||--o{ project_members : "has"
projects ||--o{ tasks : "contains"
projects ||--o{ chat_messages : "has"
projects ||--o{ analysis_snapshots : "tracks"
projects ||--o{ files : "stores"
projects ||--o{ invitations : "issues"
project_members ||--o{ tasks : "assigned"
project_members ||--o{ chat_messages : "sends"
project_members ||--o{ files : "uploads"
tasks ||--o{ task_checklists : "has"
profiles {
uuid id PK
text display_name
text email
}
projects {
uuid id PK
text name
text description
text goal
text deliverable
date start_date
date end_date
text constraints
text document_url
boolean is_private
enum status
uuid owner_id FK
timestamp created_at
}
project_members {
uuid id PK
uuid project_id FK
uuid user_id FK
text display_name
text major_or_part
array strengths
array time_slots
text hours_per_week
enum color
enum role
boolean info_completed
timestamp joined_at
}
tasks {
uuid id PK
uuid project_id FK
uuid assignee_id FK
text label
enum category
integer progress
enum status
date start_date
date end_date
array depends_on
integer sort_order
timestamp updated_at
}
task_checklists {
uuid id PK
uuid task_id FK
text content
boolean is_completed
timestamp completed_at
integer sort_order
}
chat_messages {
uuid id PK
uuid project_id FK
uuid sender_id FK
enum role
text content
jsonb metadata
timestamp created_at
}
analysis_snapshots {
uuid id PK
uuid project_id FK
jsonb result_json
boolean is_active
timestamp created_at
}
files {
uuid id PK
uuid project_id FK
uuid uploader_id FK
text file_name
text storage_path
text mime_type
integer size_bytes
timestamp created_at
}
invitations {
uuid id PK
uuid project_id FK
text token UK
text email
enum status
timestamp expires_at
timestamp created_at
}
νλ‘μ νΈ μ 보μ νμ λ°μ΄ν°λ₯Ό Gemini APIμ μ λ¬νμ¬ κ³Όμ μ μλ λΆν΄Β·λ°°μ ν©λλ€.
μ λ ₯ λ°μ΄ν°:
- νλ‘μ νΈ κΈ°λ³Έμ 보 (μ΄λ¦, μ€λͺ , λͺ©ν, μ°μΆλ¬Ό, κΈ°κ°, μ μ½μ¬ν)
- νμ μ 보 (μ΄λ¦, μ 곡, κ°μ , μ νΈ μκ°λ, μ£ΌλΉ κ°μ©μκ°)
- μ²¨λΆ λ¬Έμ (PDF, μ΄λ―Έμ§ λ± β Base64 μΈμ½λ©νμ¬ Geminiμ μ λ¬)
μΆλ ₯ ꡬ쑰 (JSON Schema κ°μ ):
{
"nodes": [
{ "id": "task_1", "label": "API μ€κ³", "day": "Day 4-7",
"assignee": "μ΄μΉν¬", "category": "backend", "dependsOn": ["task_0"] }
],
"timelines": [
{ "memberName": "μ΄μΉν¬", "bars": [
{ "label": "API μ€κ³", "startPercent": 10, "widthPercent": 20 }
]}
],
"checklists": { "task_1": ["μꡬμ¬ν λΆμ", "API λͺ
μΈ μμ±", "리뷰"] },
"comment": "κ° νμμ κ°μ κ³Ό μκ°λλ₯Ό κ³ λ €νμ¬ λ°°μ νμ΅λλ€..."
}μμ μ± ν보:
responseSchemaλ‘ JSON ꡬ쑰 κ°μ (Structured Output)- μλ΅ μ€ν¨ μ μ΅λ 3ν μ¬μλ (μ¨λ 0.7 β 0.3 νν₯)
- λΆμμ ν JSON μλ 볡ꡬ (λ―Έμ’ λ£ λ¬Έμμ΄, λ«νμ§ μμ κ΄νΈ μ²λ¦¬)
- IPλΉ λΆλΉ 5ν Rate Limiting
νμκ³Όμ λνμμ μ§ν μν©μ μλμΌλ‘ κ°μ§νκ³ μ λ°μ΄νΈν©λλ€.
μλ μ§νλ₯ μ
λ°μ΄νΈ: AI μλ΅μ [PROGRESS_UPDATE] νκ·Έκ° ν¬ν¨λλ©΄ ν΄λΉ κ³Όμ
μ μ§νλ₯ κ³Ό μνλ₯Ό μλ λ³κ²½ (todo β in_progress β done)
μλ 체ν¬λ¦¬μ€νΈ μλ£: [CHECKLIST_UPDATE] νκ·Έλ‘ μ²΄ν¬λ¦¬μ€νΈ νλͺ©μ μλ μλ£ μ²λ¦¬νκ³ , μλ£ λΉμ¨μ λ°λΌ κ³Όμ
μ§νλ₯ μ μ¬κ³μ°
κ°μ νΈλ¦¬κ±° κ°μ§: 3μΌ μ΄μ μ§νλ₯ 0%μΈ κ³Όμ μ΄ μμΌλ©΄ AIκ° μλμΌλ‘ κ°μ§νμ¬ νμμκ² λΆλλ¬μ΄ κ²©λ €μ ꡬ체μ μΈ μμ κ°μ΄λλ₯Ό μ 곡
- Node.js 18+
- npm
# μμ‘΄μ± μ€μΉ
npm install
# νκ²½λ³μ μ€μ
cp .env.example .env.local.env.localμ λ€μ νκ²½λ³μλ₯Ό μ€μ ν©λλ€:
GEMINI_API_KEY= # Google Gemini API ν€
NEXT_PUBLIC_SUPABASE_URL= # Supabase νλ‘μ νΈ URL
NEXT_PUBLIC_SUPABASE_ANON_KEY= # Supabase μ΅λͺ
ν€
SUPABASE_SERVICE_ROLE_KEY= # Supabase μλΉμ€ ν€
RESEND_API_KEY= # Resend μ΄λ©μΌ API ν€# κ°λ° μλ² μ€ν
npm run devhttp://localhost:3000μμ νμΈν μ μμ΅λλ€.
ν ννλλ (Teamplanit) | λ©μμ΄μ¬μμ²λΌ μμ΄λμ΄ν€
| μ΄λ¦ | μν |
|---|---|
| μ΄μΉν¬ | Backend |
| μ λ―Όκ²½ | Backend |
| κΉμ§μ° | Frontend |
| κΉμ§μ | κΈ°ν |
| μ‘°μ©ν | λμμΈ |
| μμν | λ©ν |








