@blastlabs/utils 1.17.0 โ 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -0
- package/bin/init-ai-rules.cjs +25 -10
- package/package.json +1 -1
- package/rules/changelog.md +60 -0
- package/rules/development-workflow.md +96 -0
- package/rules/documentation.md +13 -2
- package/rules/entities-layer.md +15 -10
- package/rules/naming-convention.md +212 -0
- package/rules/shared-layer.md +12 -9
- package/rules/views-layer.md +6 -44
package/README.md
CHANGED
|
@@ -255,6 +255,89 @@ function App() {
|
|
|
255
255
|
import type { FormDevToolsProps, ApiLogEntry } from '@blastlabs/utils/components/dev';
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
+
## ๐ CLI ๋๊ตฌ
|
|
259
|
+
|
|
260
|
+
์ด ํจํค์ง๋ ํ๋ก์ ํธ ์ค์ ์ ์๋ํํ๋ CLI ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
|
|
261
|
+
|
|
262
|
+
### FSD Entity Generator
|
|
263
|
+
|
|
264
|
+
Feature-Sliced Design ์ํคํ
์ฒ์ฉ ์ํฐํฐ ์ค์บํด๋ฉ์ ์๋์ผ๋ก ์์ฑํฉ๋๋ค.
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# entities ํด๋๋ก ์ด๋
|
|
268
|
+
cd src/entities
|
|
269
|
+
|
|
270
|
+
# ์ํฐํฐ ์์ฑ
|
|
271
|
+
npx blastlabs-generate-entity user
|
|
272
|
+
npx blastlabs-generate-entity my-new-entity
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**์์ฑ๋๋ ๊ตฌ์กฐ:**
|
|
276
|
+
```
|
|
277
|
+
user/
|
|
278
|
+
โโโ index.ts
|
|
279
|
+
โโโ api/
|
|
280
|
+
โ โโโ get-user-list.ts
|
|
281
|
+
โ โโโ get-user-detail.ts
|
|
282
|
+
โ โโโ user-queries.ts
|
|
283
|
+
โ โโโ index.ts
|
|
284
|
+
โ โโโ mapper/
|
|
285
|
+
โ โ โโโ map-user.ts
|
|
286
|
+
โ โ โโโ map-user-detail.ts
|
|
287
|
+
โ โโโ query/
|
|
288
|
+
โ โโโ user-list-query.ts
|
|
289
|
+
โโโ model/
|
|
290
|
+
โโโ user.ts
|
|
291
|
+
โโโ user-detail.ts
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**ํน์ง:**
|
|
295
|
+
- TanStack Query queryOptions ํจํด ์ง์
|
|
296
|
+
- Zod ์คํค๋ง ์๋ ์์ฑ
|
|
297
|
+
- API mapper ํจํด ์ ์ฉ
|
|
298
|
+
- TypeScript ํ์
์์ ์ฑ ๋ณด์ฅ
|
|
299
|
+
|
|
300
|
+
### AI Rules Installer
|
|
301
|
+
|
|
302
|
+
Cursor, Claude Code์ฉ AI ๊ท์น์ ํ๋ก์ ํธ์ ์ค์นํฉ๋๋ค.
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# ํ๋ก์ ํธ ๋ฃจํธ์์ ์คํ
|
|
306
|
+
npx blastlabs-init-ai-rules [options]
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**์ต์
:**
|
|
310
|
+
- `--fsd` - FSD ์ํคํ
์ฒ ๊ท์น ํฌํจ
|
|
311
|
+
- `--all` - ๋ชจ๋ ๊ท์น ์ค์น (base + fsd)
|
|
312
|
+
- `--list, -l` - ์ค์น ๊ฐ๋ฅํ ๊ท์น ๋ชฉ๋ก ๋ณด๊ธฐ
|
|
313
|
+
- `--help, -h` - ๋์๋ง ๋ณด๊ธฐ
|
|
314
|
+
|
|
315
|
+
**์์:**
|
|
316
|
+
```bash
|
|
317
|
+
# ๊ธฐ๋ณธ ๊ท์น๋ง ์ค์น
|
|
318
|
+
npx blastlabs-init-ai-rules
|
|
319
|
+
|
|
320
|
+
# FSD ์ํคํ
์ฒ ๊ท์น ํฌํจ
|
|
321
|
+
npx blastlabs-init-ai-rules --fsd
|
|
322
|
+
|
|
323
|
+
# ๋ชจ๋ ๊ท์น ์ค์น
|
|
324
|
+
npx blastlabs-init-ai-rules --all
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**์ค์น๋๋ ํ์ผ:**
|
|
328
|
+
```
|
|
329
|
+
.cursor/rules/*.mdc # Cursor์ฉ ๊ท์น
|
|
330
|
+
.claude/rules/*.md # Claude Code์ฉ ๊ท์น
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**ํฌํจ๋ ๊ท์น:**
|
|
334
|
+
- TypeScript ํ์ค
|
|
335
|
+
- React Hooks ๊ฐ์ด๋๋ผ์ธ
|
|
336
|
+
- ํ
์คํธ ์์ฑ ๊ฐ์ด๋
|
|
337
|
+
- ๋ฌธ์ํ ๊ฐ์ด๋๋ผ์ธ
|
|
338
|
+
- Git ์ปค๋ฐ ์ปจ๋ฒค์
|
|
339
|
+
- FSD ์ํคํ
์ฒ (์ ํ)
|
|
340
|
+
|
|
258
341
|
## ์ฃผ์์ฌํญ
|
|
259
342
|
|
|
260
343
|
- **๊ฐ๋ฐ์ฉ ์ปดํฌ๋ํธ(`components/dev`)๋ ํ๋ก๋์
ํ๊ฒฝ์์ ์ ์ธํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.**
|
package/bin/init-ai-rules.cjs
CHANGED
|
@@ -7,10 +7,13 @@ const path = require("path");
|
|
|
7
7
|
const RULE_CATEGORIES = {
|
|
8
8
|
// ๊ธฐ๋ณธ ๊ท์น (ํญ์ ํฌํจ)
|
|
9
9
|
base: [
|
|
10
|
+
"development-workflow.md",
|
|
10
11
|
"typescript-standards.md",
|
|
12
|
+
"naming-convention.md",
|
|
11
13
|
"react-hooks.md",
|
|
12
14
|
"testing.md",
|
|
13
15
|
"documentation.md",
|
|
16
|
+
"changelog.md",
|
|
14
17
|
"git-commit.md",
|
|
15
18
|
],
|
|
16
19
|
// FSD ์ํคํ
์ฒ ๊ท์น
|
|
@@ -28,6 +31,7 @@ function parseArgs(args) {
|
|
|
28
31
|
all: false,
|
|
29
32
|
list: false,
|
|
30
33
|
help: false,
|
|
34
|
+
force: false,
|
|
31
35
|
};
|
|
32
36
|
|
|
33
37
|
for (const arg of args) {
|
|
@@ -39,6 +43,8 @@ function parseArgs(args) {
|
|
|
39
43
|
options.all = true;
|
|
40
44
|
} else if (arg === "--list" || arg === "-l") {
|
|
41
45
|
options.list = true;
|
|
46
|
+
} else if (arg === "--force" || arg === "-f") {
|
|
47
|
+
options.force = true;
|
|
42
48
|
}
|
|
43
49
|
}
|
|
44
50
|
|
|
@@ -52,12 +58,14 @@ function showHelp() {
|
|
|
52
58
|
console.log("Options:");
|
|
53
59
|
console.log(" --fsd FSD ์ํคํ
์ฒ ๊ท์น ํฌํจ");
|
|
54
60
|
console.log(" --all ๋ชจ๋ ๊ท์น ์ค์น (base + fsd)");
|
|
61
|
+
console.log(" --force, -f ๊ธฐ์กด ํ์ผ ๋ฎ์ด์ฐ๊ธฐ");
|
|
55
62
|
console.log(" --list, -l ์ค์น ๊ฐ๋ฅํ ๊ท์น ๋ชฉ๋ก ๋ณด๊ธฐ");
|
|
56
63
|
console.log(" --help, -h ๋์๋ง ๋ณด๊ธฐ");
|
|
57
64
|
console.log("\n์์:");
|
|
58
65
|
console.log(" npx blastlabs-init-ai-rules # ๊ธฐ๋ณธ ๊ท์น๋ง");
|
|
59
66
|
console.log(" npx blastlabs-init-ai-rules --fsd # ๊ธฐ๋ณธ + FSD ๊ท์น");
|
|
60
67
|
console.log(" npx blastlabs-init-ai-rules --all # ๋ชจ๋ ๊ท์น");
|
|
68
|
+
console.log(" npx blastlabs-init-ai-rules --force # ๊ธฐ์กด ํ์ผ ๋ฎ์ด์ฐ๊ธฐ");
|
|
61
69
|
console.log("\n์์ฑ๋๋ ํ์ผ:");
|
|
62
70
|
console.log(" .cursor/rules/*.mdc - Cursor์ฉ ๊ท์น ํ์ผ๋ค");
|
|
63
71
|
console.log(" .claude/rules/*.md - Claude Code์ฉ ๊ท์น ํ์ผ๋ค");
|
|
@@ -139,9 +147,14 @@ function serializeCursorFrontmatter(frontmatter) {
|
|
|
139
147
|
if (frontmatter.description) {
|
|
140
148
|
yaml += `description: ${frontmatter.description}\n`;
|
|
141
149
|
}
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
// Cursor๋ globs ์ฌ์ฉ (paths๋ฅผ globs๋ก ๋ณํ)
|
|
151
|
+
// ๋ฐฐ์ด์ธ ๊ฒฝ์ฐ ์ผํ๋ก ๊ตฌ๋ถ๋ ํ ์ค๋ก ๋ณํ
|
|
152
|
+
const globs = frontmatter.globs || frontmatter.paths;
|
|
153
|
+
if (globs) {
|
|
154
|
+
const globsStr = Array.isArray(globs) ? globs.join(",") : globs;
|
|
155
|
+
yaml += `globs: "${globsStr}"\n`;
|
|
144
156
|
}
|
|
157
|
+
// alwaysApply๋ Cursor ์ ์ฉ
|
|
145
158
|
if (frontmatter.alwaysApply !== undefined) {
|
|
146
159
|
yaml += `alwaysApply: ${frontmatter.alwaysApply}\n`;
|
|
147
160
|
}
|
|
@@ -170,7 +183,7 @@ function serializeClaudeFrontmatter(frontmatter) {
|
|
|
170
183
|
return yaml;
|
|
171
184
|
}
|
|
172
185
|
|
|
173
|
-
function generateCursorRules(ruleFiles, sourceDir, targetDir) {
|
|
186
|
+
function generateCursorRules(ruleFiles, sourceDir, targetDir, force = false) {
|
|
174
187
|
const cursorDir = path.join(targetDir, ".cursor", "rules");
|
|
175
188
|
if (!fs.existsSync(cursorDir)) {
|
|
176
189
|
fs.mkdirSync(cursorDir, { recursive: true });
|
|
@@ -191,7 +204,7 @@ function generateCursorRules(ruleFiles, sourceDir, targetDir) {
|
|
|
191
204
|
continue;
|
|
192
205
|
}
|
|
193
206
|
|
|
194
|
-
if (fs.existsSync(targetPath)) {
|
|
207
|
+
if (fs.existsSync(targetPath) && !force) {
|
|
195
208
|
console.log(` โญ๏ธ ${targetName} - ์ด๋ฏธ ์กด์ฌํจ, ๊ฑด๋๋`);
|
|
196
209
|
skipped++;
|
|
197
210
|
continue;
|
|
@@ -202,14 +215,15 @@ function generateCursorRules(ruleFiles, sourceDir, targetDir) {
|
|
|
202
215
|
const output = serializeCursorFrontmatter(frontmatter) + body;
|
|
203
216
|
|
|
204
217
|
fs.writeFileSync(targetPath, output);
|
|
205
|
-
|
|
218
|
+
const action = force && fs.existsSync(targetPath) ? "๐" : "โ
";
|
|
219
|
+
console.log(` ${action} ${targetName}`);
|
|
206
220
|
installed++;
|
|
207
221
|
}
|
|
208
222
|
|
|
209
223
|
return { installed, skipped };
|
|
210
224
|
}
|
|
211
225
|
|
|
212
|
-
function generateClaudeRules(ruleFiles, sourceDir, targetDir) {
|
|
226
|
+
function generateClaudeRules(ruleFiles, sourceDir, targetDir, force = false) {
|
|
213
227
|
const claudeDir = path.join(targetDir, ".claude", "rules");
|
|
214
228
|
if (!fs.existsSync(claudeDir)) {
|
|
215
229
|
fs.mkdirSync(claudeDir, { recursive: true });
|
|
@@ -229,7 +243,7 @@ function generateClaudeRules(ruleFiles, sourceDir, targetDir) {
|
|
|
229
243
|
continue;
|
|
230
244
|
}
|
|
231
245
|
|
|
232
|
-
if (fs.existsSync(targetPath)) {
|
|
246
|
+
if (fs.existsSync(targetPath) && !force) {
|
|
233
247
|
console.log(` โญ๏ธ ${ruleName} - ์ด๋ฏธ ์กด์ฌํจ, ๊ฑด๋๋`);
|
|
234
248
|
skipped++;
|
|
235
249
|
continue;
|
|
@@ -240,7 +254,8 @@ function generateClaudeRules(ruleFiles, sourceDir, targetDir) {
|
|
|
240
254
|
const output = serializeClaudeFrontmatter(frontmatter) + body;
|
|
241
255
|
|
|
242
256
|
fs.writeFileSync(targetPath, output);
|
|
243
|
-
|
|
257
|
+
const action = force && fs.existsSync(targetPath) ? "๐" : "โ
";
|
|
258
|
+
console.log(` ${action} ${ruleName}`);
|
|
244
259
|
installed++;
|
|
245
260
|
}
|
|
246
261
|
|
|
@@ -285,11 +300,11 @@ function main() {
|
|
|
285
300
|
|
|
286
301
|
// Cursor ๊ท์น ์์ฑ
|
|
287
302
|
console.log("๐ง Cursor ๊ท์น ์์ฑ:\n");
|
|
288
|
-
const cursor = generateCursorRules(rulesToInstall, rulesSourceDir, targetDir);
|
|
303
|
+
const cursor = generateCursorRules(rulesToInstall, rulesSourceDir, targetDir, options.force);
|
|
289
304
|
|
|
290
305
|
// Claude ๊ท์น ์์ฑ
|
|
291
306
|
console.log("\n๐ค Claude ๊ท์น ์์ฑ:\n");
|
|
292
|
-
const claude = generateClaudeRules(rulesToInstall, rulesSourceDir, targetDir);
|
|
307
|
+
const claude = generateClaudeRules(rulesToInstall, rulesSourceDir, targetDir, options.force);
|
|
293
308
|
|
|
294
309
|
const totalInstalled = cursor.installed + claude.installed;
|
|
295
310
|
const totalSkipped = cursor.skipped + claude.skipped;
|
package/package.json
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Changelog ์์ฑ ๊ท์น"
|
|
3
|
+
globs: "CHANGELOG.md"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Changelog Rules
|
|
8
|
+
|
|
9
|
+
## ํ์ ๊ท์น
|
|
10
|
+
|
|
11
|
+
- [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ํ์ ์ค์
|
|
12
|
+
- Semantic Versioning ์ค์
|
|
13
|
+
- ์ต์ ๋ณ๊ฒฝ์ฌํญ์ `[Unreleased]` ์น์
์ ์ถ๊ฐ
|
|
14
|
+
|
|
15
|
+
## ์น์
๊ตฌ์กฐ
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
# Changelog
|
|
19
|
+
|
|
20
|
+
## [Unreleased]
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- ์๋ก์ด ๊ธฐ๋ฅ
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- ๊ธฐ์กด ๊ธฐ๋ฅ์ ๋ณ๊ฒฝ
|
|
27
|
+
|
|
28
|
+
### Deprecated
|
|
29
|
+
- ๊ณง ์ ๊ฑฐ๋ ๊ธฐ๋ฅ
|
|
30
|
+
|
|
31
|
+
### Removed
|
|
32
|
+
- ์ ๊ฑฐ๋ ๊ธฐ๋ฅ
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- ๋ฒ๊ทธ ์์
|
|
36
|
+
|
|
37
|
+
### Security
|
|
38
|
+
- ๋ณด์ ํจ์น
|
|
39
|
+
|
|
40
|
+
## [1.0.0] - 2024-01-01
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## ๋ฒ์ ๋ฆด๋ฆฌ์ฆ ์
|
|
44
|
+
|
|
45
|
+
1. `[Unreleased]` ๋ด์ฉ์ ์ ๋ฒ์ ์น์
์ผ๋ก ์ด๋
|
|
46
|
+
2. ๋ฆด๋ฆฌ์ฆ ๋ ์ง ์ถ๊ฐ
|
|
47
|
+
3. ์๋ก์ด `[Unreleased]` ์น์
์์ฑ
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
## [Unreleased]
|
|
51
|
+
|
|
52
|
+
## [1.1.0] - 2024-02-01
|
|
53
|
+
### Added
|
|
54
|
+
- ์ด์ ์ Unreleased์ ์๋ ๋ด์ฉ
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## ์ค์
|
|
58
|
+
|
|
59
|
+
- **Always** update CHANGELOG.md when making changes
|
|
60
|
+
- ๋ฐฐํฌ ์ ๋ฐ๋์ changelog ํ์ธ
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "๊ฐ๋ฐ ์ํฌํ๋ก์ฐ: PRD ์ฐธ๊ณ ๋ฐ ํ
์คํธ ๊ธฐ๋ณธ ์งํ"
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Development Workflow
|
|
7
|
+
|
|
8
|
+
## ํ์ ์์น
|
|
9
|
+
|
|
10
|
+
### 1. PRD ๋จผ์ ํ์ธ
|
|
11
|
+
|
|
12
|
+
๋ชจ๋ ๊ธฐ๋ฅ ๊ฐ๋ฐ ์ ์ **๋ฐ๋์** PRD(Product Requirement Document)๋ฅผ ๋จผ์ ํ์ธํ์ธ์:
|
|
13
|
+
|
|
14
|
+
- **PRD๊ฐ ์๋ค๋ฉด** ๋ด์ฉ์ ํ์ธํ๊ณ ์คํ ํ์
|
|
15
|
+
- **PRD๊ฐ ์๋ค๋ฉด** ์ฌ์ฉ์์ ํจ๊ป PRD๋ฅผ ์์ฑ
|
|
16
|
+
- ์ฌ์ฉ์๋ก๋ถํฐ ์๊ตฌ์ฌํญ ์์ง
|
|
17
|
+
- AI๊ฐ PRD ์ด์ ์์ฑ
|
|
18
|
+
- ์ฌ์ฉ์ ํ์ธ ํ ๊ฐ๋ฐ ์งํ
|
|
19
|
+
- PRD์์ ์๊ตฌ์ฌํญ, UI/UX ์คํ, ๋น์ฆ๋์ค ๋ก์ง์ ๋ช
ํํ ํ์
|
|
20
|
+
- ๋ถํ์คํ ๋ถ๋ถ์ PRD๋ฅผ ํตํด ๋ช
ํํ ํ ๊ฐ๋ฐ ์งํ
|
|
21
|
+
|
|
22
|
+
**PRD ํ์ธ ์ฒดํฌ๋ฆฌ์คํธ:**
|
|
23
|
+
- [ ] ๊ธฐ๋ฅ ๋ชฉ์ ๊ณผ ๋ชฉํ๊ฐ ๋ช
ํํ๊ฐ?
|
|
24
|
+
- [ ] UI/UX ์คํ์ด ์ ์๋์ด ์๋๊ฐ?
|
|
25
|
+
- [ ] API ์คํ์ด ์ ์๋์ด ์๋๊ฐ?
|
|
26
|
+
- [ ] ์์ธ ์ํฉ๊ณผ ์๋ฌ ์ฒ๋ฆฌ๊ฐ ์ ์๋์ด ์๋๊ฐ?
|
|
27
|
+
|
|
28
|
+
### 2. ํ
์คํธ ๊ธฐ๋ณธ ์งํ
|
|
29
|
+
|
|
30
|
+
**๋ชจ๋ ๊ธฐ๋ฅ ๊ตฌํ์ ํ
์คํธ ์ฝ๋์ ํจ๊ป ์งํํฉ๋๋ค.**
|
|
31
|
+
|
|
32
|
+
#### ํ
์คํธ ์ฐ์ ์์น
|
|
33
|
+
|
|
34
|
+
1. **ํ
์คํธ ์์ด ๊ตฌํํ์ง ์๊ธฐ**
|
|
35
|
+
- ๊ธฐ๋ฅ ๊ตฌํ ์ ํ
์คํธ ์ผ์ด์ค ๋จผ์ ์์ฑ
|
|
36
|
+
- ํ
์คํธ๊ฐ ์คํจํ๋ฉด ๊ตฌํ์ผ๋ก ๊ฐ์ฃผํ์ง ์์
|
|
37
|
+
|
|
38
|
+
2. **์ต์ ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง ์ค์**
|
|
39
|
+
- ์๋ก์ด hook: 100% ์ปค๋ฒ๋ฆฌ์ง ๊ถ์ฅ
|
|
40
|
+
- ์ปดํฌ๋ํธ: ์ฃผ์ ์ฌ์ฉ์ ์๋๋ฆฌ์ค ํ
์คํธ
|
|
41
|
+
- ์ ํธ๋ฆฌํฐ ํจ์: 100% ์ปค๋ฒ๋ฆฌ์ง
|
|
42
|
+
|
|
43
|
+
3. **ํ
์คํธ ์คํ ํ PR**
|
|
44
|
+
- `npm test` ํต๊ณผ ํ์ธ
|
|
45
|
+
- ๋น๋ ์ฑ๊ณต ํ์ธ
|
|
46
|
+
- ํ
์คํธ ์คํจ ์ PR ๋ถ๊ฐ
|
|
47
|
+
|
|
48
|
+
## ๊ฐ๋ฐ ์์
|
|
49
|
+
|
|
50
|
+
### Step 1: PRD ํ์ธ/์์ฑ
|
|
51
|
+
```
|
|
52
|
+
์ฌ์ฉ์: "๋ก๊ทธ์ธ ๊ธฐ๋ฅ ์ถ๊ฐํด์ค"
|
|
53
|
+
AI: "PRD๊ฐ ์๋์? ์๋ค๋ฉด ๋จผ์ ํจ๊ป ์์ฑํด์.
|
|
54
|
+
|
|
55
|
+
๋จผ์ ๋ช ๊ฐ์ง ์ง๋ฌธ๋๋ฆด๊ฒ์:
|
|
56
|
+
1. ๋ก๊ทธ์ธ ๋ฐฉ๋ฒ (์ด๋ฉ์ผ/์์
)
|
|
57
|
+
2. ํ์ํ UI ์ปดํฌ๋ํธ
|
|
58
|
+
3. ์ฐ๋ํ API ์๋ํฌ์ธํธ
|
|
59
|
+
|
|
60
|
+
์ด๋ฅผ ๋ฐํ์ผ๋ก PRD ์ด์์ ์์ฑํ ๊ฒ์."
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Step 2: ํ
์คํธ ์ฝ๋ ์์ฑ
|
|
64
|
+
```
|
|
65
|
+
AI: "ํ
์คํธ ์ฝ๋๋ถํฐ ์์ฑํ ๊ฒ์."
|
|
66
|
+
โ ๋ก๊ทธ์ธ ํ
์คํธ ์์ฑ
|
|
67
|
+
โ ์คํจํ๋ ๊ฒ ํ์ธ
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step 3: ๊ธฐ๋ฅ ๊ตฌํ
|
|
71
|
+
```
|
|
72
|
+
AI: "์ด์ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ ๊ฒ์."
|
|
73
|
+
โ ์ต์ํ์ ๊ตฌํ์ผ๋ก ํ
์คํธ ํต๊ณผ
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 4: ๋ฆฌํฉํ ๋ง
|
|
77
|
+
```
|
|
78
|
+
AI: "์ฝ๋๋ฅผ ์ ๋ฆฌํ ๊ฒ์."
|
|
79
|
+
โ ๋ฆฌํฉํ ๋ง ํ ํ
์คํธ ์ฌ์คํ
|
|
80
|
+
โ ๋ชจ๋ ํ
์คํธ ํต๊ณผ ํ์ธ
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## ์์ธ ์ฌํญ
|
|
84
|
+
|
|
85
|
+
**ํ
์คํธ๋ฅผ ์๋ตํ ์ ์๋ ๊ฒฝ์ฐ:**
|
|
86
|
+
- ํ๋กํ ํ์ดํ (์ฝ๋ ํ๊ธฐ ์์ )
|
|
87
|
+
- ์คํ์ผ๋ง ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ
|
|
88
|
+
- ๋ช
์์ ์ผ๋ก ํ
์คํธ ์ ์ธ ์์ฒญ ์
|
|
89
|
+
|
|
90
|
+
**๊ทธ ์ธ์๋ ๋ฌด์กฐ๊ฑด ํ
์คํธ ์์ฑ**
|
|
91
|
+
|
|
92
|
+
## ์ค์
|
|
93
|
+
|
|
94
|
+
- **Always** check PRD first before implementation
|
|
95
|
+
- **Always** write tests before or with implementation
|
|
96
|
+
- **Never** skip tests without explicit reason
|
package/rules/documentation.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: '๋ฌธ์ํ ๊ฐ์ด๋๋ผ์ธ'
|
|
3
3
|
alwaysApply: false
|
|
4
|
+
paths:
|
|
5
|
+
- '**/docs/**'
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Documentation Guidelines
|
|
@@ -14,8 +16,17 @@ alwaysApply: false
|
|
|
14
16
|
## ๋ฌธ์ ์
๋ฐ์ดํธ
|
|
15
17
|
|
|
16
18
|
- ๊ธฐ๋ฅ ์ถ๊ฐ ์ README.md ์
๋ฐ์ดํธ
|
|
17
|
-
- ์ hooks ์ถ๊ฐ ์ ๊ด๋ จ docs
|
|
19
|
+
- ์ hooks ์ถ๊ฐ ์ ๊ด๋ จ docs/\*.md ์
๋ฐ์ดํธ
|
|
20
|
+
- ๋ณ๊ฒฝ์ฌํญ์ ๋ฐ๋์ CHANGELOG.md์ ๊ธฐ๋ก
|
|
21
|
+
|
|
22
|
+
## CHANGELOG ์์ฑ
|
|
23
|
+
|
|
24
|
+
- [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ํ์ ์ค์
|
|
25
|
+
- ์ต์ ๋ณ๊ฒฝ์ฌํญ์ `[Unreleased]` ์น์
์ ์ถ๊ฐ
|
|
26
|
+
- ์น์
: Added, Changed, Deprecated, Removed, Fixed, Security
|
|
27
|
+
- ๋ฒ์ ๋ฆด๋ฆฌ์ฆ ์ `[Unreleased]`๋ฅผ ํด๋น ๋ฒ์ ์ผ๋ก ์ด๋
|
|
18
28
|
|
|
19
29
|
## ํ์ ์ฌํญ
|
|
20
30
|
|
|
21
31
|
- **Always** update documentation when adding features
|
|
32
|
+
- **Always** update CHANGELOG.md for any changes
|
package/rules/entities-layer.md
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: 'Entities ๋ ์ด์ด ๊ตฌ์กฐ ๋ฐ API ํจํด'
|
|
3
3
|
paths:
|
|
4
|
-
-
|
|
4
|
+
- '**/entities/**'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Entities Layer (์ํฐํฐ)
|
|
8
8
|
|
|
9
9
|
์ํฐํฐ๋ ๋๋ฉ์ธ ๋ชจ๋ธ๊ณผ API ๋ก์ง์ ๊ด๋ฆฌํฉ๋๋ค.
|
|
10
|
+
mapper๋ ๋ฐ์๋ฐ์ดํฐ๋ฅผ model์ ์ค๊ณํ ๋ฐฉ์์ผ๋ก map์ ํฉ๋๋ค.
|
|
11
|
+
query๋ params๋ก ๋ณดํต get์์ ์ฌ์ฉํฉ๋๋ค.
|
|
10
12
|
|
|
11
13
|
## ๊ตฌ์กฐ
|
|
14
|
+
|
|
12
15
|
```
|
|
13
16
|
entities/
|
|
14
17
|
โโโ (์ํฐํฐ ์ด๋ฆ)/ ์: inquiry, popular-product
|
|
@@ -22,29 +25,27 @@ entities/
|
|
|
22
25
|
โ โโโ get-(์ํฐํฐ ์ด๋ฆ)-list.ts
|
|
23
26
|
โ โโโ get-(์ํฐํฐ ์ด๋ฆ)-detail.ts
|
|
24
27
|
โ โโโ (์ํฐํฐ ์ด๋ฆ)-queries.ts
|
|
25
|
-
โ โโโ mutate.ts
|
|
26
|
-
โ โโโ query.ts
|
|
27
28
|
โ โโโ index.ts
|
|
28
29
|
โโโ model/
|
|
29
30
|
โ โโโ (์ํฐํฐ ์ด๋ฆ).ts
|
|
30
31
|
โ โโโ (์ํฐํฐ ์ด๋ฆ)-detail.ts
|
|
31
32
|
โ โโโ (์ํฐํฐ ์ด๋ฆ)-update.ts
|
|
32
|
-
โโโ schema.ts
|
|
33
33
|
โโโ index.ts
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## ๊ฐ ํ์ผ์ ์ญํ
|
|
37
|
+
|
|
37
38
|
- **mapper/**: API ์๋ต์ ๋๋ฉ์ธ ๋ชจ๋ธ๋ก ๋ณํ
|
|
38
39
|
- **query/**: ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ํ์
์ ์
|
|
39
|
-
- **get
|
|
40
|
-
- **get
|
|
40
|
+
- **get-\*-list.ts**: ๋ฆฌ์คํธ ์กฐํ API ํจ์
|
|
41
|
+
- **get-\*-detail.ts**: ์์ธ ์กฐํ API ํจ์
|
|
42
|
+
- **post-\*.ts** : post API ํจ์ (delete, put๊ฐ์๊ฒ๋ ์์ ์ ๋์ฌ๊ฐ ๋ณํจ)
|
|
41
43
|
- **\*-queries.ts**: TanStack Query queryOptions ์ ์ (all, lists, list, details, detail ๋ฑ)
|
|
42
|
-
- **mutate.ts**: mutation ํจ์๋ค
|
|
43
44
|
- **model/**: ๋๋ฉ์ธ ๋ชจ๋ธ ํ์
์ ์
|
|
44
|
-
- **schema.ts**: zod ์คํค๋ง ์ ์ ๋ฐ ๋ณํ ํจ์
|
|
45
45
|
- **index.ts**: `export * as (์ํฐํฐ ์ด๋ฆ)Api from "./api"`
|
|
46
46
|
|
|
47
47
|
## ์์
|
|
48
|
+
|
|
48
49
|
```
|
|
49
50
|
entities/inquiry/
|
|
50
51
|
โโโ api/
|
|
@@ -60,8 +61,12 @@ entities/inquiry/
|
|
|
60
61
|
โโโ model/
|
|
61
62
|
โ โโโ inquiry.ts
|
|
62
63
|
โ โโโ inquiry-detail.ts
|
|
63
|
-
โโโ schema.ts
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## TanStack Query ํจํด
|
|
67
|
+
|
|
67
68
|
์๋ฒ ์ํ ๊ด๋ฆฌ๋ TanStack Query์ queryOptions ํจํด์ ์ฌ์ฉํฉ๋๋ค.
|
|
69
|
+
|
|
70
|
+
## model์ ๊ท์น
|
|
71
|
+
|
|
72
|
+
zod๋ฅผ ์ฌ์ฉํ๋ฉฐ export const (์ํฐํฐ)Schema์ export type (์ํฐํฐ)Type ์ ๋ค์ด๋ฐ ๊ท์น์ ํ์ฉํ๋ค
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "ํ์ผ ๋ฐ ๋ณ์ ๋ค์ด๋ฐ ์ปจ๋ฒค์
"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
paths:
|
|
5
|
+
- "**/*.ts"
|
|
6
|
+
- "**/*.tsx"
|
|
7
|
+
- "**/*.js"
|
|
8
|
+
- "**/*.jsx"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Naming Convention
|
|
12
|
+
|
|
13
|
+
## ํ์ผ ๋ค์ด๋ฐ
|
|
14
|
+
|
|
15
|
+
### ๊ธฐ๋ณธ ๊ท์น
|
|
16
|
+
|
|
17
|
+
**๋ชจ๋ ํ์ผ/ํด๋๋ `kebab-case` ์ฌ์ฉ**
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
โ
good
|
|
21
|
+
user-profile/
|
|
22
|
+
use-user-data/
|
|
23
|
+
button-group.tsx
|
|
24
|
+
|
|
25
|
+
โ bad
|
|
26
|
+
UserProfile/
|
|
27
|
+
useUserData/
|
|
28
|
+
buttonGroup.tsx
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### ์์ธ: React ์ปดํฌ๋ํธ
|
|
32
|
+
|
|
33
|
+
**์ปดํฌ๋ํธ ํ์ผ์ `PascalCase` ์ฌ์ฉ**
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
components/
|
|
37
|
+
โ
ButtonGroup.tsx
|
|
38
|
+
โ
UserProfile.tsx
|
|
39
|
+
โ
FormInput.tsx
|
|
40
|
+
|
|
41
|
+
โ button-group.tsx
|
|
42
|
+
โ user-profile.tsx
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**๋จ, ํด๋๋ `kebab-case`**
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
components/
|
|
49
|
+
button-group/
|
|
50
|
+
ButtonGroup.tsx
|
|
51
|
+
ButtonGroup.test.tsx
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Hooks
|
|
55
|
+
|
|
56
|
+
**`use-` prefix + `camelCase`**
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
hooks/
|
|
60
|
+
โ
use-user-data.ts
|
|
61
|
+
โ
use-form-state.ts
|
|
62
|
+
โ
use-debounce.ts
|
|
63
|
+
|
|
64
|
+
โ userData.ts
|
|
65
|
+
โ useUserData.ts (ํ์ผ๋ช
)
|
|
66
|
+
โ form-state.ts
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### ํ์
ํ์ผ
|
|
70
|
+
|
|
71
|
+
**`.types.ts` ๋๋ `.type.ts` ์ ๋ฏธ์ฌ**
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
model/
|
|
75
|
+
โ
user.types.ts
|
|
76
|
+
โ
product.type.ts
|
|
77
|
+
โ
api.types.ts
|
|
78
|
+
|
|
79
|
+
โ UserTypes.ts
|
|
80
|
+
โท user-type.ts (๋จ์ๅ)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### ํ
์คํธ ํ์ผ
|
|
84
|
+
|
|
85
|
+
**๋์ ํ์ผ๋ช
+ `.test.` + ํ์ฅ์**
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
ButtonGroup.tsx โ ButtonGroup.test.tsx
|
|
89
|
+
useUserData.ts โ useUserData.test.ts
|
|
90
|
+
api.ts โ api.test.ts
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### ํด๋ ๊ตฌ์กฐ
|
|
94
|
+
|
|
95
|
+
**FSD ์ํคํ
์ฒ ์์**
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
src/
|
|
99
|
+
โโโ entities/
|
|
100
|
+
โ โโโ user/ # kebab-case
|
|
101
|
+
โ โโโ model/
|
|
102
|
+
โ โ โโโ user.types.ts
|
|
103
|
+
โ โ โโโ user-detail.types.ts
|
|
104
|
+
โ โโโ api/
|
|
105
|
+
โ โ โโโ get-user-list.ts
|
|
106
|
+
โ โ โโโ use-user-query.ts
|
|
107
|
+
โ โ โโโ user.test.ts
|
|
108
|
+
โ โโโ ui/
|
|
109
|
+
โ โโโ UserCard.tsx # PascalCase
|
|
110
|
+
โ โโโ UserCard.test.tsx
|
|
111
|
+
โโโ features/
|
|
112
|
+
โ โโโ auth-login/ # kebab-case
|
|
113
|
+
โ โโโ model/
|
|
114
|
+
โ โโโ api/
|
|
115
|
+
โ โโโ ui/
|
|
116
|
+
โ โโโ LoginForm.tsx # PascalCase
|
|
117
|
+
โโโ shared/
|
|
118
|
+
โ โโโ ui/
|
|
119
|
+
โ โโโ button/ # kebab-case
|
|
120
|
+
โ โโโ Button.tsx # PascalCase
|
|
121
|
+
โ โโโ Button.test.tsx
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## ๋ณ์/ํจ์ ๋ค์ด๋ฐ
|
|
125
|
+
|
|
126
|
+
### ๋ณ์
|
|
127
|
+
|
|
128
|
+
**`camelCase` ์ฌ์ฉ**
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
โ
good
|
|
132
|
+
const userName = '...';
|
|
133
|
+
const isActive = true;
|
|
134
|
+
const maxCount = 10;
|
|
135
|
+
|
|
136
|
+
โ bad
|
|
137
|
+
const user_name = '...';
|
|
138
|
+
const IsActive = true;
|
|
139
|
+
const MAX_COUNT = 10; (const๊ฐ ์๋๋ผ๋ฉด)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### ์์
|
|
143
|
+
|
|
144
|
+
**`UPPER_SNAKE_CASE` ์ฌ์ฉ**
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
โ
good
|
|
148
|
+
const MAX_RETRY_COUNT = 3;
|
|
149
|
+
const API_BASE_URL = 'https://...';
|
|
150
|
+
const DEFAULT_TIMEOUT = 5000;
|
|
151
|
+
|
|
152
|
+
โ bad
|
|
153
|
+
const maxRetryCount = 3;
|
|
154
|
+
const apiBaseUrl = 'https://...';
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### ํจ์
|
|
158
|
+
|
|
159
|
+
**`camelCase` + ๋์ฌ๋ก ์์**
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
โ
good
|
|
163
|
+
function getUserData() { }
|
|
164
|
+
function handleSubmit() { }
|
|
165
|
+
function isValidEmail() { }
|
|
166
|
+
|
|
167
|
+
โ bad
|
|
168
|
+
function userData() { }
|
|
169
|
+
function form_submit() { }
|
|
170
|
+
function ValidEmail() { }
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### ์ธํฐํ์ด์ค/ํ์
|
|
174
|
+
|
|
175
|
+
**`PascalCase` ์ฌ์ฉ**
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
โ
good
|
|
179
|
+
interface UserProfile { }
|
|
180
|
+
type LoginFormData = { };
|
|
181
|
+
interface ApiResponse<T> { }
|
|
182
|
+
|
|
183
|
+
โ bad
|
|
184
|
+
interface userProfile { }
|
|
185
|
+
type loginFormData = { }
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Enum
|
|
189
|
+
|
|
190
|
+
**`PascalCase` + ๋ฉค๋ฒ๋ `UPPER_SNAKE_CASE`**
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
โ
good
|
|
194
|
+
enum UserRole {
|
|
195
|
+
ADMIN = 'ADMIN',
|
|
196
|
+
USER = 'USER',
|
|
197
|
+
GUEST = 'GUEST',
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
โ bad
|
|
201
|
+
enum userRole {
|
|
202
|
+
admin = 'admin',
|
|
203
|
+
USER = 'user',
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## ์ค์
|
|
208
|
+
|
|
209
|
+
- **Always** use kebab-case for files and folders
|
|
210
|
+
- **Always** use PascalCase for component files
|
|
211
|
+
- **Always** use camelCase for variables and functions
|
|
212
|
+
- **Always** use UPPER_SNAKE_CASE for constants
|
package/rules/shared-layer.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: 'Shared ๋ ์ด์ด ๊ตฌ์กฐ ๋ฐ lib vs utils ๊ตฌ๋ถ'
|
|
3
3
|
paths:
|
|
4
|
-
-
|
|
4
|
+
- '**/shared/**'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Shared Layer (๊ณต์ ๋ ์ด์ด)
|
|
@@ -9,11 +9,10 @@ paths:
|
|
|
9
9
|
ํ๋ก์ ํธ ์ ์ฒด์์ ๊ณต์ ๋๋ ์ฝ๋๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
|
|
10
10
|
|
|
11
11
|
## ๊ตฌ์กฐ
|
|
12
|
+
|
|
12
13
|
```
|
|
13
14
|
shared/
|
|
14
15
|
โโโ api/ API ์ธ์คํด์ค ์ค์ (instance_v2.ts ๋ฑ)
|
|
15
|
-
โโโ constant/ ๊ณตํต ์์ (path.ts ๋ฑ)
|
|
16
|
-
โโโ hooks/ ๊ณตํต React ํ
|
|
17
16
|
โโโ mock-data/ ๊ฐ๋ฐ์ฉ ๋ชฉ ๋ฐ์ดํฐ
|
|
18
17
|
โโโ lib/ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ํผ ๋ฐ ์ค์
|
|
19
18
|
โ โโโ (๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ช
)/
|
|
@@ -28,14 +27,15 @@ shared/
|
|
|
28
27
|
โ โ โโโ (์ปดํฌ๋ํธ๋ช
).tsx
|
|
29
28
|
โ โโโ theme/ ํ
๋ง ๊ด๋ จ CSS ํ์ผ
|
|
30
29
|
โ โโโ utils/ UI ๊ด๋ จ ์ ํธ๋ฆฌํฐ ํจ์
|
|
31
|
-
โโโ util/ ์ผ๋ฐ ์ ํธ๋ฆฌํฐ ํจ์
|
|
32
30
|
โโโ utils/ ์ถ๊ฐ ์ ํธ๋ฆฌํฐ ํจ์
|
|
33
31
|
```
|
|
34
32
|
|
|
35
33
|
## lib vs utils ๊ตฌ๋ถ ๊ธฐ์ค
|
|
36
34
|
|
|
37
35
|
### `shared/lib/`
|
|
36
|
+
|
|
38
37
|
์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ๋ก์ ํธ์ ๋ง๊ฒ ๊ฐ์ธ๊ฑฐ๋ ์ค์ ํ๋ ์ฝ๋
|
|
38
|
+
|
|
39
39
|
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ํผ(wrapper) ์ปดํฌ๋ํธ
|
|
40
40
|
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๊ธฐ ์ค์ ๋ฐ Provider
|
|
41
41
|
- ์์:
|
|
@@ -43,16 +43,19 @@ shared/
|
|
|
43
43
|
- `shared/lib/tanstack-query/query-client.tsx`
|
|
44
44
|
- `shared/lib/suspense/suspense-wrapper.tsx`
|
|
45
45
|
|
|
46
|
-
### `shared/utils/`
|
|
46
|
+
### `shared/utils/`
|
|
47
|
+
|
|
47
48
|
์์ ์ ํธ๋ฆฌํฐ ํจ์ ๋ฐ ๋น์ฆ๋์ค ๋ก์ง ํฌํผ
|
|
49
|
+
|
|
48
50
|
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฌด๊ดํ ์์ ํจ์
|
|
49
51
|
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ์ ํธ ํจ์
|
|
50
52
|
- ์์:
|
|
51
|
-
- `shared/
|
|
52
|
-
- `shared/
|
|
53
|
-
- `shared/
|
|
53
|
+
- `shared/utils/convert-price.ts` - ๊ฐ๊ฒฉ ๋ณํ ํจ์
|
|
54
|
+
- `shared/utils/export-excel.ts` - ์์
๋ด๋ณด๋ด๊ธฐ ํจ์
|
|
55
|
+
- `shared/utils/form-validation.ts` - ํผ ๊ฒ์ฆ ์ ํธ
|
|
54
56
|
|
|
55
57
|
## ํ๋จ ๊ธฐ์ค
|
|
58
|
+
|
|
56
59
|
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ์ธ๋๊ฐ? โ `lib/`
|
|
57
60
|
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฌด๊ดํ ๋ก์ง์ธ๊ฐ? โ `utils/`
|
|
58
61
|
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ์ ํธ์ธ๊ฐ? โ `utils/`
|
package/rules/views-layer.md
CHANGED
|
@@ -1,72 +1,34 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: 'Views ๋ ์ด์ด (ํ์ด์ง) ๊ตฌ์กฐ'
|
|
3
3
|
paths:
|
|
4
|
-
-
|
|
4
|
+
- '**/views/**'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Views Layer (ํ์ด์ง ๋ ์ด์ด)
|
|
8
8
|
|
|
9
9
|
ํ์ด์ง ๋จ์์ UI์ ๋ก์ง์ ๊ด๋ฆฌํฉ๋๋ค.
|
|
10
|
+
๊ธฐ๋ณธ์ ์ผ๋ก fsd ๋ฐฉ์์ ๋ฐ๋ฆ
๋๋ค
|
|
10
11
|
|
|
11
12
|
## ๊ตฌ์กฐ
|
|
13
|
+
|
|
12
14
|
```
|
|
13
15
|
views/
|
|
14
16
|
โโโ (ํ์ด์ง๋ช
)/ ์: inquiry, product, seller
|
|
15
17
|
โโโ page.tsx ๋ฉ์ธ ํ์ด์ง ์ปดํฌ๋ํธ (ํ์)
|
|
16
|
-
โโโ (ํ์ด์ง๋ช
)-list-page.tsx
|
|
17
|
-
โโโ (ํ์ด์ง๋ช
)-detail-page.tsx
|
|
18
18
|
โโโ detail/
|
|
19
19
|
โ โโโ page.tsx
|
|
20
20
|
โ โโโ ui/
|
|
21
|
-
โ โโโ hooks/ use-(ํ์ด์ง๋ช
)-detail-data.tsx ๋ฑ
|
|
22
|
-
โ โโโ components/
|
|
23
|
-
โโโ list/
|
|
24
|
-
โ โโโ (์ปฌ๋ผ๋ช
)-column.tsx
|
|
25
|
-
โ โโโ search.tsx
|
|
26
|
-
โ โโโ (๋ชจ๋ฌ๋ช
)-modal.tsx
|
|
27
21
|
โโโ ui/
|
|
28
|
-
โโโ hooks/ use-(ํ์ด์ง๋ช
)-data.tsx, use-(ํ์ด์ง๋ช
)-actions.tsx ๋ฑ
|
|
29
|
-
โโโ components/
|
|
30
22
|
โโโ utils/
|
|
31
|
-
โโโ schema/ zod ์คํค๋ง
|
|
32
|
-
โโโ constants.ts
|
|
33
23
|
```
|
|
34
24
|
|
|
35
25
|
## ์์
|
|
36
26
|
|
|
37
27
|
### ๊ธฐ๋ณธ ํ์ด์ง ๊ตฌ์กฐ
|
|
28
|
+
|
|
38
29
|
```
|
|
39
30
|
views/inquiry/
|
|
40
31
|
โโโ detail/
|
|
41
32
|
โ โโโ page.tsx
|
|
42
|
-
|
|
43
|
-
โโโ list/
|
|
44
|
-
โโโ inquiry-column.tsx
|
|
45
|
-
โโโ inquiry-modal.tsx
|
|
46
|
-
โโโ search.tsx
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### ์์ธ ํ์ด์ง ๊ตฌ์กฐ
|
|
50
|
-
```
|
|
51
|
-
views/ai-management/agency/agency-detail/
|
|
52
|
-
โโโ page.tsx
|
|
53
|
-
โโโ hooks/
|
|
54
|
-
โ โโโ use-agency-detail-data.tsx
|
|
55
|
-
โ โโโ use-agency-data-actions.tsx
|
|
56
|
-
โโโ components/
|
|
57
|
-
โ โโโ agency-basic-info-tab.tsx
|
|
58
|
-
โโโ schema/
|
|
59
|
-
โโโ agency-detail.ts
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### ๊ด๋ฆฌ ํ์ด์ง ๊ตฌ์กฐ
|
|
63
|
-
```
|
|
64
|
-
views/product/category-management/
|
|
65
|
-
โโโ page.tsx
|
|
66
|
-
โโโ hooks/
|
|
67
|
-
โ โโโ use-category-data.tsx
|
|
68
|
-
โ โโโ use-category-actions.tsx
|
|
69
|
-
โโโ ui/
|
|
70
|
-
โโโ category-management.tsx
|
|
71
|
-
โโโ category-modal.tsx
|
|
33
|
+
โ page.tsx
|
|
72
34
|
```
|