Admin Dashboard Implementation Guide
๊ด๋ฆฌ์ ํ๋ฉด(Admin Panel) ๋ง์ด๊ทธ๋ ์ด์ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋ ์ค๊ณ์
1. ์ ์ฒด ์์คํ ์ํคํ ์ฒ ๋ฐ ๊ตฌํ ๊ณํ
๋ณธ ์ค๊ณ์๋ ๊ด๋ฆฌ์ํ๋ฉด_ํตํฉ๋์๋ณด๋_UI์ ์.html ์ ์ ํ์ผ์ ์ฌ์ฉ์ ๋์ ์๋ฎฌ๋ ์ด์
์ ํ๋ก๋์
๊ธ ์๋ฒ ์ธํ๋ผ์ ์์ฐฉํ๊ธฐ ์ํ ์ค๊ณ ๋ช
์ธ์
๋๋ค. ์์คํ
ํ๊ฒฝ์ Node.js / PostgreSQL / MinIO S3 ๋ฐ Redis Queue ์ํคํ
์ฒ๋ฅผ ์ค์ํฉ๋๋ค.
๊ตฌํ ๋จ๊ณ๋ณ ๊ฐ๋ฐ ๋ก๋๋งต
[1๋จ๊ณ] ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง ํ์ฅ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์
- ๊ณตํต ์ฝ๋ ๋ถ๋ฅ ๋ฐ ์ธ๋ถ ๊ฐ ์ ์ด๋ฅผ ์ํ
code_master๋ฐcode_detailํ ์ด๋ธ ์ ์ค. - ๊ธฐ์กด ํ
์ด๋ธ ํ์ฉ (์ปฌ๋ผ ์ถ๊ฐ ์์): ๊ธฐ์กด์ ์กด์ฌํ๋ ํ๋ก์ ํธ ํ
์ด๋ธ(
tb_project)์category์ปฌ๋ผ๊ณผ ์ฌ์ฉ์ ํ ์ด๋ธ(tb_user)์"group"์ปฌ๋ผ์code_detail.base_code์ธ๋ํค ์ฐธ์กฐ ๊ตฌ์กฐ๋ก ๊ทธ๋๋ก ์ฐ๋ํ์ฌ ๋ถํ์ํ ํ ์ด๋ธ ํฝ์ฐฝ ๋ฐ ์ปฌ๋ผ ์ถ๊ฐ๋ฅผ ์ฐจ๋จํฉ๋๋ค. - ์์คํ
๊ณตํต ์๋ ๋ณด์กด ๋ฐ ์ญ์ ์๊ณ์น๋ฅผ ๋
๋ฆฝ์ ์ผ๋ก ์ ์ดํ๊ธฐ ์ํ
tb_system_policy(์์คํ ๊ณตํต ์ ์ฑ ํ ์ด๋ธ) ์ ์ค. - ์ค์๊ฐ ๋ฐฐ๋ ๊ณต์ง ์ด๋ ฅ ๋ณด๊ด์ ์ํ
tb_banner_notice๋ฐ ์ ๊ธฐ ์๋์ญ์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋กํ๊ธฐ ์ํtb_auto_clean_log์ ์ค.
[2๋จ๊ณ] ๋ฐฑ์๋ RESTful API ๋ฐ WebSocket ํธ๋ค๋ฌ ๊ฐ๋ฐ
- REST API: ๊ฐ ๊ธฐ๋ฅ ๋ฐ ๊ณตํต ์ฝ๋ ๋ฐ์ดํฐ์ CRUD API Endpoint ๊ตฌ์ถ (Express Controller ์ฐ๋).
- WebSocket:
socket.js์ ์ ์ํ ํด๋ผ์ด์ธํธ ์ธ์ ์users๋ฉ๋ชจ๋ฆฌ ๋งต์ ๋ณด๊ด ๋ฐ ๊ด๋ฆฌ์๊ฐ ๊ฐ์ ํด์ฅ(forcedLogout) ์ด๋ฒคํธ๋ฅผ ํธ์ถํ๋ฉด ํด๋น ํด๋ผ์ด์ธํธ ์์ผ์ ์ ์์ ๋๊ณ ์ธ์ ์ ์ ๊ฑฐํ๋๋ก ๊ตฌํ.
[3๋จ๊ณ] ํ๋ก ํธ์๋ ์ด๋๋ฏผ ๋์๋ณด๋ UI ์ฐ๋
- ํ๋กํ ํ์ ๋์์ธ ์ปจ์ (Pretendard ์์ฒด, Forest Green ํ ๋ง ์์)์ CSS ๋ณ์๋ก ๊ทธ๋๋ก ๋ฐ์.
- ๋ชจ๋ฌ ๋ค์ด์ผ๋ก๊ทธ์ ํญ ๋ ๋๋ง์ ์ค์๊ฐ API ๋ฐ์ดํฐ ํต์ ๋ก์ง ๋ฐ์ธ๋ฉ.
2. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง ์ค๊ณ (ERD)
๊ธฐ์กด์ ์ด๋ฏธ ๋ณด์ ํ tb_project.category ๋ฐ tb_user."group" ๊ตฌ์กฐ๋ฅผ ํ์ฉํ ๊ด๊ณ ์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
3. ํ๋ฉด๋ณ ์ฐ๋ ํ ์ด๋ธ ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ธ ๋งคํ
๐ ํ๋ฉด 1: ์ข ํฉ ์ฉ๋ ๋ฐ ์ ์์ ํํฉ (Dashboard)
์ฃผ์ ๋ฐ์ดํฐ ํ๋ฆ ๋ฐ ํ์ฉ ํ ์ด๋ธ:
- ์ ์ฒด ์ฌ์ฉ ์ฉ๋ KPI & ํ์ฅ๋ณ ๊ฒ์ด์ง๋ฐ:
tb_projectํ ์ด๋ธ์ ํ๋ ์ฉ๋(storage_byte)๊ณผtb_dataํ ์ด๋ธ์ ์ค ๋์ ์ฉ๋(data_size) ํฉ์ฐ ๊ฒฐ๊ณผ ๋ฐ ํ์ผ ๊ฑด์๋ฅผCOUNT()ํ์ฌ ๋ ๋๋ง. - ์ค์๊ฐ ์ ์์ ์ธ์
๋ชฉ๋ก:
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ฒฝ์ ํ์ง ์๊ณ Node.js ๋ฉ์ธ ํ๋ก์ธ์ค(
socket.js)์ ๋ฉ๋ชจ๋ฆฌ ์ธ์ ํด์๋งต์์ ์ง์ ์ฐ๊ฒฐ ์ํ(ID, IP, ์์น ๊ฒฝ๋ก)๋ฅผ ์ถ์ถ. - ๋๊ธฐ ์ค์ธ ์์ถ์์ : Redis(BullMQ Queue) ๋๊ธฐ์ด API๋ฅผ ์กฐํํ์ฌ ๋ณด๋ฅ ์ค์ธ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ถ ๋ค์ด๋ก๋ ๊ฐ์ ํ์ .
๐๏ธ ํ๋ฉด 2: ํ๋ก์ ํธ ๊ด๋ฆฌ (Project Management)
์ฃผ์ ๋ฐ์ดํฐ ํ๋ฆ ๋ฐ ํ์ฉ ํ ์ด๋ธ:
- ์ข์ธก ํ๋ก์ ํธ ๊ทธ๋ฆฌ๋:
tb_projectํ ์ด๋ธ ์ ์ฒด ๋ฐ์ดํฐ์code_detail์ ์นดํ ๊ณ ๋ฆฌ ์ฝ๋ ํ๊ธ ๋ช ์นญ(TDC, GPD ๋ฑ)์tb_project.category์ธ๋ํค ๊ด๊ณ๋ฅผ ์กฐ์ธํ์ฌ ๋ ๋๋ง. - ์ฐ์ธก ์ฐธ์ฌ ๊ถํ ์ฌ์ฉ์ ๋ชฉ๋ก:
tb_permission$\bowtie$tb_user์กฐ์ธ์ ํตํด ํด๋น ํ์ฅ์ ๊ธฐ์๋ ์ฌ์ฉ์ ๋ฆฌ์คํธ์ ๋ฐ ๋ฑ๊ธ ์ธ๋ผ์ธ ์ ๋ ํธ ์ ๋ฐ์ดํธ. - ์ฌ์ฉ์ ๋ฐฐ์ ์ถ๊ฐ ๋ชจ๋ฌ:
tb_user์ ์ ์ฒด ์ฌ์ฉ์ ๋ฐ์ดํฐ์ ํ์ฌ ํ๋ก์ ํธ์ ์ํด ์์ง ์์ ์ ์ ์ฐจ์งํฉ ์ฐ์ฐ์ผ๋ก ๊ฐ์ฉ ์ ์ ๋ชฉ๋ก ๊ตฌ์ฑ.
๐ฅ ํ๋ฉด 4: ์ฌ์ฉ์ ๊ด๋ฆฌ (User Management)
์ฃผ์ ๋ฐ์ดํฐ ํ๋ฆ ๋ฐ ํ์ฉ ํ ์ด๋ธ:
- ์ข์ธก ๊ณ์ ๋ชฉ๋ก:
tb_userํ ์ด๋ธ ๋ฐcode_detail๊ถํ๊ทธ๋ฃน(๊ธฐ์กด"group"์ปฌ๋ผ ์ฌ์ฌ์ฉ) ๋งคํ ๋ ๋๋ง. - ์ฐ์ธก ์ฐธ์ฌ ํ๋ก์ ํธ ๋ชฉ๋ก:
tb_permission$\bowtie$tb_project์กฐ์ธ์ ํ์ฉํ์ฌ ์ ํ ์ ์ ๊ฐ ์์๋ ๋ชจ๋ ํ๋ก์ ํธ ID ๋ฐ ํ์ฅ๋ช ์ถ๋ ฅ.
๐ ํ๋ฉด 5: ๊ฐ์ฌ ๋ก๊ทธ ์กฐํ (Audit Logs)
์ฃผ์ ๋ฐ์ดํฐ ํ๋ฆ ๋ฐ ํ์ฉ ํ ์ด๋ธ:
- ์์คํ
๊ฐ์ฌ ์ด๋ ฅ ๋ชฉ๋ก:
ํ์ผ ์ญ์ /์ด๋/๋ค์ด๋ก๋ ์ด๋ฒคํธ๋ฅผ ์ ์ฌํ๋
tb_logํ ์ด๋ธ์ ํํฐ ๊ฒ์ ์ฟผ๋ฆฌ(์ฌ์ฉ์ ID, ์ก์ ํ์ )์ ์ฐ๋ํ์ฌ ๋ฆฌ์คํธ ๋ ๋๋ง.
โ๏ธ ํ๋ฉด 6: ์๋ ๋ณด์กด ๋ฐ ํ์ผ ์ญ์ ์ ์ฑ ์ค์ (Delete Policy)
์ฃผ์ ๋ฐ์ดํฐ ํ๋ฆ ๋ฐ ํ์ฉ ํ ์ด๋ธ:
- ์์คํ
๊ณตํต ์๋ ์ญ์ ์ ์ฑ
์ค์ ํผ:
ํ๋ก์ ํธ ๋จ์ ์ค์ ์ ํํผํ๊ณ , ์ ์ค๋
tb_system_policy์ ๋จ์ผ ๊ธ๋ก๋ฒ ๋ ์ฝ๋๋ฅผ ์ ์ด. - ์๋ ์ญ์ ์ ๊ธฐ ์คํ ์ด๋ ฅ:
์ ๊ธฐ ์ค์ผ์ค๋ฌ ๋ฐฐ์น ๊ตฌ๋ ์์ ๋ก๊ทธ ๊ธฐ๋ก์
tb_auto_clean_log์์ ๋ฆฌ์คํธ์ . ์ค์ ๊ฐ ์ ์ฅ ๋ฐ ๊ธฐ๋ก ์ ์ฌ ์ ํ๋ก์ ํธ ID ๋์'SYSTEM'๊ธฐ๋ก ์๋ณ์๋ฅผ ์ฌ์ฉ.
๐ ํ๋ฉด 7: ๊ณตํต ์ฝ๋ ๊ด๋ฆฌ (Common Code Management)
์ฃผ์ ๋ฐ์ดํฐ ํ๋ฆ ๋ฐ ํ์ฉ ํ ์ด๋ธ:
- ์๋จ ๋ง์คํฐ ๋๋ถ๋ฅ:
code_masterํ ์ด๋ธ CRUD. - ํ๋จ ์์ธ ์๋ถ๋ฅ:
code_detailํ ์ด๋ธ CRUD.- ๋๋ถ๋ฅ ์ ํ์ด ์์ ์ ์๋ถ๋ฅ ๋ฑ๋ก ํผ ์ง์ ์ฐจ๋จ ์ ํจ์ฑ ์ ์ด.
- ์๋ถ๋ฅ์
base_code์ปฌ๋ผ์main_code || '_' || sub_code์กฐํฉ์ผ๋ก ์๋ ๋๊ธฐํ. - ๋๋ถ๋ฅ ์ญ์ ์ ์ธ๋ํค
ON DELETE CASCADE๋ช ์ธ๋ฅผ ํตํ์ฌ ์๋ถ๋ฅ ๋ ์ฝ๋๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฐ์์ ์ผ๋ก ์๋ ์ฒญ์๋๋๋ก ์ค์ .
4. ํต์ฌ ๋ฐฑ์๋ CRUD API Endpoint ์ค๊ณ์
ํ๋ก ํธ์๋-๋ฐฑ์๋ ๊ฐ ํต์ ์ ์ํด ๊ตฌ์ฑ๋์ด์ผ ํ RESTful API ๋ฆฌ์คํธ์ ๋๋ค.
1. ํ๋ก์ ํธ ๊ด๋ฆฌ API (/api/admin/projects)
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| GET | / | ์ ์ฒด ํ๋ก์ ํธ ๋ฐ ์นดํ ๊ณ ๋ฆฌ ์ ๋ณด ์กฐํ |
| POST | / | ์ ๊ท ํ๋ก์ ํธ ๋ฑ๋ก |
| PUT | /:id | ํน์ ํ๋ก์ ํธ ๋ด์ฉ(์นดํ ๊ณ ๋ฆฌ category ๊ฐ, ์ฉ๋์ ํ, ํ์ฑํ) ๊ฐฑ์ |
| DELETE | /:id | ํ๋ก์ ํธ ์๊ตฌ ์ญ์ (์ฐธ์ฌ ๊ถํ ๋ฐ ๋ฉํ๋ฐ์ดํฐ ์๋ CASCADE) |
2. ํ๋ก์ ํธ ๊ถํ ๋ฐฐ์ API (/api/admin/permissions)
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| GET | /project/:projectId | ํน์ ํ์ฅ์ ์ฐธ์ฌ ์ค์ธ ์ ์ ๋ชฉ๋ก ์กฐํ |
| POST | /assign | ํ์ฅ์ ํน์ ์ฌ์ฉ์ ๊ถํ ์ ๊ท ๋ถ์ฌ (๋ค์ค ๋ฐฐ์ ) |
| PUT | /update | ๋ฐฐ์ ์ ์ ์ ๊ถํ ๋ฑ๊ธ(lev) ์์ |
| DELETE | /remove | ํ์ฅ ์ฐธ์ฌ ๊ถํ ๋ฐฐ์ ์ ์ธ (๋งคํ ํ ์ญ์ ) |
3. ์ค์๊ฐ ๋ฐฐ๋ ๊ณต์ง API (/api/admin/banners)
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| GET | / | ๋ฐฐ๋ ์ก์ถ ์ด๋ ฅ ์กฐํ (์ํ, ๋ ์ง๊ฒ์ ํํฐ ์ง์) |
| POST | / | ์ ๊ท ๋ฐฐ๋ ๊ณต์ง ์์ฑ ๋ฐ ๋ฑ๋ก |
| PUT | /stop/:id | ๊ณต์ง ์๋ ์ก์ถ ์ค์ง (์ํ๋ฅผ expired๋ก ๊ฐ์ ์ ๋ฐ์ดํธ) |
4. ์ฌ์ฉ์ ๊ด๋ฆฌ API (/api/admin/users)
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| GET | / | ์ ์ฒด ๊ณ์ ์ ๋ณด ๋ฐ ๊ถํ๊ทธ๋ฃน ์กฐํ |
| GET | /:id/permissions | ํด๋น ์ ์ ๊ฐ ์ฐธ์ฌ ๊ถํ์ ์ง๋ ํ๋ก์ ํธ ๋ชฉ๋ก ์กฐํ |
| POST | / | ์ ๊ท ์ฌ์ฉ์ ๊ณ์ ๋ฑ๋ก (ํจ์ค์๋ bcrypt ์ํธํ) |
| PUT | /:id | ์ฌ์ฉ์ ์ ๋ณด(๊ถํ ๊ทธ๋ฃน group ํฌํจ) ๋ฐ ์ฌ์ง ์ํ ๊ฐฑ์ |
| DELETE | /:id | ์ฌ์ฉ์ ๊ณ์ ์ญ์ (๊ถํ ์ ๋ณด ๋ฐ ์ค์ ์ฐ์ ์ญ์ ) |
5. ๊ณตํต ์ฝ๋ ๊ด๋ฆฌ API (/api/admin/common-codes)
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| GET | /masters | ๋๋ถ๋ฅ ๋ง์คํฐ ์ฝ๋ ๋ชฉ๋ก ์กฐํ |
| POST | /masters | ์ ๊ท ๋๋ถ๋ฅ ๋ฑ๋ก |
| PUT | /masters/:code | ๋๋ถ๋ฅ ์์ |
| DELETE | /masters/:code | ๋๋ถ๋ฅ ์ญ์ (ํ์ ์๋ถ๋ฅ ์๋ ์ฐ์ ์ญ์ ) |
| GET | /details/:mainCode | ์ ํ๋ ๋๋ถ๋ฅ์ ํด๋นํ๋ ์๋ถ๋ฅ ์ ๋ ฌ ์กฐํ |
| POST | /details | ์ ๊ท ์๋ถ๋ฅ ๋ฑ๋ก (base_code ์๋ ์ฐ์ฐ ์์ฑ) |
| PUT | /details/:mainCode/:subCode | ์๋ถ๋ฅ ์์ (๋ช ์นญ, ์ ๋ ฌ์์, ์ฌ์ฉ์ฌ๋ถ) |
| DELETE | /details/:mainCode/:subCode | ์๋ถ๋ฅ ์ญ์ |
6. ์์คํ
๊ณตํต ๋ณด์กด ์ ์ฑ
API (/api/admin/system-policy)
| ๋ฉ์๋ | ์๋ํฌ์ธํธ | ์ค๋ช |
|---|---|---|
| GET | / | ์์คํ ๊ธ๋ก๋ฒ ๋ณด์กด ์ ์ฑ ์กฐํ |
| POST | /update | ๊ธ๋ก๋ฒ ๋ณด์กด ์ ์ฑ ๊ฐ ๊ฐฑ์ ๋ฐ ์ ์ฅ |