Skip to content

Commit 73ef029

Browse files
committed
๐Ÿ“ฆ chore: copilot ์ฝ”๋“œ๋ฆฌ๋ทฐ instruction ์ƒ์„ฑ
1 parent fa5a9c0 commit 73ef029

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# Denamu Project - GitHub Copilot Instructions
2+
3+
## ํ”„๋กœ์ ํŠธ ๊ฐœ์š”
4+
5+
**๋ฐ๋‚˜๋ฌด(Denamu)** - RSS ๊ธฐ๋ฐ˜ ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ ํ๋ ˆ์ด์…˜ ํ”Œ๋žซํผ
6+
7+
๊ฐœ๋ฐœ์ž๋“ค์ด ๋ถ„์‚ฐ๋œ ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ ์ฝ˜ํ…์ธ ๋ฅผ ํ•œ ๊ณณ์—์„œ ํŽธ๋ฆฌํ•˜๊ฒŒ ๊ตฌ๋…ํ•˜๊ณ , ์‹ค์‹œ๊ฐ„ ํŠธ๋ Œ๋“œ๋ฅผ ํ™•์ธํ•˜๋ฉฐ, ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ํ†ตํ•ด ์†Œํ†ตํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
8+
9+
## ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
10+
11+
### `/server`
12+
13+
- **NestJS ๊ธฐ๋ฐ˜ WAS(Web Application Server)**
14+
- TypeORM์„ ์‚ฌ์šฉํ•œ MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™
15+
- Redis๋ฅผ ํ™œ์šฉํ•œ ์บ์‹ฑ ๋ฐ ์„ธ์…˜ ๊ด€๋ฆฌ
16+
- Socket.IO ๊ธฐ๋ฐ˜ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ๊ธฐ๋Šฅ
17+
- JWT ์ธ์ฆ ๋ฐ OAuth(Google, GitHub) ์†Œ์…œ ๋กœ๊ทธ์ธ
18+
- Prometheus๋ฅผ ํ†ตํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง
19+
- Winston์„ ํ™œ์šฉํ•œ ๊ตฌ์กฐํ™”๋œ ๋กœ๊น…
20+
21+
### `/feed-crawler`
22+
23+
- **RSS ํ”ผ๋“œ ํฌ๋กค๋Ÿฌ ์„œ๋น„์Šค**
24+
- ๋“ฑ๋ก๋œ RSS ํ”ผ๋“œ๋ฅผ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ˆ˜์ง‘
25+
- AI(Anthropic Claude) ๊ธฐ๋ฐ˜ ์ฝ˜ํ…์ธ  ๋ถ„์„ ๋ฐ ํƒœ๊ทธ ์ƒ์„ฑ
26+
- MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ˆ˜์ง‘ ๋ฐ์ดํ„ฐ ์ €์žฅ
27+
- ์˜์กด์„ฑ ์ฃผ์ž…(tsyringe) ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜
28+
29+
### `/client`
30+
31+
- **React + TypeScript ๊ธฐ๋ฐ˜ ํ”„๋ก ํŠธ์—”๋“œ**
32+
- Vite ๋นŒ๋“œ ๋„๊ตฌ ์‚ฌ์šฉ
33+
- TanStack Query๋ฅผ ํ†ตํ•œ ์„œ๋ฒ„ ์ƒํƒœ ๊ด€๋ฆฌ
34+
- Zustand๋ฅผ ํ†ตํ•œ ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ ๊ด€๋ฆฌ
35+
- Radix UI + Tailwind CSS ๊ธฐ๋ฐ˜ ์ปดํฌ๋„ŒํŠธ ์‹œ์Šคํ…œ
36+
- Socket.IO Client๋กœ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์—ฐ๋™
37+
38+
### `/docker-compose`
39+
40+
- **์ธํ”„๋ผ ๊ตฌ์„ฑ ํŒŒ์ผ**
41+
- ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ (docker-compose.local.yml)
42+
- ๊ฐœ๋ฐœ ์„œ๋ฒ„ ํ™˜๊ฒฝ (docker-compose.dev.yml)
43+
- ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ (docker-compose.prod.yml)
44+
- ์ธํ”„๋ผ ์„œ๋น„์Šค (MySQL, Redis, Prometheus, Grafana)
45+
46+
---
47+
48+
## ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๊ฐ€์ด๋“œ๋ผ์ธ
49+
50+
### ๋ฆฌ๋ทฐ ์–ธ์–ด
51+
52+
์ฝ”๋“œ ๋ฆฌ๋ทฐ์‹œ์—๋Š” ๋ฐ˜๋“œ์‹œ ํ•œ๊ตญ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
53+
54+
### ๋ฆฌ๋ทฐ ์šฐ์„ ์ˆœ์œ„ (Pn ๋ฃฐ ์ ์šฉ)
55+
56+
์ฝ”๋“œ ๋ฆฌ๋ทฐ ์‹œ ์•„๋ž˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ฐ˜๋“œ์‹œ ๋ช…์‹œํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜์„ธ์š”:
57+
58+
- **P1 (์ตœ์šฐ์„ )**: ์ฆ‰๊ฐ ์ˆ˜์ •์ด ํ•„์š”ํ•œ ์ค‘๋Œ€ํ•œ ๋ฌธ์ œ (๋ณด์•ˆ ์ทจ์•ฝ์ , ํฌ๋ฆฌํ‹ฐ์ปฌ ๋ฒ„๊ทธ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์˜ค๋ฅ˜)
59+
- **P2 (๋งค์šฐ ์ค‘์š”)**: ๋ฐ˜๋“œ์‹œ ๋ฐ˜์˜ํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ ํ’ˆ์งˆ/๊ธฐ๋Šฅ ์ด์Šˆ
60+
- **P3 (์ค‘์š”)**: ์ž ์žฌ์  ๋ฒ„๊ทธ ์œ„ํ—˜์ด๋‚˜ ์ค‘์š”ํ•œ ๊ฐœ์„  ์‚ฌํ•ญ
61+
- **P4 (๊ฐ€๋ฒผ์šด ์ œ์•ˆ)**: ๊ฐ€๋…์„ฑ/์œ ์ง€๋ณด์ˆ˜์„ฑ ๊ฐœ์„  ๊ถŒ์žฅ ์‚ฌํ•ญ
62+
- **P5 (์งˆ๋ฌธ ๋ฐ ์ถ”์ฒœ)**: ์„ ํƒ์  ์ œ์•ˆ ๋ฐ ์งˆ๋ฌธ
63+
64+
### ๋ฐฑ์—”๋“œ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์ค‘์  ์‚ฌํ•ญ
65+
66+
#### 1. ๋ณด์•ˆ ๋ฐ ์ž ์žฌ ๋ฒ„๊ทธ ์œ„ํ—˜ (P1-P2)
67+
68+
- **SQL Injection**: TypeORM ์ฟผ๋ฆฌ ๋นŒ๋” ์‚ฌ์šฉ ์‹œ raw query ๊ฒ€์ฆ
69+
- **์ธ์ฆ/์ธ๊ฐ€**: JWT ํ† ํฐ ๊ฒ€์ฆ, refresh token ๊ฐฑ์‹  ๋กœ์ง ํ™•์ธ
70+
- **์ž…๋ ฅ ๊ฒ€์ฆ**: class-validator DTO ๊ฒ€์ฆ ๋ˆ„๋ฝ ์—ฌ๋ถ€
71+
- **XSS ๋ฐฉ์ง€**: ์‚ฌ์šฉ์ž ์ž…๋ ฅ sanitization ํ™•์ธ
72+
- **Race Condition**: Redis ๋™์‹œ์„ฑ ์ œ์–ด (๋ฝ, ํŠธ๋žœ์žญ์…˜)
73+
- **์—๋Ÿฌ ํ•ธ๋“ค๋ง**: try-catch ๋ˆ„๋ฝ, ์ ์ ˆํ•œ HTTP ์ƒํƒœ ์ฝ”๋“œ ๋ฐ˜ํ™˜
74+
- **ํŒŒ์ผ ์—…๋กœ๋“œ**: ํŒŒ์ผ ํฌ๊ธฐ ์ œํ•œ, MIME ํƒ€์ž… ๊ฒ€์ฆ
75+
- **๋ฆฌ์†Œ์Šค ๋ˆ„์ˆ˜**: DB ์ปค๋„ฅ์…˜, ํŒŒ์ผ ํ•ธ๋“ค๋Ÿฌ ์ •๋ฆฌ ํ™•์ธ
76+
77+
#### 2. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ฒ€์ฆ (P1-P3)
78+
79+
- **๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ**: ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ์ ์ ˆ์„ฑ
80+
- **์ƒํƒœ ์ „์ด**: ์—”ํ‹ฐํ‹ฐ ์ƒํƒœ ๋ณ€ํ™” ๋กœ์ง์˜ ์ •ํ•ฉ์„ฑ
81+
- **์—ฃ์ง€ ์ผ€์ด์Šค**: ๊ฒฝ๊ณ„๊ฐ’, null/undefined ์ฒ˜๋ฆฌ
82+
- **์ค‘๋ณต ๋ฐฉ์ง€**: ์กฐํšŒ์ˆ˜ ์ฆ๊ฐ€, ์ข‹์•„์š” ๋“ฑ ์ค‘๋ณต ๋ฐฉ์ง€ ๋กœ์ง
83+
- **๋„๋ฉ”์ธ ๊ทœ์น™**: ๋น„์ฆˆ๋‹ˆ์Šค ์ œ์•ฝ ์กฐ๊ฑด ์ค€์ˆ˜ ์—ฌ๋ถ€
84+
85+
#### 3. ์„ฑ๋Šฅ ์ตœ์ ํ™” (P2-P4)
86+
87+
- **N+1 ์ฟผ๋ฆฌ**: TypeORM relations eager loading ํ™•์ธ
88+
- **์ธ๋ฑ์Šค ํ™œ์šฉ**: WHERE, JOIN ์กฐ๊ฑด์— ์ธ๋ฑ์Šค ์‚ฌ์šฉ
89+
- **์บ์‹ฑ ์ „๋žต**: Redis ์บ์‹œ TTL ์ ์ •์„ฑ, ์บ์‹œ ๋ฌดํšจํ™” ๋กœ์ง
90+
- **ํŽ˜์ด์ง€๋„ค์ด์…˜**: offset ๋Œ€์‹  cursor ๊ธฐ๋ฐ˜ ํŽ˜์ด์ง€๋„ค์ด์…˜ ๊ณ ๋ ค
91+
- **๋ถˆํ•„์š”ํ•œ ์ฟผ๋ฆฌ**: ์ค‘๋ณต DB ํ˜ธ์ถœ ์ œ๊ฑฐ
92+
- **๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ**: ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ
93+
94+
#### 4. ์ฝ”๋“œ ํ’ˆ์งˆ (P3-P5)
95+
96+
- **SOLID ์›์น™**: ๋‹จ์ผ ์ฑ…์ž„, ์˜์กด์„ฑ ์—ญ์ „ ์ค€์ˆ˜
97+
- **์ค‘๋ณต ์ œ๊ฑฐ**: DRY ์›์น™, ๊ณตํ†ต ๋กœ์ง ์ถ”์ถœ
98+
- **๋ช…๋ช… ๊ทœ์น™**: ๋ช…ํ™•ํ•˜๊ณ  ์ผ๊ด€๋œ ๋ณ€์ˆ˜/ํ•จ์ˆ˜๋ช…
99+
- **ํƒ€์ž… ์•ˆ์ •์„ฑ**: any ํƒ€์ž… ๋‚จ์šฉ ๋ฐฉ์ง€, ์ ์ ˆํ•œ ํƒ€์ž… ์ •์˜
100+
- **ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€**: ์ฃผ์š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋‹จ์œ„ ํ…Œ์ŠคํŠธ
101+
102+
---
103+
104+
## ๊ธฐ์ˆ  ์Šคํƒ๋ณ„ ๊ถŒ์žฅ ์‚ฌํ•ญ
105+
106+
### NestJS (Server)
107+
108+
- ๋ชจ๋“ˆํ™”๋œ ๊ตฌ์กฐ ์œ ์ง€ (๊ฐ ๊ธฐ๋Šฅ๋ณ„ Module, Controller, Service ๋ถ„๋ฆฌ)
109+
- Dependency Injection ์ ๊ทน ํ™œ์šฉ
110+
- Global Exception Filter๋กœ ์ผ๊ด€๋œ ์—๋Ÿฌ ์‘๋‹ต
111+
- Pipe๋ฅผ ํ†ตํ•œ ์ž…๋ ฅ ๊ฒ€์ฆ ๋ฐ ๋ณ€ํ™˜
112+
- Interceptor๋กœ ๋กœ๊น…, ์‘๋‹ต ๋ณ€ํ™˜ ์ฒ˜๋ฆฌ
113+
- Guard๋ฅผ ํ†ตํ•œ ์ธ์ฆ/์ธ๊ฐ€ ๊ตฌํ˜„
114+
115+
### TypeScript ๊ณตํ†ต
116+
117+
- strict ๋ชจ๋“œ ํ™œ์„ฑํ™” ์œ ์ง€
118+
- enum ๋Œ€์‹  union type ์‚ฌ์šฉ ๊ณ ๋ ค
119+
- ํƒ€์ž… ์ถ”๋ก  ํ™œ์šฉ, ๋ถˆํ•„์š”ํ•œ ํƒ€์ž… ๋ช…์‹œ ์ง€์–‘
120+
- ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž… ์ ๊ทน ํ™œ์šฉ (Pick, Omit, Partial ๋“ฑ)
121+
122+
### React (Client)
123+
124+
- ์ปดํฌ๋„ŒํŠธ ๋‹จ์ผ ์ฑ…์ž„ ์›์น™ ์ค€์ˆ˜
125+
- Custom Hooks๋กœ ๋กœ์ง ์žฌ์‚ฌ์šฉ
126+
- useCallback, useMemo๋กœ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ๋ฐฉ์ง€
127+
- TanStack Query์˜ staleTime, cacheTime ์ ์ ˆํžˆ ์„ค์ •
128+
- ์ ‘๊ทผ์„ฑ(a11y) ๊ณ ๋ ค (ARIA ๋ ˆ์ด๋ธ”, ํ‚ค๋ณด๋“œ ๋„ค๋น„๊ฒŒ์ด์…˜)
129+
130+
---
131+
132+
## ๋ฆฌ๋ทฐ ์˜ˆ์‹œ
133+
134+
### ์ข‹์€ ๋ฆฌ๋ทฐ ์˜ˆ์‹œ
135+
136+
```
137+
P1) [๋ณด์•ˆ] JWT ํ† ํฐ ๊ฒ€์ฆ ์‹œ ๋งŒ๋ฃŒ ์‹œ๊ฐ„(exp) ์ฒดํฌ๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
138+
๋งŒ๋ฃŒ๋œ ํ† ํฐ์œผ๋กœ๋„ ์ธ์ฆ์ด ํ†ต๊ณผ๋  ์ˆ˜ ์žˆ์–ด ์ฆ‰์‹œ ์ˆ˜์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
139+
140+
P2) [์„ฑ๋Šฅ] findAll() ๋ฉ”์„œ๋“œ์—์„œ ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ ํ•„ํ„ฐ๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
141+
WHERE ์ ˆ๋กœ DB ๋ ˆ๋ฒจ์—์„œ ํ•„ํ„ฐ๋งํ•˜๋Š” ๊ฒƒ์ด ์„ฑ๋Šฅ์ƒ ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
142+
143+
P3) [๋ฒ„๊ทธ ๊ฐ€๋Šฅ์„ฑ] Redis ์บ์‹œ ์กฐํšŒ ์‹คํŒจ ์‹œ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์ด ์—†์Šต๋‹ˆ๋‹ค.
144+
Redis ์žฅ์•  ์‹œ ์„œ๋น„์Šค ์ „์ฒด๊ฐ€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์œผ๋‹ˆ fallback ๋กœ์ง์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.
145+
146+
P4) [๊ฐ€๋…์„ฑ] ์ค‘์ฒฉ๋œ if๋ฌธ์ด ๋งŽ์•„ ๋กœ์ง ์ดํ•ด๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
147+
Early return ํŒจํ„ด์ด๋‚˜ Guard clause๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋” ๋ช…ํ™•ํ•ด์งˆ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
148+
149+
P5) [์ œ์•ˆ] lodash ๋Œ€์‹  native array ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
150+
์„ฑ๋Šฅ ์ฐจ์ด๊ฐ€ ํฌ์ง€ ์•Š๋‹ค๋ฉด ๊ณ ๋ คํ•ด๋ณด์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”.
151+
```
152+
153+
---
154+
155+
## ์ฃผ์˜์‚ฌํ•ญ
156+
157+
- **๋ฐฐํฌ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ**: ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹คํ–‰, ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ™•์ธ
158+
- **๋กœ๊น…**: ๋ฏผ๊ฐ ์ •๋ณด(๋น„๋ฐ€๋ฒˆํ˜ธ, ํ† ํฐ) ๋กœ๊ทธ ์ถœ๋ ฅ ๊ธˆ์ง€
159+
- **์—๋Ÿฌ ๋ฉ”์‹œ์ง€**: ํ”„๋กœ๋•์…˜์—์„œ๋Š” ์ƒ์„ธ ์—๋Ÿฌ ์Šคํƒ ๋…ธ์ถœ ๋ฐฉ์ง€
160+
- **API ๋ฒ„์ „ ๊ด€๋ฆฌ**: Breaking change ์‹œ API ๋ฒ„์ „์—… ๊ณ ๋ ค
161+
- **DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜**: ๋ฐ์ดํ„ฐ ์†์‹ค ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ๋กค๋ฐฑ ๊ณ„ํš ์ˆ˜๋ฆฝ

0 commit comments

Comments
ย (0)