์์นด๋ฐ๋ฏธ๋ Altsis ์์คํ ์ ์ต์์ ๋จ์์ ๋๋ค. ๊ฐ ์์นด๋ฐ๋ฏธ๋ ๋ ๋ฆฝ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ฐ์ง๋ฉฐ, ์์นด๋ฐ๋ฏธ ๋ด์ ํ๊ต, ์ฌ์ฉ์, ํ๊ธฐ ๋ฑ์ด ๊ตฌ์ฑ๋ฉ๋๋ค.
๋ผ์ฐํธ ํ์ผ:
backend/src/routes/academies.js์ปจํธ๋กค๋ฌ ํ์ผ:backend/src/controllers/academies.js๋ชจ๋ธ ํ์ผ:backend/src/models/Academy.js
| ๋ฉ์๋ | ๊ฒฝ๋ก | ์ค๋ช | ๊ถํ |
|---|---|---|---|
POST |
/api/academies |
์์นด๋ฐ๋ฏธ ์์ฑ | owner |
GET |
/api/academies |
์์นด๋ฐ๋ฏธ ๋ชฉ๋ก/์์ธ ์กฐํ | ์ธ์ฆ ๋ถ์(๋จ์ผ) / owner|admin(๋ชฉ๋ก) |
PUT |
/api/academies/:academyId/activate |
์์นด๋ฐ๋ฏธ ํ์ฑํ | owner |
PUT |
/api/academies/:academyId/inactivate |
์์นด๋ฐ๋ฏธ ๋นํ์ฑํ | owner |
PUT |
/api/academies/:academyId/email |
์ด๋ฉ์ผ ๋ณ๊ฒฝ | owner |
PUT |
/api/academies/:academyId/tel |
์ ํ๋ฒํธ ๋ณ๊ฒฝ | owner |
PUT |
/api/academies/:academyId/chat |
์ฑํ ์ค์ | owner |
PUT |
/api/academies/:academyId/ai |
AI ํ์ฑํ/๋นํ์ฑํ | owner |
PUT |
/api/academies/:academyId/ai/apikey |
AI API ํค ์ค์ | owner |
GET |
/api/academies/:academyId/ai/apikey |
AI API ํค ์กด์ฌ ํ์ธ | owner |
PUT |
/api/academies/:academyId/ai/model |
AI ๋ชจ๋ธ ์ค์ | owner |
POST |
/api/academies/:academyId/backup |
๋ฐฑ์ ์์ฑ | owner|admin|manager |
GET |
/api/academies/:academyId/backup |
๋ฐฑ์ ๋ชฉ๋ก/์์ธ ์กฐํ | owner|admin|manager |
PUT |
/api/academies/:academyId/restore |
๋ฐฑ์ ๋ณต์ | owner|admin|manager |
DELETE |
/api/academies/:academyId/backup |
๋ฐฑ์ ์ญ์ | owner|admin|manager |
GET |
/api/academies/:academyId/:docType/:docId? |
๋ํ๋จผํธ ์กฐํ | owner|admin |
DELETE |
/api/academies/:academyId |
์์นด๋ฐ๋ฏธ ์ญ์ | owner |
์์นด๋ฐ๋ฏธ์ ํด๋น ์์นด๋ฐ๋ฏธ์ ๊ด๋ฆฌ์ ๊ณ์ ์ ๋์์ ์์ฑํฉ๋๋ค. ์์นด๋ฐ๋ฏธ ์์ฑ ์ ๋
๋ฆฝ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค({academyId}-db)๊ฐ ์๋์ผ๋ก ์์ฑ๋ฉ๋๋ค.
POST /api/academies
๊ถํ: owner
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
academyId |
string |
O | ์์นด๋ฐ๋ฏธ ๊ณ ์ ID (์๋ฌธ, ์ซ์, ํ์ดํ) |
academyName |
string |
O | ์์นด๋ฐ๋ฏธ ์ด๋ฆ |
adminId |
string |
O | ๊ด๋ฆฌ์ ์ฌ์ฉ์ ID |
adminName |
string |
O | ๊ด๋ฆฌ์ ์ด๋ฆ |
email |
string |
X | ์์นด๋ฐ๋ฏธ ์ด๋ฉ์ผ |
tel |
string |
X | ์์นด๋ฐ๋ฏธ ์ ํ๋ฒํธ |
{
"academyId": "my-academy",
"academyName": "๋์ ์์นด๋ฐ๋ฏธ",
"adminId": "admin01",
"adminName": "๊ด๋ฆฌ์",
"email": "admin@example.com",
"tel": "02-1234-5678"
}{
"academy": {
"_id": "507f1f77bcf86cd799439011",
"academyId": "my-academy",
"academyName": "๋์ ์์นด๋ฐ๋ฏธ",
"email": "admin@example.com",
"tel": "02-1234-5678",
"adminId": "admin01",
"adminName": "๊ด๋ฆฌ์",
"isActivated": true,
"chatEnabled": false,
"aiEnabled": false,
"aiModel": "gemini-3.6-flash",
"createdAt": "2024-01-15T09:00:00.000Z",
"updatedAt": "2024-01-15T09:00:00.000Z"
},
"admin": {
"userId": "admin01",
"userName": "๊ด๋ฆฌ์",
"password": "์๋์์ฑ๋๋น๋ฐ๋ฒํธ"
}
}| ์ํ ์ฝ๋ | ๋ฉ์์ง | ์ค๋ช |
|---|---|---|
400 |
FIELD_REQUIRED({ํ๋๋ช
}) |
ํ์ ํ๋ ๋๋ฝ |
400 |
FIELD_INVALID({ํ๋๋ช
}) |
ํ๋ ๊ฐ ์ ํจ์ฑ ๊ฒ์ฌ ์คํจ |
409 |
FIELD_IN_USE(academyId) |
์ด๋ฏธ ์ฌ์ฉ ์ค์ธ ์์นด๋ฐ๋ฏธ ID |
์์นด๋ฐ๋ฏธ๋ฅผ ๋จ์ผ ๋๋ ๋ชฉ๋ก์ผ๋ก ์กฐํํฉ๋๋ค.
GET /api/academies
๊ถํ: ๋จ์ผ ์กฐํ ์ ์ธ์ฆ ๋ถ์ (๊ฒ์คํธ ์ ๊ทผ ๊ฐ๋ฅ), ๋ชฉ๋ก ์กฐํ ์ owner ๋๋ admin
| ํ๋ผ๋ฏธํฐ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
academyId |
string |
X | ํน์ ์์นด๋ฐ๋ฏธ ID๋ก ์กฐํ |
{
"academy": {
"_id": "507f1f77bcf86cd799439011",
"academyId": "my-academy",
"academyName": "๋์ ์์นด๋ฐ๋ฏธ",
"isActivated": true,
"chatEnabled": false,
"aiEnabled": false,
"aiModel": "gemini-3.6-flash"
}
}{
"academies": [
{
"_id": "507f1f77bcf86cd799439011",
"academyId": "academy-a",
"academyName": "์์นด๋ฐ๋ฏธ A",
"isActivated": true
},
{
"_id": "507f1f77bcf86cd799439012",
"academyId": "academy-b",
"academyName": "์์นด๋ฐ๋ฏธ B",
"isActivated": false
}
]
}| ์ํ ์ฝ๋ | ๋ฉ์์ง | ์ค๋ช |
|---|---|---|
400 |
FIELD_REQUIRED(academyID) |
๊ฒ์คํธ ์ ๊ทผ ์ academyId ํ๋ผ๋ฏธํฐ ๋๋ฝ |
403 |
PERMISSION_DENIED |
๊ถํ ๋ถ์กฑ |
404 |
ACADEMY_NOT_FOUND |
์์นด๋ฐ๋ฏธ๋ฅผ ์ฐพ์ ์ ์์ |
์์นด๋ฐ๋ฏธ์ ํ์ฑํ ์ํ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค. ๋นํ์ฑํ๋ ์์นด๋ฐ๋ฏธ์๋ ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค.
PUT /api/academies/:academyId/activate
๊ถํ: owner
PUT /api/academies/:academyId/inactivate
๊ถํ: owner
| ํ๋ผ๋ฏธํฐ | ํ์ | ์ค๋ช |
|---|---|---|
academyId |
string |
์์นด๋ฐ๋ฏธ ID |
{
"academy": {
"_id": "507f1f77bcf86cd799439011",
"academyId": "my-academy",
"isActivated": true
}
}PUT /api/academies/:academyId/email
๊ถํ: owner
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
email |
string |
X | ์ ์ด๋ฉ์ผ ์ฃผ์ (๋น ๊ฐ์ด๋ฉด ์ญ์ ) |
{
"email": "new-email@example.com"
}{
"academy": {
"_id": "...",
"email": "new-email@example.com"
}
}PUT /api/academies/:academyId/tel
๊ถํ: owner
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
tel |
string |
X | ์ ์ ํ๋ฒํธ (๋น ๊ฐ์ด๋ฉด ์ญ์ ) |
์์นด๋ฐ๋ฏธ์ ์ฑํ ๊ธฐ๋ฅ ํ์ฑํ ์ํ๋ฅผ ์ค์ ํฉ๋๋ค.
PUT /api/academies/:academyId/chat
๊ถํ: owner
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
chatEnabled |
boolean |
X | true(ํ์ฑํ) / false(๋นํ์ฑํ). ๋ฏธ์ ๊ณต ์ ํ ๊ธ |
{
"chatEnabled": true
}{
"academy": {
"_id": "...",
"chatEnabled": true
}
}PUT /api/academies/:academyId/ai
๊ถํ: owner
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
aiEnabled |
boolean |
X | true(ํ์ฑํ) / false(๋นํ์ฑํ). ๋ฏธ์ ๊ณต ์ ํ ๊ธ |
PUT /api/academies/:academyId/ai/apikey
๊ถํ: owner
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
apiKey |
string |
O | AI ์๋น์ค API ํค |
aiModel |
string |
X | AI ๋ชจ๋ธ๋ช |
aiProvider |
string |
X | AI ์ ๊ณต์ (openai / anthropic / gemini) |
{
"success": true
}์ฐธ๊ณ :
aiApiKey๋ ๋ณด์์ ์ํด API ์กฐํ ์๋ต์ ํฌํจ๋์ง ์์ต๋๋ค (select: false).
GET /api/academies/:academyId/ai/apikey
๊ถํ: owner
{
"hasApiKey": true,
"apiKeyHint": "AIzaโขโขโขโขโขโขโขโขKzuw",
"aiProvider": "gemini",
"aiModel": "gemini-3.6-flash"
}์ฐธ๊ณ : ์ ์ฒด API ํค๋ ๋ฐํํ์ง ์์ต๋๋ค.
apiKeyHint๋ ์ยท๋ค ์ผ๋ถ๋ง ๋จ๊ธด ๋ง์คํน ๋ฌธ์์ด์ ๋๋ค.
PUT /api/academies/:academyId/ai/model
๊ถํ: owner
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
aiModel |
string |
O | ์ฌ์ฉํ AI ๋ชจ๋ธ๋ช
(์: gemini-3.6-flash) |
PUT /api/academies/:academyId/ai/usage-limits
๊ถํ: owner, admin, manager (admin/manager๋ ๋ณธ์ธ ์์นด๋ฐ๋ฏธ๋ง)
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
enabled |
boolean |
O | 1์ธ ์ผ์ผ Alt ํ๋ ์ฌ์ฉ ์ฌ๋ถ |
dailyUserAlts |
number |
์กฐ๊ฑด๋ถ | 1์ธ๋น ์ผ(UTC) Alt ํ๋. 1 Alt = 10,000 ํ ํฐ. enabled=true์ด๋ฉด 0๋ณด๋ค ์ปค์ผ ํจ |
์ง์ ํ ๋ชจ๋ธ์ ๋ํ๋จผํธ๋ฅผ ์ ์ฒด ์กฐํํ์ฌ S3์ JSON ํ์ผ๋ก ์ ๋ก๋ํฉ๋๋ค.
POST /api/academies/:academyId/backup
๊ถํ: owner, admin ๋๋ manager
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
models |
object[] |
O | ๋ฐฑ์ ํ ๋ชจ๋ธ ๋ชฉ๋ก |
models[].title |
string |
O | ๋ชจ๋ธ๋ช
(users, schools, seasons, registrations, syllabuses, enrollments, forms, notifications, archives, chatRooms, chatMessages) |
{
"models": [
{ "title": "users" },
{ "title": "schools" },
{ "title": "seasons" },
{ "title": "registrations" }
]
}{
"logs": [
"โ [Backup] my-academy/backup/2024-01-15_09:00:00.000",
"โ requested by admin01(my-academy)",
"โโ backup users...",
"โโ reading users... 150",
"โโ writing users...",
"โโ backup users is done(1234ms)",
"โ [Backup] my-academy/backup/2024-01-15_09:00:00.000 is done(5678ms)"
]
}GET /api/academies/:academyId/backup
๊ถํ: owner, admin ๋๋ manager
{
"backupList": [
{
"title": "2024-01-15_09:00:00.000",
"key": "my-academy/backup/2024-01-15_09:00:00.000/"
},
{
"title": "2024-01-14_18:30:00.000",
"key": "my-academy/backup/2024-01-14_18:30:00.000/"
}
]
}GET /api/academies/:academyId/backup?title={๋ฐฑ์
์ ๋ชฉ}
๊ถํ: owner, admin ๋๋ manager
| ํ๋ผ๋ฏธํฐ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
title |
string |
O | ๋ฐฑ์ ์ ๋ชฉ (ํ์์คํฌํ) |
{
"backup": [
{
"title": "users.json",
"size": 102400,
"key": "my-academy/backup/2024-01-15_09:00:00.000/users.json",
"lastModified": "2024-01-15T09:00:05.000Z"
},
{
"title": "schools.json",
"size": 8192,
"key": "my-academy/backup/2024-01-15_09:00:00.000/schools.json",
"lastModified": "2024-01-15T09:00:03.000Z"
}
]
}ํน์ ๋ชจ๋ธ์ ๋ํ๋จผํธ๋ฅผ ์ ๋ถ ๊ต์ฒดํ์ฌ ๋ณต์ํฉ๋๋ค.
PUT /api/academies/:academyId/restore
๊ถํ: owner, admin ๋๋ manager
์ฃผ์: ๋ณต์ ์ ํด๋น ๋ชจ๋ธ์ ๊ธฐ์กด ๋ฐ์ดํฐ๊ฐ ๋ชจ๋ ์ญ์ ๋ ํ ๋ฐฑ์ ๋ฐ์ดํฐ๋ก ๋์ฒด๋ฉ๋๋ค.
| ํ๋ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
model |
string |
O | ๋ณต์ํ ๋ชจ๋ธ๋ช |
documents |
object[] |
O | ๋ณต์ํ ๋ํ๋จผํธ ๋ฐฐ์ด |
DELETE /api/academies/:academyId/backup?title={๋ฐฑ์
์ ๋ชฉ}
๊ถํ: owner, admin ๋๋ manager
| ํ๋ผ๋ฏธํฐ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
title |
string |
O | ์ญ์ ํ ๋ฐฑ์ ์ ๋ชฉ |
์์นด๋ฐ๋ฏธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ด์ ์์ ์ปฌ๋ ์ ์ ์ง์ ์กฐํํฉ๋๋ค. ๊ด๋ฆฌ ๋ฐ ๋๋ฒ๊น ์ฉ๋๋ก ์ฌ์ฉ๋ฉ๋๋ค.
GET /api/academies/:academyId/:docType/:docId?
๊ถํ: owner ๋๋ admin
| ํ๋ผ๋ฏธํฐ | ํ์ | ํ์ | ์ค๋ช |
|---|---|---|---|
academyId |
string |
O | ์์นด๋ฐ๋ฏธ ID |
docType |
string |
O | ์ปฌ๋ ์
ํ์
(users, schools, seasons ๋ฑ) |
docId |
string |
X | ๋ํ๋จผํธ ObjectId (๋ฏธ์ ๊ณต ์ ๋ชฉ๋ก ์กฐํ) |
{
"documents": [
{ "_id": "...", "userId": "user01", "userName": "ํ๊ธธ๋" },
{ "_id": "...", "userId": "user02", "userName": "๊น์ฒ ์" }
]
}{
"document": {
"_id": "...",
"userId": "user01",
"userName": "ํ๊ธธ๋"
}
}์์นด๋ฐ๋ฏธ ๋ฌธ์์ ํด๋น ์์นด๋ฐ๋ฏธ์ ์ ์ฒด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ญ์ ํฉ๋๋ค.
DELETE /api/academies/:academyId
๊ถํ: owner
์ฃผ์: ์ด ์์ ์ ๋๋๋ฆด ์ ์์ต๋๋ค. ์์นด๋ฐ๋ฏธ์ ์ํ ๋ชจ๋ ๋ฐ์ดํฐ(์ฌ์ฉ์, ํ๊ต, ํ๊ธฐ, ์์ ๋ฑ)๊ฐ ์๊ตฌ ์ญ์ ๋ฉ๋๋ค.
| ํ๋ผ๋ฏธํฐ | ํ์ | ์ค๋ช |
|---|---|---|
academyId |
string |
์ญ์ ํ ์์นด๋ฐ๋ฏธ ID |
{}| ์ํ ์ฝ๋ | ๋ฉ์์ง | ์ค๋ช |
|---|---|---|
404 |
ACADEMY_NOT_FOUND |
์์นด๋ฐ๋ฏธ๋ฅผ ์ฐพ์ ์ ์์ |
| ํจ์๋ช | ๋ฉ์๋ | ๊ฒฝ๋ก | ์ค๋ช |
|---|---|---|---|
CAcademy |
POST | /api/academies |
์์นด๋ฐ๋ฏธ ์์ฑ |
RAcademies |
GET | /api/academies |
์์นด๋ฐ๋ฏธ ๋ชฉ๋ก ์กฐํ |
RAcademy |
GET | /api/academies?academyId=... |
์์นด๋ฐ๋ฏธ ๋จ์ผ ์กฐํ |
UActivateAcademy |
PUT | /api/academies/:academyId/activate |
ํ์ฑํ |
UInactivateAcademy |
PUT | /api/academies/:academyId/inactivate |
๋นํ์ฑํ |
UAcademyEmail |
PUT | /api/academies/:academyId/email |
์ด๋ฉ์ผ ๋ณ๊ฒฝ |
UAcademyTel |
PUT | /api/academies/:academyId/tel |
์ ํ๋ฒํธ ๋ณ๊ฒฝ |
UAcademyChatEnabled |
PUT | /api/academies/:academyId/chat |
์ฑํ ์ค์ |
UAcademyAiEnabled |
PUT | /api/academies/:academyId/ai |
AI ํ์ฑํ ์ค์ |
UAcademyAiApiKey |
PUT | /api/academies/:academyId/ai/apikey |
AI API ํค ์ค์ |
RAcademyAiApiKey |
GET | /api/academies/:academyId/ai/apikey |
AI API ํค ํ์ธ |
CAcademyBackup |
POST | /api/academies/:academyId/backup |
๋ฐฑ์ ์์ฑ |
RAcademyBackup |
GET | /api/academies/:academyId/backup |
๋ฐฑ์ ์กฐํ |
URestoreAcademy |
PUT | /api/academies/:academyId/restore |
๋ฐฑ์ ๋ณต์ |
DAcademyBackup |
DELETE | /api/academies/:academyId/backup |
๋ฐฑ์ ์ญ์ |
DAcademy |
DELETE | /api/academies/:academyId |
์์นด๋ฐ๋ฏธ ์ญ์ |