aiwf 0.3.17 → 0.3.19
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.ko.md +84 -0
- package/README.md +87 -0
- package/ai-tools/README.md +105 -0
- package/ai-tools/augment/README.md +371 -0
- package/ai-tools/augment/config.json +30 -0
- package/ai-tools/augment/template/.augment/aiwf-integration.md +387 -0
- package/ai-tools/augment/template/.augment/augment.yaml +347 -0
- package/ai-tools/augment/template/augment.config.json +64 -0
- package/ai-tools/claude-code/README.md +151 -0
- package/ai-tools/claude-code/config.json +28 -0
- package/ai-tools/claude-code/template/CLAUDE.md +91 -0
- package/ai-tools/cursor/README.md +314 -0
- package/ai-tools/cursor/config.json +29 -0
- package/ai-tools/cursor/template/.cursorrules +362 -0
- package/ai-tools/github-copilot/README.md +195 -0
- package/ai-tools/github-copilot/config.json +24 -0
- package/ai-tools/github-copilot/template/.github/copilot-instructions.md +202 -0
- package/ai-tools/windsurf/README.md +355 -0
- package/ai-tools/windsurf/config.json +29 -0
- package/ai-tools/windsurf/template/.windsurf/aiwf-rules.md +260 -0
- package/ai-tools/windsurf/template/.windsurf/windsurf.config.js +312 -0
- package/ai-tools/windsurf/template/windsurf.config.json +63 -0
- package/docs/CODE_CLEANUP_GUIDE.ko.md +415 -0
- package/docs/CODE_CLEANUP_GUIDE.md +415 -0
- package/docs/VALIDATOR_API.ko.md +324 -0
- package/docs/VALIDATOR_API.md +324 -0
- package/package.json +3 -2
- package/src/cli/index.js +338 -0
- package/src/config/file-lists.js +5 -5
- package/src/lib/backup-manager.js +4 -3
- package/src/lib/installer.js +126 -3
- package/src/lib/validator.js +78 -313
- package/src/utils/messages.js +16 -2
- package/src/utils/paths.js +1 -20
- package/templates/README.md +0 -78
- package/templates/api-server/config.json +0 -64
- package/templates/api-server/template/.aiwf/config.json +0 -56
- package/templates/api-server/template/.aiwf/feature-ledger.json +0 -42
- package/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -40
- package/templates/api-server/template/.aiwf/scripts/cli.js +0 -111
- package/templates/api-server/template/.env.example +0 -29
- package/templates/api-server/template/.eslintrc.json +0 -23
- package/templates/api-server/template/README.md +0 -171
- package/templates/api-server/template/jest.config.js +0 -26
- package/templates/api-server/template/nodemon.json +0 -9
- package/templates/api-server/template/package.json +0 -61
- package/templates/api-server/template/src/app.ts +0 -60
- package/templates/api-server/template/src/config/swagger.ts +0 -38
- package/templates/api-server/template/src/controllers/aiwfController.ts +0 -54
- package/templates/api-server/template/src/controllers/authController.ts +0 -128
- package/templates/api-server/template/src/controllers/statusController.ts +0 -28
- package/templates/api-server/template/src/index.ts +0 -28
- package/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -50
- package/templates/api-server/template/src/middleware/authMiddleware.ts +0 -41
- package/templates/api-server/template/src/middleware/errorHandler.ts +0 -42
- package/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -14
- package/templates/api-server/template/src/middleware/requestLogger.ts +0 -20
- package/templates/api-server/template/src/routes/aiwf.ts +0 -31
- package/templates/api-server/template/src/routes/index.ts +0 -13
- package/templates/api-server/template/src/routes/v1/index.ts +0 -67
- package/templates/api-server/template/src/utils/logger.ts +0 -37
- package/templates/api-server/template/tests/app.test.ts +0 -40
- package/templates/api-server/template/tsconfig.json +0 -43
- package/templates/npm-library/config.json +0 -61
- package/templates/npm-library/template/LICENSE +0 -21
- package/templates/npm-library/template/README.md +0 -201
- package/templates/npm-library/template/package.json +0 -78
- package/templates/web-app/config.json +0 -53
- package/templates/web-app/template/.aiwf/config.json +0 -54
- package/templates/web-app/template/.aiwf/feature-ledger.json +0 -37
- package/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -40
- package/templates/web-app/template/.aiwf/scripts/cli.js +0 -110
- package/templates/web-app/template/.eslintrc.cjs +0 -20
- package/templates/web-app/template/README.md +0 -151
- package/templates/web-app/template/index.html +0 -14
- package/templates/web-app/template/package.json +0 -44
- package/templates/web-app/template/postcss.config.js +0 -6
- package/templates/web-app/template/public/vite.svg +0 -1
- package/templates/web-app/template/src/App.tsx +0 -21
- package/templates/web-app/template/src/components/Layout.tsx +0 -57
- package/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -107
- package/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -71
- package/templates/web-app/template/src/index.css +0 -60
- package/templates/web-app/template/src/main.tsx +0 -10
- package/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -57
- package/templates/web-app/template/src/pages/HomePage.tsx +0 -89
- package/templates/web-app/template/src/pages/NotFound.tsx +0 -25
- package/templates/web-app/template/src/stores/aiwfStore.ts +0 -126
- package/templates/web-app/template/src/types/global.d.ts +0 -9
- package/templates/web-app/template/src/vite-env.d.ts +0 -1
- package/templates/web-app/template/tailwind.config.js +0 -30
- package/templates/web-app/template/tsconfig.json +0 -37
- package/templates/web-app/template/tsconfig.node.json +0 -10
- package/templates/web-app/template/vite.config.ts +0 -23
- /package/rules/global/{code-style-guide.md → aiwf-code-style-guide.md} +0 -0
- /package/rules/global/{coding-principles.md → aiwf-coding-principles.md} +0 -0
- /package/rules/global/{development-process.md → aiwf-development-process.md} +0 -0
- /package/rules/global/{global-rules.md → aiwf-global-rules.md} +0 -0
- /package/rules/manual/{generate-plan-docs.md → aiwf-generate-plan-docs.md} +0 -0
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "1.0.0",
|
|
3
|
-
"project": "{{projectName}}",
|
|
4
|
-
"created": "{{createdAt}}",
|
|
5
|
-
"features": [
|
|
6
|
-
{
|
|
7
|
-
"id": "F001",
|
|
8
|
-
"name": "API 서버 초기 설정",
|
|
9
|
-
"description": "Express + TypeScript 기반 RESTful API 서버 초기 설정",
|
|
10
|
-
"type": "setup",
|
|
11
|
-
"status": "completed",
|
|
12
|
-
"created_at": "{{createdAt}}",
|
|
13
|
-
"completed_at": "{{createdAt}}",
|
|
14
|
-
"components": [
|
|
15
|
-
"Express 서버 설정",
|
|
16
|
-
"TypeScript 설정",
|
|
17
|
-
"미들웨어 구성",
|
|
18
|
-
"에러 핸들링",
|
|
19
|
-
"API 문서화 (Swagger)"
|
|
20
|
-
],
|
|
21
|
-
"endpoints": [
|
|
22
|
-
"GET /api/health",
|
|
23
|
-
"GET /api/v1/status",
|
|
24
|
-
"GET /docs"
|
|
25
|
-
],
|
|
26
|
-
"files": [
|
|
27
|
-
"src/index.ts",
|
|
28
|
-
"src/app.ts",
|
|
29
|
-
"src/middleware/*",
|
|
30
|
-
"src/config/*"
|
|
31
|
-
],
|
|
32
|
-
"tags": ["초기설정", "인프라", "API"]
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"statistics": {
|
|
36
|
-
"total_features": 1,
|
|
37
|
-
"completed": 1,
|
|
38
|
-
"in_progress": 0,
|
|
39
|
-
"planned": 0,
|
|
40
|
-
"total_endpoints": 3
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "backend-engineer",
|
|
3
|
-
"name": "백엔드 엔지니어",
|
|
4
|
-
"description": "Express API 서버 개발 전문가",
|
|
5
|
-
"expertise": [
|
|
6
|
-
"RESTful API 설계",
|
|
7
|
-
"Express.js 최적화",
|
|
8
|
-
"데이터베이스 설계 및 쿼리 최적화",
|
|
9
|
-
"인증/인가 시스템",
|
|
10
|
-
"API 보안",
|
|
11
|
-
"성능 튜닝"
|
|
12
|
-
],
|
|
13
|
-
"context": {
|
|
14
|
-
"focus_areas": [
|
|
15
|
-
"API 설계 패턴",
|
|
16
|
-
"에러 핸들링",
|
|
17
|
-
"입력 검증",
|
|
18
|
-
"미들웨어 아키텍처",
|
|
19
|
-
"데이터베이스 트랜잭션"
|
|
20
|
-
],
|
|
21
|
-
"code_style": {
|
|
22
|
-
"naming": "camelCase (변수/함수), PascalCase (클래스/인터페이스)",
|
|
23
|
-
"structure": "계층형 아키텍처 (Controller-Service-Repository)",
|
|
24
|
-
"error_handling": "중앙집중식 에러 핸들러",
|
|
25
|
-
"validation": "DTO와 validation 미들웨어 사용"
|
|
26
|
-
},
|
|
27
|
-
"best_practices": [
|
|
28
|
-
"RESTful 원칙 준수",
|
|
29
|
-
"적절한 HTTP 상태 코드 사용",
|
|
30
|
-
"요청/응답 DTO 정의",
|
|
31
|
-
"비즈니스 로직과 컨트롤러 분리",
|
|
32
|
-
"트랜잭션 관리"
|
|
33
|
-
]
|
|
34
|
-
},
|
|
35
|
-
"prompts": {
|
|
36
|
-
"api_design": "RESTful 원칙을 따르며 확장 가능하고 유지보수가 쉬운 API를 설계해주세요.",
|
|
37
|
-
"security": "OWASP Top 10을 고려하여 보안이 강화된 API를 구현해주세요.",
|
|
38
|
-
"performance": "캐싱, 쿼리 최적화, 비동기 처리를 활용하여 고성능 API를 만들어주세요."
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const args = process.argv.slice(2);
|
|
7
|
-
const command = args[0];
|
|
8
|
-
const subcommand = args[1];
|
|
9
|
-
|
|
10
|
-
const projectRoot = path.resolve(__dirname, '../..');
|
|
11
|
-
const aiwfDir = path.join(projectRoot, '.aiwf');
|
|
12
|
-
const featureLedgerPath = path.join(aiwfDir, 'feature-ledger.json');
|
|
13
|
-
const configPath = path.join(aiwfDir, 'config.json');
|
|
14
|
-
|
|
15
|
-
// Feature Ledger 관련 명령어
|
|
16
|
-
if (command === 'feature') {
|
|
17
|
-
const ledger = JSON.parse(fs.readFileSync(featureLedgerPath, 'utf8'));
|
|
18
|
-
|
|
19
|
-
switch (subcommand) {
|
|
20
|
-
case 'list':
|
|
21
|
-
console.log('\n📋 Feature Ledger\n');
|
|
22
|
-
ledger.features.forEach(feature => {
|
|
23
|
-
const status = {
|
|
24
|
-
completed: '✅',
|
|
25
|
-
in_progress: '🔄',
|
|
26
|
-
planned: '📝'
|
|
27
|
-
}[feature.status];
|
|
28
|
-
console.log(`${status} [${feature.id}] ${feature.name}`);
|
|
29
|
-
console.log(` ${feature.description}`);
|
|
30
|
-
if (feature.endpoints && feature.endpoints.length > 0) {
|
|
31
|
-
console.log(` Endpoints: ${feature.endpoints.join(', ')}`);
|
|
32
|
-
}
|
|
33
|
-
console.log(` Tags: ${feature.tags.join(', ')}`);
|
|
34
|
-
console.log();
|
|
35
|
-
});
|
|
36
|
-
console.log(`총 ${ledger.features.length}개 기능`);
|
|
37
|
-
break;
|
|
38
|
-
|
|
39
|
-
case 'stats':
|
|
40
|
-
console.log('\n📊 Feature 통계\n');
|
|
41
|
-
console.log(`총 기능: ${ledger.statistics.total_features}`);
|
|
42
|
-
console.log(`완료: ${ledger.statistics.completed}`);
|
|
43
|
-
console.log(`진행중: ${ledger.statistics.in_progress}`);
|
|
44
|
-
console.log(`계획됨: ${ledger.statistics.planned}`);
|
|
45
|
-
console.log(`총 엔드포인트: ${ledger.statistics.total_endpoints || 0}`);
|
|
46
|
-
break;
|
|
47
|
-
|
|
48
|
-
default:
|
|
49
|
-
console.log('사용법: npm run aiwf feature [list|stats]');
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// API 관련 명령어
|
|
54
|
-
else if (command === 'api') {
|
|
55
|
-
switch (subcommand) {
|
|
56
|
-
case 'docs':
|
|
57
|
-
console.log('API 문서 업데이트 중...');
|
|
58
|
-
console.log('Swagger 문서가 /docs 경로에서 제공됩니다.');
|
|
59
|
-
break;
|
|
60
|
-
|
|
61
|
-
case 'validate':
|
|
62
|
-
console.log('API 스펙 검증 중...');
|
|
63
|
-
// 실제 구현에서는 OpenAPI 스펙 검증 로직
|
|
64
|
-
console.log('✅ API 스펙이 유효합니다.');
|
|
65
|
-
break;
|
|
66
|
-
|
|
67
|
-
default:
|
|
68
|
-
console.log('사용법: npm run aiwf api [docs|validate]');
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// 상태 명령어
|
|
73
|
-
else if (command === 'status') {
|
|
74
|
-
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
75
|
-
const ledger = JSON.parse(fs.readFileSync(featureLedgerPath, 'utf8'));
|
|
76
|
-
|
|
77
|
-
console.log('\n🚀 AIWF API 서버 상태\n');
|
|
78
|
-
console.log(`프로젝트: ${config.project_name}`);
|
|
79
|
-
console.log(`타입: ${config.project_type}`);
|
|
80
|
-
console.log(`프레임워크: ${config.framework}`);
|
|
81
|
-
console.log(`버전: ${config.version}`);
|
|
82
|
-
console.log();
|
|
83
|
-
console.log('📊 통계:');
|
|
84
|
-
console.log(`- 총 기능: ${ledger.statistics.total_features}`);
|
|
85
|
-
console.log(`- 총 엔드포인트: ${ledger.statistics.total_endpoints || 0}`);
|
|
86
|
-
console.log();
|
|
87
|
-
console.log('🤖 AI 페르소나:', config.features.ai_persona.default);
|
|
88
|
-
console.log('📦 Context 압축:', config.features.context_compression.level);
|
|
89
|
-
console.log('📚 API 문서화:', config.features.api_documentation.swagger ? 'Swagger 활성화' : '비활성화');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// 도움말
|
|
93
|
-
else {
|
|
94
|
-
console.log(`
|
|
95
|
-
AIWF CLI - AI Workflow Framework (API Server)
|
|
96
|
-
|
|
97
|
-
사용법: npm run aiwf [command] [subcommand]
|
|
98
|
-
|
|
99
|
-
명령어:
|
|
100
|
-
status 프로젝트 상태 보기
|
|
101
|
-
feature list 기능 목록 보기
|
|
102
|
-
feature stats 기능 통계 보기
|
|
103
|
-
api docs API 문서 업데이트
|
|
104
|
-
api validate API 스펙 검증
|
|
105
|
-
|
|
106
|
-
예시:
|
|
107
|
-
npm run aiwf status
|
|
108
|
-
npm run aiwf feature list
|
|
109
|
-
npm run aiwf api docs
|
|
110
|
-
`);
|
|
111
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# Application
|
|
2
|
-
NODE_ENV=development
|
|
3
|
-
PORT=3000
|
|
4
|
-
HOST=localhost
|
|
5
|
-
|
|
6
|
-
# Security
|
|
7
|
-
JWT_SECRET=your-super-secret-jwt-key-change-this
|
|
8
|
-
JWT_EXPIRES_IN=7d
|
|
9
|
-
BCRYPT_ROUNDS=10
|
|
10
|
-
|
|
11
|
-
# Database (uncomment and configure as needed)
|
|
12
|
-
# DB_HOST=localhost
|
|
13
|
-
# DB_PORT=5432
|
|
14
|
-
# DB_NAME=myapp
|
|
15
|
-
# DB_USER=myuser
|
|
16
|
-
# DB_PASSWORD=mypassword
|
|
17
|
-
|
|
18
|
-
# AIWF Settings
|
|
19
|
-
AIWF_ENABLED=true
|
|
20
|
-
AIWF_TOKEN_LIMIT=100000
|
|
21
|
-
AIWF_COMPRESSION_LEVEL=balanced
|
|
22
|
-
|
|
23
|
-
# API Rate Limiting
|
|
24
|
-
RATE_LIMIT_WINDOW_MS=900000
|
|
25
|
-
RATE_LIMIT_MAX_REQUESTS=100
|
|
26
|
-
|
|
27
|
-
# Logging
|
|
28
|
-
LOG_LEVEL=info
|
|
29
|
-
LOG_FORMAT=json
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"parser": "@typescript-eslint/parser",
|
|
3
|
-
"extends": [
|
|
4
|
-
"eslint:recommended",
|
|
5
|
-
"plugin:@typescript-eslint/recommended"
|
|
6
|
-
],
|
|
7
|
-
"parserOptions": {
|
|
8
|
-
"ecmaVersion": 2022,
|
|
9
|
-
"sourceType": "module",
|
|
10
|
-
"project": "./tsconfig.json"
|
|
11
|
-
},
|
|
12
|
-
"rules": {
|
|
13
|
-
"@typescript-eslint/explicit-function-return-type": "off",
|
|
14
|
-
"@typescript-eslint/no-explicit-any": "warn",
|
|
15
|
-
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
|
|
16
|
-
"no-console": ["warn", { "allow": ["warn", "error"] }]
|
|
17
|
-
},
|
|
18
|
-
"env": {
|
|
19
|
-
"node": true,
|
|
20
|
-
"es2022": true,
|
|
21
|
-
"jest": true
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# {{projectName}}
|
|
2
|
-
|
|
3
|
-
AIWF가 통합된 Express + TypeScript RESTful API 서버입니다.
|
|
4
|
-
|
|
5
|
-
## 시작하기
|
|
6
|
-
|
|
7
|
-
### 개발 서버 실행
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install
|
|
11
|
-
cp .env.example .env
|
|
12
|
-
npm run dev
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
서버가 [http://localhost:3000](http://localhost:3000)에서 실행됩니다.
|
|
16
|
-
|
|
17
|
-
### API 문서
|
|
18
|
-
|
|
19
|
-
Swagger UI: [http://localhost:3000/docs](http://localhost:3000/docs)
|
|
20
|
-
|
|
21
|
-
### 빌드
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npm run build
|
|
25
|
-
npm start
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 기술 스택
|
|
29
|
-
|
|
30
|
-
- **Express 4** - 웹 프레임워크
|
|
31
|
-
- **TypeScript** - 타입 안정성
|
|
32
|
-
- **JWT** - 인증
|
|
33
|
-
- **Swagger** - API 문서화
|
|
34
|
-
- **Winston** - 로깅
|
|
35
|
-
- **Jest** - 테스팅
|
|
36
|
-
- **AIWF** - AI 지원 개발 워크플로우
|
|
37
|
-
|
|
38
|
-
## 프로젝트 구조
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
src/
|
|
42
|
-
├── config/ # 설정 파일
|
|
43
|
-
├── controllers/ # 요청 핸들러
|
|
44
|
-
├── middleware/ # Express 미들웨어
|
|
45
|
-
├── models/ # 데이터 모델
|
|
46
|
-
├── routes/ # API 라우트 정의
|
|
47
|
-
├── services/ # 비즈니스 로직
|
|
48
|
-
├── utils/ # 유틸리티 함수
|
|
49
|
-
└── types/ # TypeScript 타입 정의
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## API 엔드포인트
|
|
53
|
-
|
|
54
|
-
### 인증
|
|
55
|
-
|
|
56
|
-
- `POST /api/v1/auth/register` - 회원가입
|
|
57
|
-
- `POST /api/v1/auth/login` - 로그인
|
|
58
|
-
|
|
59
|
-
### 상태
|
|
60
|
-
|
|
61
|
-
- `GET /health` - 헬스체크
|
|
62
|
-
- `GET /api/v1/status` - API 상태
|
|
63
|
-
|
|
64
|
-
### AIWF
|
|
65
|
-
|
|
66
|
-
- `GET /api/aiwf/features` - Feature Ledger 조회
|
|
67
|
-
- `GET /api/aiwf/token-usage` - 토큰 사용량 조회
|
|
68
|
-
- `GET /api/aiwf/context` - Context 상태 조회
|
|
69
|
-
|
|
70
|
-
## AIWF 기능
|
|
71
|
-
|
|
72
|
-
### Feature Ledger
|
|
73
|
-
|
|
74
|
-
API 엔드포인트 개발을 자동으로 추적합니다.
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
npm run aiwf:feature list # 기능 목록 보기
|
|
78
|
-
npm run aiwf:feature stats # 통계 보기
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### API 문서 자동화
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
npm run aiwf:api docs # API 문서 업데이트
|
|
85
|
-
npm run aiwf:api validate # API 스펙 검증
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### AI 페르소나
|
|
89
|
-
|
|
90
|
-
- `backend-engineer` - 백엔드 개발 (기본값)
|
|
91
|
-
- `api-architect` - API 설계
|
|
92
|
-
- `database-specialist` - 데이터베이스
|
|
93
|
-
- `security-auditor` - 보안 감사
|
|
94
|
-
- `performance-optimizer` - 성능 최적화
|
|
95
|
-
|
|
96
|
-
## 개발 가이드
|
|
97
|
-
|
|
98
|
-
### 새 API 엔드포인트 추가
|
|
99
|
-
|
|
100
|
-
1. 라우트 정의 (`src/routes/`)
|
|
101
|
-
2. 컨트롤러 구현 (`src/controllers/`)
|
|
102
|
-
3. 서비스 로직 작성 (`src/services/`)
|
|
103
|
-
4. 입력 검증 추가
|
|
104
|
-
5. Swagger 문서 작성
|
|
105
|
-
|
|
106
|
-
### 미들웨어 추가
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
// src/middleware/myMiddleware.ts
|
|
110
|
-
export const myMiddleware = (req: Request, res: Response, next: NextFunction) => {
|
|
111
|
-
// 미들웨어 로직
|
|
112
|
-
next();
|
|
113
|
-
};
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### 환경 변수
|
|
117
|
-
|
|
118
|
-
`.env` 파일 설정:
|
|
119
|
-
|
|
120
|
-
```env
|
|
121
|
-
NODE_ENV=development
|
|
122
|
-
PORT=3000
|
|
123
|
-
JWT_SECRET=your-secret-key
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## 테스트
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
# 전체 테스트 실행
|
|
130
|
-
npm test
|
|
131
|
-
|
|
132
|
-
# 감시 모드
|
|
133
|
-
npm run test:watch
|
|
134
|
-
|
|
135
|
-
# 커버리지 리포트
|
|
136
|
-
npm test -- --coverage
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## 보안
|
|
140
|
-
|
|
141
|
-
- Helmet.js로 보안 헤더 설정
|
|
142
|
-
- Rate limiting 적용
|
|
143
|
-
- JWT 토큰 인증
|
|
144
|
-
- 입력 검증 (express-validator)
|
|
145
|
-
- CORS 설정
|
|
146
|
-
|
|
147
|
-
## 배포
|
|
148
|
-
|
|
149
|
-
### Docker
|
|
150
|
-
|
|
151
|
-
```dockerfile
|
|
152
|
-
FROM node:18-alpine
|
|
153
|
-
WORKDIR /app
|
|
154
|
-
COPY package*.json ./
|
|
155
|
-
RUN npm ci --only=production
|
|
156
|
-
COPY . .
|
|
157
|
-
RUN npm run build
|
|
158
|
-
EXPOSE 3000
|
|
159
|
-
CMD ["npm", "start"]
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### PM2
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
npm run build
|
|
166
|
-
pm2 start dist/index.js --name {{projectName}}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## 라이선스
|
|
170
|
-
|
|
171
|
-
MIT
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
preset: 'ts-jest',
|
|
3
|
-
testEnvironment: 'node',
|
|
4
|
-
roots: ['<rootDir>/src', '<rootDir>/tests'],
|
|
5
|
-
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.ts$': 'ts-jest',
|
|
8
|
-
},
|
|
9
|
-
collectCoverageFrom: [
|
|
10
|
-
'src/**/*.ts',
|
|
11
|
-
'!src/**/*.d.ts',
|
|
12
|
-
'!src/**/*.interface.ts',
|
|
13
|
-
'!src/index.ts',
|
|
14
|
-
],
|
|
15
|
-
moduleNameMapper: {
|
|
16
|
-
'^@/(.*)$': '<rootDir>/src/$1',
|
|
17
|
-
'^@config/(.*)$': '<rootDir>/src/config/$1',
|
|
18
|
-
'^@controllers/(.*)$': '<rootDir>/src/controllers/$1',
|
|
19
|
-
'^@middleware/(.*)$': '<rootDir>/src/middleware/$1',
|
|
20
|
-
'^@models/(.*)$': '<rootDir>/src/models/$1',
|
|
21
|
-
'^@routes/(.*)$': '<rootDir>/src/routes/$1',
|
|
22
|
-
'^@services/(.*)$': '<rootDir>/src/services/$1',
|
|
23
|
-
'^@utils/(.*)$': '<rootDir>/src/utils/$1',
|
|
24
|
-
'^@types/(.*)$': '<rootDir>/src/types/$1',
|
|
25
|
-
},
|
|
26
|
-
};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{projectName}}",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"description": "AIWF 통합 Express API 서버",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "nodemon",
|
|
8
|
-
"build": "tsc",
|
|
9
|
-
"start": "node dist/index.js",
|
|
10
|
-
"test": "jest",
|
|
11
|
-
"test:watch": "jest --watch",
|
|
12
|
-
"lint": "eslint . --ext .ts",
|
|
13
|
-
"aiwf": "node .aiwf/scripts/cli.js",
|
|
14
|
-
"aiwf:status": "npm run aiwf status",
|
|
15
|
-
"aiwf:feature": "npm run aiwf feature",
|
|
16
|
-
"aiwf:api": "npm run aiwf api"
|
|
17
|
-
},
|
|
18
|
-
"keywords": [
|
|
19
|
-
"api",
|
|
20
|
-
"express",
|
|
21
|
-
"typescript",
|
|
22
|
-
"aiwf"
|
|
23
|
-
],
|
|
24
|
-
"author": "",
|
|
25
|
-
"license": "MIT",
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"express": "^4.18.2",
|
|
28
|
-
"cors": "^2.8.5",
|
|
29
|
-
"helmet": "^7.0.0",
|
|
30
|
-
"compression": "^1.7.4",
|
|
31
|
-
"dotenv": "^16.3.1",
|
|
32
|
-
"jsonwebtoken": "^9.0.1",
|
|
33
|
-
"bcryptjs": "^2.4.3",
|
|
34
|
-
"express-validator": "^7.0.1",
|
|
35
|
-
"swagger-jsdoc": "^6.2.8",
|
|
36
|
-
"swagger-ui-express": "^5.0.0",
|
|
37
|
-
"winston": "^3.9.0",
|
|
38
|
-
"express-rate-limit": "^6.8.0"
|
|
39
|
-
},
|
|
40
|
-
"devDependencies": {
|
|
41
|
-
"@types/express": "^4.17.17",
|
|
42
|
-
"@types/node": "^20.0.0",
|
|
43
|
-
"@types/cors": "^2.8.13",
|
|
44
|
-
"@types/compression": "^1.7.2",
|
|
45
|
-
"@types/jsonwebtoken": "^9.0.2",
|
|
46
|
-
"@types/bcryptjs": "^2.4.2",
|
|
47
|
-
"@types/swagger-jsdoc": "^6.0.1",
|
|
48
|
-
"@types/swagger-ui-express": "^4.1.3",
|
|
49
|
-
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
|
50
|
-
"@typescript-eslint/parser": "^5.60.0",
|
|
51
|
-
"typescript": "^5.1.0",
|
|
52
|
-
"ts-node": "^10.9.0",
|
|
53
|
-
"nodemon": "^3.0.0",
|
|
54
|
-
"eslint": "^8.43.0",
|
|
55
|
-
"jest": "^29.5.0",
|
|
56
|
-
"@types/jest": "^29.5.0",
|
|
57
|
-
"ts-jest": "^29.1.0",
|
|
58
|
-
"supertest": "^6.3.0",
|
|
59
|
-
"@types/supertest": "^2.0.12"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import express, { Application } from 'express';
|
|
2
|
-
import cors from 'cors';
|
|
3
|
-
import helmet from 'helmet';
|
|
4
|
-
import compression from 'compression';
|
|
5
|
-
import rateLimit from 'express-rate-limit';
|
|
6
|
-
import swaggerUi from 'swagger-ui-express';
|
|
7
|
-
import { swaggerSpec } from '@config/swagger';
|
|
8
|
-
import { errorHandler } from '@middleware/errorHandler';
|
|
9
|
-
import { notFoundHandler } from '@middleware/notFoundHandler';
|
|
10
|
-
import { requestLogger } from '@middleware/requestLogger';
|
|
11
|
-
import { aiwfMiddleware } from '@middleware/aiwfMiddleware';
|
|
12
|
-
import routes from '@routes/index';
|
|
13
|
-
|
|
14
|
-
const app: Application = express();
|
|
15
|
-
|
|
16
|
-
// Security middleware
|
|
17
|
-
app.use(helmet());
|
|
18
|
-
app.use(cors());
|
|
19
|
-
|
|
20
|
-
// Rate limiting
|
|
21
|
-
const limiter = rateLimit({
|
|
22
|
-
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '900000'),
|
|
23
|
-
max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS || '100'),
|
|
24
|
-
message: 'Too many requests from this IP, please try again later.',
|
|
25
|
-
});
|
|
26
|
-
app.use('/api', limiter);
|
|
27
|
-
|
|
28
|
-
// Body parsing middleware
|
|
29
|
-
app.use(express.json({ limit: '10mb' }));
|
|
30
|
-
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
|
31
|
-
|
|
32
|
-
// Compression middleware
|
|
33
|
-
app.use(compression());
|
|
34
|
-
|
|
35
|
-
// Request logging
|
|
36
|
-
app.use(requestLogger);
|
|
37
|
-
|
|
38
|
-
// AIWF integration
|
|
39
|
-
app.use(aiwfMiddleware);
|
|
40
|
-
|
|
41
|
-
// API Documentation
|
|
42
|
-
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
|
|
43
|
-
|
|
44
|
-
// Health check
|
|
45
|
-
app.get('/health', (req, res) => {
|
|
46
|
-
res.status(200).json({
|
|
47
|
-
status: 'healthy',
|
|
48
|
-
timestamp: new Date().toISOString(),
|
|
49
|
-
uptime: process.uptime(),
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// API routes
|
|
54
|
-
app.use('/api', routes);
|
|
55
|
-
|
|
56
|
-
// Error handlers
|
|
57
|
-
app.use(notFoundHandler);
|
|
58
|
-
app.use(errorHandler);
|
|
59
|
-
|
|
60
|
-
export default app;
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import swaggerJsdoc from 'swagger-jsdoc';
|
|
2
|
-
import { version } from '../../package.json';
|
|
3
|
-
|
|
4
|
-
const options: swaggerJsdoc.Options = {
|
|
5
|
-
definition: {
|
|
6
|
-
openapi: '3.0.0',
|
|
7
|
-
info: {
|
|
8
|
-
title: '{{projectName}} API',
|
|
9
|
-
version,
|
|
10
|
-
description: 'AIWF 통합 Express API 서버',
|
|
11
|
-
contact: {
|
|
12
|
-
name: 'API Support',
|
|
13
|
-
email: 'support@example.com',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
servers: [
|
|
17
|
-
{
|
|
18
|
-
url: `http://localhost:${process.env.PORT || 3000}`,
|
|
19
|
-
description: 'Development server',
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
components: {
|
|
23
|
-
securitySchemes: {
|
|
24
|
-
bearerAuth: {
|
|
25
|
-
type: 'http',
|
|
26
|
-
scheme: 'bearer',
|
|
27
|
-
bearerFormat: 'JWT',
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
security: [{
|
|
32
|
-
bearerAuth: [],
|
|
33
|
-
}],
|
|
34
|
-
},
|
|
35
|
-
apis: ['./src/routes/**/*.ts', './src/models/**/*.ts'],
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const swaggerSpec = swaggerJsdoc(options);
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from 'express';
|
|
2
|
-
import fs from 'fs/promises';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
export const aiwfController = {
|
|
6
|
-
|
|
7
|
-
getTokenUsage: async (req: Request, res: Response, next: NextFunction) => {
|
|
8
|
-
try {
|
|
9
|
-
// 실제 구현에서는 토큰 사용량을 추적하는 로직 필요
|
|
10
|
-
const mockData = {
|
|
11
|
-
total: parseInt(process.env.AIWF_TOKEN_LIMIT || '100000'),
|
|
12
|
-
used: 45000,
|
|
13
|
-
remaining: 55000,
|
|
14
|
-
percentage: 45,
|
|
15
|
-
history: [
|
|
16
|
-
{
|
|
17
|
-
date: new Date().toISOString(),
|
|
18
|
-
tokens: 1500,
|
|
19
|
-
action: 'API endpoint creation',
|
|
20
|
-
endpoint: 'POST /api/v1/users',
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
res.json({
|
|
26
|
-
success: true,
|
|
27
|
-
data: mockData,
|
|
28
|
-
});
|
|
29
|
-
} catch (error) {
|
|
30
|
-
next(error);
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
getContextStatus: async (req: Request, res: Response, next: NextFunction) => {
|
|
35
|
-
try {
|
|
36
|
-
const configPath = path.join(process.cwd(), '.aiwf', 'config.json');
|
|
37
|
-
const configData = await fs.readFile(configPath, 'utf-8');
|
|
38
|
-
const config = JSON.parse(configData);
|
|
39
|
-
|
|
40
|
-
res.json({
|
|
41
|
-
success: true,
|
|
42
|
-
data: {
|
|
43
|
-
compressionLevel: config.features.context_compression.level,
|
|
44
|
-
cacheEnabled: config.features.context_compression.cache_enabled,
|
|
45
|
-
tokenLimit: config.features.context_compression.token_limit,
|
|
46
|
-
activePersona: config.features.ai_persona.default,
|
|
47
|
-
availablePersonas: config.features.ai_persona.available,
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
} catch (error) {
|
|
51
|
-
next(error);
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
};
|