diff --git a/README.md b/README.md index aae8ed4..7c8622f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ๐Ÿ“‹ ์ฃผ๊ฐ„์—…๋ฌด๋ณด๊ณ  ์‹œ์Šคํ…œ (Weekly Report) +# ๐Ÿ“‹ Weekly Report System SI ํ”„๋กœ์ ํŠธ ํŒ€์„ ์œ„ํ•œ ์ฃผ๊ฐ„์—…๋ฌด๋ณด๊ณ  ์ž‘์„ฑ ๋ฐ ์ทจํ•ฉ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. @@ -9,12 +9,15 @@ SI ํ”„๋กœ์ ํŠธ ํŒ€์„ ์œ„ํ•œ ์ฃผ๊ฐ„์—…๋ฌด๋ณด๊ณ  ์ž‘์„ฑ ๋ฐ ์ทจํ•ฉ ์‹œ์Šคํ…œ์ž… - Task ๋‹จ์œ„๋กœ ์ž‘์—… ๋‚ด์šฉ, ์‹œ๊ฐ„, ์™„๋ฃŒ ์—ฌ๋ถ€ ๊ด€๋ฆฌ - ์ด์Šˆ/๋ฆฌ์Šคํฌ, ํœด๊ฐ€์ผ์ •, ๊ธฐํƒ€์‚ฌํ•ญ ์ž…๋ ฅ - ์ž‘์„ฑ โ†’ ์ œ์ถœ โ†’ ์ทจํ•ฉ ์›Œํฌํ”Œ๋กœ์šฐ +- **์ด์ „ ์ฃผ ๊ณ„ํš โ†’ ์ด๋ฒˆ ์ฃผ ์‹ค์  ์ž๋™ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ** +- **๋ฏธ๋ž˜ ์ฃผ์ฐจ ์ž‘์„ฑ ์ฐจ๋‹จ** (URL ์ง์ ‘ ์ ‘๊ทผ ๋ฐฉ์ง€) -### ๐Ÿค– PMO AI ๋ฆฌ๋ทฐ -- OpenAI ๊ธฐ๋ฐ˜ ์ฃผ๊ฐ„๋ณด๊ณ  ์ž๋™ ํ”ผ๋“œ๋ฐฑ -- ์‹ค์ /๊ณ„ํš์˜ ๊ตฌ์ฒด์„ฑ ๊ฒ€ํ†  -- ์ผ์ • ๋ช…ํ™•์„ฑ ๋ฐ ์‹œ๊ฐ„ ์‚ฐ์ • ์ ์ ˆ์„ฑ ํ‰๊ฐ€ -- ๊ตฌ์ฒด์ ์ธ ์ž‘์„ฑ ์˜ˆ์‹œ์™€ ๊ฐœ์„  ๊ฐ€์ด๋“œ ์ œ๊ณต +### ๐Ÿค– AI ๊ธฐ๋Šฅ +- **AI ์ž๋™์ฑ„์šฐ๊ธฐ**: ํ…์ŠคํŠธ/์ด๋ฏธ์ง€ โ†’ ํ”„๋กœ์ ํŠธ๋ณ„ ์‹ค์ /๊ณ„ํš ์ž๋™ ๋ถ„๋ฅ˜ + - ๋“œ๋ž˜๊ทธ์•ค๋“œ๋กญ, ํŒŒ์ผ์„ ํƒ, **Ctrl+V ๋ถ™์—ฌ๋„ฃ๊ธฐ** ์ง€์› + - OpenAI GPT-4o ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ ์ž๋™ ๋งค์นญ +- **PMO AI ๋ฆฌ๋ทฐ**: ์ฃผ๊ฐ„๋ณด๊ณ  ํ’ˆ์งˆ ํ‰๊ฐ€ (3๋‹จ๊ณ„ ๋“ฑ๊ธ‰: ์šฐ์ˆ˜/์ ํ•ฉ/๋ฏธํก) +- **๊ด€๋ฆฌ์ž ์ผ๊ด„๋“ฑ๋ก**: ์—ฌ๋Ÿฌ ์ง์›์˜ ์ฃผ๊ฐ„๋ณด๊ณ  ์ผ๊ด„ ํŒŒ์‹ฑ ๋ฐ ๋“ฑ๋ก ### ๐Ÿ“Š ์ทจํ•ฉ ๋ณด๊ณ ์„œ - ์ฃผ์ฐจ๋ณ„ ์ „์ฒด ๋ณด๊ณ ์„œ ์ทจํ•ฉ @@ -22,6 +25,12 @@ SI ํ”„๋กœ์ ํŠธ ํŒ€์„ ์œ„ํ•œ ์ฃผ๊ฐ„์—…๋ฌด๋ณด๊ณ  ์ž‘์„ฑ ๋ฐ ์ทจํ•ฉ ์‹œ์Šคํ…œ์ž… - ์ธ์›๋ณ„ ํˆฌ์ž… ์‹œ๊ฐ„ ํ˜„ํ™ฉ - ์›๋ฌธ ๋ณด๊ธฐ ๊ธฐ๋Šฅ +### ๐Ÿ” ์ธ์ฆ ์‹œ์Šคํ…œ +- **DB ๊ธฐ๋ฐ˜ ์„ธ์…˜ ๊ด€๋ฆฌ** (Spring Session JDBC ๋ฐฉ์‹) +- ์„ธ์…˜ ํƒ€์ž„์•„์›ƒ: 10๋ถ„ (Sliding Expiration) +- ๋กœ๊ทธ์ธ ์ด๋ ฅ ๊ด€๋ฆฌ (IP, ์ ‘์†์‹œ๊ฐ„, ์„ธ์…˜์ƒํƒœ) +- ์„ธ์…˜ ์ƒํƒœ: ์ ‘์†์ค‘ / ํ™œ์„ฑ / ์„ธ์…˜๋งŒ๋ฃŒ / ๋กœ๊ทธ์•„์›ƒ + ### ๐Ÿ‘ฅ ์ง์›/ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ - ์ง์› ๋“ฑ๋ก ๋ฐ ๊ด€๋ฆฌ - ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ฐ ์ƒํƒœ ๊ด€๋ฆฌ @@ -34,8 +43,9 @@ SI ํ”„๋กœ์ ํŠธ ํŒ€์„ ์œ„ํ•œ ์ฃผ๊ฐ„์—…๋ฌด๋ณด๊ณ  ์ž‘์„ฑ ๋ฐ ์ทจํ•ฉ ์‹œ์Šคํ…œ์ž… | Frontend | Vue 3, Nuxt 3 | | Backend | Nitro (Nuxt Server) | | Database | PostgreSQL | -| AI | OpenAI GPT-4o-mini | +| AI | OpenAI GPT-4o / GPT-4o-mini | | UI | Bootstrap 5, Bootstrap Icons | +| Session | DB ๊ธฐ๋ฐ˜ ์„ธ์…˜ (wr_session ํ…Œ์ด๋ธ”) | ## ๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ @@ -44,9 +54,10 @@ weeklyreport/ โ”œโ”€โ”€ frontend/ # ํ”„๋ก ํŠธ์—”๋“œ ํŽ˜์ด์ง€ โ”‚ โ”œโ”€โ”€ components/ # ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ โ”‚ โ”œโ”€โ”€ composables/ # Vue Composables +โ”‚ โ”œโ”€โ”€ admin/ # ๊ด€๋ฆฌ์ž ์ „์šฉ +โ”‚ โ”‚ โ””โ”€โ”€ bulk-import.vue # AI ์ผ๊ด„ ๋“ฑ๋ก โ”‚ โ”œโ”€โ”€ report/ # ์ฃผ๊ฐ„๋ณด๊ณ  ๊ด€๋ จ โ”‚ โ”‚ โ”œโ”€โ”€ weekly/ # ๊ฐœ์ธ ์ฃผ๊ฐ„๋ณด๊ณ  -โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ bulk-import.vue # AI ์ผ๊ด„ ๋“ฑ๋ก โ”‚ โ”‚ โ””โ”€โ”€ summary/ # ์ทจํ•ฉ ๋ณด๊ณ ์„œ โ”‚ โ”œโ”€โ”€ employee/ # ์ง์› ๊ด€๋ฆฌ โ”‚ โ”œโ”€โ”€ project/ # ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ @@ -54,37 +65,21 @@ weeklyreport/ โ”œโ”€โ”€ backend/ โ”‚ โ”œโ”€โ”€ api/ # API ์—”๋“œํฌ์ธํŠธ โ”‚ โ”‚ โ”œโ”€โ”€ auth/ # ์ธ์ฆ +โ”‚ โ”‚ โ”œโ”€โ”€ admin/ # ๊ด€๋ฆฌ์ž API +โ”‚ โ”‚ โ”œโ”€โ”€ ai/ # AI API โ”‚ โ”‚ โ”œโ”€โ”€ employee/ # ์ง์› API โ”‚ โ”‚ โ”œโ”€โ”€ project/ # ํ”„๋กœ์ ํŠธ API โ”‚ โ”‚ โ””โ”€โ”€ report/ # ๋ณด๊ณ ์„œ API -โ”‚ โ””โ”€โ”€ utils/ # ์œ ํ‹ธ๋ฆฌํ‹ฐ (DB ๋“ฑ) +โ”‚ โ”œโ”€โ”€ utils/ # ์œ ํ‹ธ๋ฆฌํ‹ฐ +โ”‚ โ”‚ โ”œโ”€โ”€ db.ts # DB ์—ฐ๊ฒฐ +โ”‚ โ”‚ โ”œโ”€โ”€ session.ts # ์„ธ์…˜ ๊ด€๋ฆฌ +โ”‚ โ”‚ โ””โ”€โ”€ ip.ts # IP ์ถ”์ถœ +โ”‚ โ””โ”€โ”€ sql/ # DDL ์Šคํฌ๋ฆฝํŠธ +โ”œโ”€โ”€ claude_temp/ # Claude ์ž‘์—…์šฉ ์ž„์‹œ ํŒŒ์ผ โ”œโ”€โ”€ nuxt.config.ts # Nuxt ์„ค์ • โ””โ”€โ”€ package.json ``` -## ๐Ÿ”— ๋ฉ”๋‰ด ๊ตฌ์กฐ - -| ๋ฉ”๋‰ด | ๊ฒฝ๋กœ | ์„ค๋ช… | ๊ถŒํ•œ | -|------|------|------|------| -| ๋กœ๊ทธ์ธ | `/login` | ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ | ์ „์ฒด | -| ํ™ˆ | `/` | ๋Œ€์‹œ๋ณด๋“œ | ๋กœ๊ทธ์ธ | -| **์ฃผ๊ฐ„๋ณด๊ณ ** | | | | -| โ”œ ๋ชฉ๋ก | `/report/weekly` | ์ฃผ๊ฐ„๋ณด๊ณ  ๋ชฉ๋ก | ๋กœ๊ทธ์ธ | -| โ”œ ์ž‘์„ฑ | `/report/weekly/write` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ž‘์„ฑ | ๋กœ๊ทธ์ธ | -| โ”œ ์ผ๊ด„์ž‘์„ฑ | `/report/weekly/bulk-import` | AI ๊ธฐ๋ฐ˜ ์ผ๊ด„ ๋“ฑ๋ก | ๋กœ๊ทธ์ธ | -| โ”œ ์ƒ์„ธ | `/report/weekly/[id]` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ƒ์„ธ๋ณด๊ธฐ | ๋กœ๊ทธ์ธ | -| โ”” ์ทจํ•ฉํ˜„ํ™ฉ | `/report/weekly/aggregate` | ์ฃผ์ฐจ๋ณ„ ์ทจํ•ฉ ํ˜„ํ™ฉ | ๋กœ๊ทธ์ธ | -| **์ทจํ•ฉ๋ณด๊ณ ์„œ** | | | | -| โ”œ ๋ชฉ๋ก | `/report/summary` | ์ทจํ•ฉ ๋ณด๊ณ ์„œ ๋ชฉ๋ก | ๊ด€๋ฆฌ์ž | -| โ”” ์ƒ์„ธ | `/report/summary/[id]` | ์ทจํ•ฉ ๋ณด๊ณ ์„œ ์ƒ์„ธ | ๊ด€๋ฆฌ์ž | -| **๊ด€๋ฆฌ** | | | | -| โ”œ ์ง์› ๋ชฉ๋ก | `/employee` | ์ง์› ๊ด€๋ฆฌ | ๊ด€๋ฆฌ์ž | -| โ”œ ์ง์› ์ƒ์„ธ | `/employee/[id]` | ์ง์› ์ •๋ณด ์ƒ์„ธ | ๊ด€๋ฆฌ์ž | -| โ”œ ํ”„๋กœ์ ํŠธ ๋ชฉ๋ก | `/project` | ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ | ๊ด€๋ฆฌ์ž | -| โ”” ํ”„๋กœ์ ํŠธ ์ƒ์„ธ | `/project/[id]` | ํ”„๋กœ์ ํŠธ ์ •๋ณด ์ƒ์„ธ | ๊ด€๋ฆฌ์ž | -| **๋งˆ์ดํŽ˜์ด์ง€** | `/mypage` | ๋‚ด ์ •๋ณด | ๋กœ๊ทธ์ธ | -| **ํ”ผ๋“œ๋ฐฑ** | `/feedback` | ํ”ผ๋“œ๋ฐฑ | ๋กœ๊ทธ์ธ | - ## ๐Ÿ—„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ ### ์ฃผ์š” ํ…Œ์ด๋ธ” @@ -96,6 +91,41 @@ weeklyreport/ | `wr_weekly_report` | ์ฃผ๊ฐ„๋ณด๊ณ  ๋งˆ์Šคํ„ฐ | | `wr_weekly_report_task` | ์ฃผ๊ฐ„๋ณด๊ณ  Task (์‹ค์ /๊ณ„ํš) | | `wr_aggregated_report_summary` | ์ทจํ•ฉ ๋ณด๊ณ ์„œ | +| `wr_session` | DB ์„ธ์…˜ (์ธ์ฆ) | +| `wr_login_history` | ๋กœ๊ทธ์ธ ์ด๋ ฅ | + +### ์„ธ์…˜ ํ…Œ์ด๋ธ” (wr_session) + +```sql +CREATE TABLE wr_session ( + session_id VARCHAR(64) PRIMARY KEY, -- ๋žœ๋ค ํ† ํฐ (64์ž hex) + employee_id INTEGER NOT NULL, + login_history_id INTEGER, + created_at TIMESTAMP DEFAULT NOW(), + last_access_at TIMESTAMP DEFAULT NOW(), + expires_at TIMESTAMP NOT NULL, -- 10๋ถ„ ํ›„ ๋งŒ๋ฃŒ + login_ip VARCHAR(45), + user_agent TEXT +); +``` + +## ๐Ÿ”— ๋ฉ”๋‰ด ๊ตฌ์กฐ + +| ๋ฉ”๋‰ด | ๊ฒฝ๋กœ | ์„ค๋ช… | ๊ถŒํ•œ | +|------|------|------|------| +| ๋กœ๊ทธ์ธ | `/login` | ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ | ์ „์ฒด | +| ๋Œ€์‹œ๋ณด๋“œ | `/` | ๋Œ€์‹œ๋ณด๋“œ | ๋กœ๊ทธ์ธ | +| **์ฃผ๊ฐ„๋ณด๊ณ ** | | | | +| โ”œ ๋ชฉ๋ก | `/report/weekly` | ์ฃผ๊ฐ„๋ณด๊ณ  ๋ชฉ๋ก | ๋กœ๊ทธ์ธ | +| โ”œ ์ž‘์„ฑ | `/report/weekly/write` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ž‘์„ฑ | ๋กœ๊ทธ์ธ | +| โ”” ์ƒ์„ธ/์ˆ˜์ • | `/report/weekly/[id]` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ƒ์„ธ๋ณด๊ธฐ/์ˆ˜์ • | ๋กœ๊ทธ์ธ | +| **์ทจํ•ฉ๋ณด๊ณ ์„œ** | `/report/summary` | ์ทจํ•ฉ ๋ณด๊ณ ์„œ | ๋กœ๊ทธ์ธ | +| **๊ด€๋ฆฌ์ž** | | | ๊ด€๋ฆฌ์ž | +| โ”œ ์ผ๊ด„๋“ฑ๋ก | `/admin/bulk-import` | AI ๊ธฐ๋ฐ˜ ์ผ๊ด„ ๋“ฑ๋ก | ๊ด€๋ฆฌ์ž | +| โ”œ ์ง์›๊ด€๋ฆฌ | `/employee` | ์ง์› ๊ด€๋ฆฌ | ๊ด€๋ฆฌ์ž | +| โ”” ํ”„๋กœ์ ํŠธ๊ด€๋ฆฌ | `/project` | ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ | ๊ด€๋ฆฌ์ž | +| **๋งˆ์ดํŽ˜์ด์ง€** | `/mypage` | ๋‚ด ์ •๋ณด, ๋กœ๊ทธ์ธ ์ด๋ ฅ | ๋กœ๊ทธ์ธ | +| **ํ”ผ๋“œ๋ฐฑ** | `/feedback` | ๊ฐœ์„ ์˜๊ฒฌ | ๋กœ๊ทธ์ธ | ## ๐Ÿš€ ์„ค์น˜ ๋ฐ ์‹คํ–‰ @@ -106,7 +136,11 @@ weeklyreport/ ### ํ™˜๊ฒฝ ๋ณ€์ˆ˜ (.env) ```env -DATABASE_URL=postgresql://user:pass@host:port/weeklyreport +DB_HOST=localhost +DB_PORT=5432 +DB_NAME=weeklyreport +DB_USER=weeklyreport +DB_PASSWORD=xxx OPENAI_API_KEY=sk-xxx ``` @@ -127,51 +161,139 @@ npm run build npm run preview ``` +### Docker ๋นŒ๋“œ +```bash +docker build -t weeklyreport:latest . +``` + ## ๐Ÿ“ก ์ฃผ์š” API ### ์ธ์ฆ | Method | Endpoint | ์„ค๋ช… | |--------|----------|------| -| POST | `/api/auth/login` | ๋กœ๊ทธ์ธ | +| POST | `/api/auth/login` | ์ด๋ฉ”์ผ+์ด๋ฆ„ ๋กœ๊ทธ์ธ | +| POST | `/api/auth/select-user` | ์ตœ๊ทผ ์‚ฌ์šฉ์ž ์„ ํƒ ๋กœ๊ทธ์ธ | | POST | `/api/auth/logout` | ๋กœ๊ทธ์•„์›ƒ | -| GET | `/api/auth/me` | ํ˜„์žฌ ์‚ฌ์šฉ์ž ์ •๋ณด | +| GET | `/api/auth/current-user` | ํ˜„์žฌ ์‚ฌ์šฉ์ž (์„ธ์…˜ ๊ฐฑ์‹ ) | +| GET | `/api/auth/me` | ์‚ฌ์šฉ์ž ์ƒ์„ธ ์ •๋ณด | +| GET | `/api/auth/login-history` | ๋กœ๊ทธ์ธ ์ด๋ ฅ | + +### AI +| Method | Endpoint | ์„ค๋ช… | +|--------|----------|------| +| POST | `/api/ai/parse-my-report` | ํ…์ŠคํŠธ โ†’ ์ฃผ๊ฐ„๋ณด๊ณ  ํŒŒ์‹ฑ | +| POST | `/api/ai/parse-my-report-image` | ์ด๋ฏธ์ง€ โ†’ ์ฃผ๊ฐ„๋ณด๊ณ  ํŒŒ์‹ฑ | +| POST | `/api/admin/parse-report` | ๊ด€๋ฆฌ์ž ์ผ๊ด„ ํ…์ŠคํŠธ ํŒŒ์‹ฑ | +| POST | `/api/admin/parse-image` | ๊ด€๋ฆฌ์ž ์ผ๊ด„ ์ด๋ฏธ์ง€ ํŒŒ์‹ฑ | +| POST | `/api/admin/bulk-register` | ์ผ๊ด„ ๋“ฑ๋ก | ### ์ฃผ๊ฐ„๋ณด๊ณ  | Method | Endpoint | ์„ค๋ช… | |--------|----------|------| | GET | `/api/report/weekly/list` | ์ฃผ๊ฐ„๋ณด๊ณ  ๋ชฉ๋ก | -| POST | `/api/report/weekly/save` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ €์žฅ | -| GET | `/api/report/weekly/[id]/detail` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ƒ์„ธ | +| POST | `/api/report/weekly/create` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ƒ์„ฑ | +| PUT | `/api/report/weekly/[id]/update` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ˆ˜์ • | +| POST | `/api/report/weekly/[id]/submit` | ์ฃผ๊ฐ„๋ณด๊ณ  ์ œ์ถœ | +| DELETE | `/api/report/weekly/[id]/delete` | ์ฃผ๊ฐ„๋ณด๊ณ  ์‚ญ์ œ | | POST | `/api/report/review` | PMO AI ๋ฆฌ๋ทฐ ์š”์ฒญ | -### ์ทจํ•ฉ ๋ณด๊ณ ์„œ -| Method | Endpoint | ์„ค๋ช… | -|--------|----------|------| -| GET | `/api/report/summary/weekly-list` | ์ฃผ์ฐจ๋ณ„ ์ทจํ•ฉ ๋ชฉ๋ก | -| POST | `/api/report/summary/aggregate` | ์ทจํ•ฉ ์‹คํ–‰ | -| GET | `/api/report/summary/week/detail` | ์ฃผ์ฐจ๋ณ„ ์ƒ์„ธ | +--- -### ์ง์›/ํ”„๋กœ์ ํŠธ -| Method | Endpoint | ์„ค๋ช… | -|--------|----------|------| -| GET | `/api/employee/list` | ์ง์› ๋ชฉ๋ก | -| POST | `/api/employee/create` | ์ง์› ๋“ฑ๋ก | -| GET | `/api/project/list` | ํ”„๋กœ์ ํŠธ ๋ชฉ๋ก | -| POST | `/api/project/create` | ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ | +## ๐Ÿค Claude ํ˜‘์—… ๊ฐ€์ด๋“œ -## ๐Ÿ“ธ ํ™”๋ฉด ๊ตฌ์„ฑ +์ด ํ”„๋กœ์ ํŠธ๋Š” Claude AI์™€ ํ˜‘์—…ํ•˜์—ฌ ๊ฐœ๋ฐœ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์‚ฌํ•ญ์„ ์ˆ™์ง€ํ•ด์ฃผ์„ธ์š”. -### ์ฃผ๊ฐ„๋ณด๊ณ  ์ž‘์„ฑ -- ํ”„๋กœ์ ํŠธ ์„ ํƒ ํ›„ Task ์ถ”๊ฐ€ -- ๊ธˆ์ฃผ ์‹ค์ : ์ž‘์—…๋‚ด์šฉ, ์‹œ๊ฐ„, ์™„๋ฃŒ์—ฌ๋ถ€ -- ์ฐจ์ฃผ ๊ณ„ํš: ๊ณ„ํš๋‚ด์šฉ, ์˜ˆ์ƒ์‹œ๊ฐ„ -- PMO AI ๋ฆฌ๋ทฐ ์ž๋™ ์ƒ์„ฑ +### โš ๏ธ ํ•„์ˆ˜ ์ค€์ˆ˜์‚ฌํ•ญ -### ์ทจํ•ฉ ๋ณด๊ณ ์„œ -- ์ฃผ์ฐจ๋ณ„ ํ”„๋กœ์ ํŠธ ํ˜„ํ™ฉ -- AI ๊ธฐ๋ฐ˜ ์‹ค์ /๊ณ„ํš ์š”์•ฝ -- ์ธ์›๋ณ„ ํˆฌ์ž… ์‹œ๊ฐ„ ํ…Œ์ด๋ธ” -- ์›๋ฌธ ๋ณด๊ธฐ (๋ชจ๋‹ฌ) +#### 1. Git ์ปค๋ฐ‹ ๊ทœ์น™ +``` +โŒ Claude๊ฐ€ ์ž„์˜๋กœ ์ปค๋ฐ‹/ํ‘ธ์‹œํ•˜์ง€ ์•Š์Œ +โœ… ์‚ฌ์šฉ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์š”์ฒญํ•  ๋•Œ๋งŒ ์ปค๋ฐ‹ +``` + +#### 2. ์ž„์‹œ ํŒŒ์ผ ๊ด€๋ฆฌ +``` +ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ์ž„์‹œ ํŒŒ์ผ ์ƒ์„ฑ ๊ธˆ์ง€ +๋ชจ๋“  ์ž„์‹œ ํŒŒ์ผ์€ claude_temp/ ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅ + - ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์Šคํฌ๋ฆฝํŠธ + - ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ + - ๋ฐฐ์น˜ ํŒŒ์ผ ๋“ฑ +``` + +#### 3. ํ•จ์ˆ˜๋ช… ์ถฉ๋Œ ์ฃผ์˜ +```typescript +// โŒ h3 ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์ถฉ๋Œ +export function getSession() { } + +// โœ… ์ ‘๋‘์–ด๋กœ ๊ตฌ๋ถ„ +export function getDbSession() { } +``` + +Nuxt/h3 ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ž๋™ importํ•˜๋Š” ํ•จ์ˆ˜๋ช… ์ฃผ์˜: +- `getSession` โ†’ `getDbSession` +- `getQuery` โ†’ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ (h3 ๊ฒƒ ์‚ฌ์šฉ) +- `getCookie` โ†’ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ (h3 ๊ฒƒ ์‚ฌ์šฉ) + +#### 4. ํ•œ๊ธ€ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ +```bash +# Windows CMD์—์„œ ํ•œ๊ธ€ ๊นจ์ง ๋ฐœ์ƒ +# ๋ฐฐ์น˜ ํŒŒ์ผ ์‚ฌ์šฉ ์‹œ ์˜๋ฌธ ๋ฉ”์‹œ์ง€ ๊ถŒ์žฅ +git commit -m "feat: add session management" +``` + +### ๐Ÿ“‹ ๊ฐœ๋ฐœ ์ปจ๋ฒค์…˜ + +#### API ์‘๋‹ต ํ˜•์‹ +```typescript +// ์„ฑ๊ณต +return { success: true, data: ... } + +// ๋ชฉ๋ก +return { reports: [...], total: 100 } + +// ์—๋Ÿฌ +throw createError({ statusCode: 400, message: '์—๋Ÿฌ ๋ฉ”์‹œ์ง€' }) +``` + +#### ์ธ์ฆ ์ฒ˜๋ฆฌ +```typescript +import { requireAuth, getAuthenticatedUserId } from '../../utils/session' + +// ํ•„์ˆ˜ ์ธ์ฆ (๋ฏธ์ธ์ฆ ์‹œ 401 ์—๋Ÿฌ) +const userId = await requireAuth(event) + +// ์„ ํƒ ์ธ์ฆ (๋ฏธ์ธ์ฆ ์‹œ null) +const userId = await getAuthenticatedUserId(event) +``` + +#### ๋‚ ์งœ/์ฃผ์ฐจ ๊ณ„์‚ฐ +```typescript +// useWeekCalc composable ์‚ฌ์šฉ +const { getWeekInfo, getWeekDates, getActualCurrentWeekInfo } = useWeekCalc() + +// ISO 8601 ์ฃผ์ฐจ ๊ธฐ์ค€ (์›”์š”์ผ ์‹œ์ž‘) +``` + +### ๐Ÿ”ง ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ์ด์Šˆ + +| ์ด์Šˆ | ์›์ธ | ํ•ด๊ฒฐ | +|------|------|------| +| `npm ci` ์‹คํŒจ | package-lock.json ๋ถˆ์ผ์น˜ | `npm install` ํ›„ lock ํŒŒ์ผ ์ปค๋ฐ‹ | +| ์„ธ์…˜ ๋งŒ๋ฃŒ ์•ˆ๋จ | expires_at ๋น„๊ต ๋ˆ„๋ฝ | `expires_at > NOW()` ์กฐ๊ฑด ํ™•์ธ | +| ๋ฏธ๋ž˜ ์ฃผ์ฐจ ์ ‘๊ทผ | URL ์ง์ ‘ ์ž…๋ ฅ | onMounted์—์„œ ์ฃผ์ฐจ ๊ฒ€์ฆ | +| ํ•จ์ˆ˜๋ช… ์ถฉ๋Œ ๊ฒฝ๊ณ  | h3 auto-import | ํ•จ์ˆ˜๋ช… ๋ณ€๊ฒฝ (์ ‘๋‘์–ด ์ถ”๊ฐ€) | + +### ๐Ÿ“‚ ์ฃผ์š” ํŒŒ์ผ ์œ„์น˜ + +| ๊ธฐ๋Šฅ | ํŒŒ์ผ | +|------|------| +| ์„ธ์…˜ ๊ด€๋ฆฌ | `backend/utils/session.ts` | +| DB ์—ฐ๊ฒฐ | `backend/utils/db.ts` | +| ์ฃผ์ฐจ ๊ณ„์‚ฐ | `frontend/composables/useWeekCalc.ts` | +| ์ธ์ฆ ์ƒํƒœ | `frontend/composables/useAuth.ts` | +| ํ—ค๋” ์ปดํฌ๋„ŒํŠธ | `frontend/components/AppHeader.vue` | + +--- ## ๐Ÿ“„ ๋ผ์ด์„ ์Šค diff --git a/claude_temp/git-push.bat b/claude_temp/git-push.bat new file mode 100644 index 0000000..2de1d91 --- /dev/null +++ b/claude_temp/git-push.bat @@ -0,0 +1,5 @@ +@echo off +cd /d D:\devs\osolit-research\workspace\weeklyreport +git add frontend/report/weekly/write.vue +git commit -m "feat: block future week access in write page" +git push