@axyl-tcb/create-template 1.0.22 → 1.0.24
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/lib/scaffold.js +16 -3
- package/package.json +1 -1
- package/template/CLAUDE.minimal.md +45 -0
- package/template/README.minimal.md +2 -0
package/lib/scaffold.js
CHANGED
|
@@ -20,9 +20,12 @@ function validateProjectName(name) {
|
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
// README.minimal.md 는 최소(N) 구성 전용
|
|
24
|
-
// scaffold() 가 최소 모드일 때만 README.md 로 사용한다.
|
|
25
|
-
const COPY_EXCLUDE = new Set([
|
|
23
|
+
// README.minimal.md / CLAUDE.minimal.md 는 최소(N) 구성 전용 소스 — 생성 프로젝트에 그대로
|
|
24
|
+
// 복사하지 않고, scaffold() 가 최소 모드일 때만 각각 README.md / CLAUDE.md 로 사용한다.
|
|
25
|
+
const COPY_EXCLUDE = new Set([
|
|
26
|
+
'node_modules', 'dist', '.git', '.npmignore',
|
|
27
|
+
'README.minimal.md', 'CLAUDE.minimal.md',
|
|
28
|
+
]);
|
|
26
29
|
|
|
27
30
|
/**
|
|
28
31
|
* 디렉토리를 재귀적으로 복사한다.
|
|
@@ -90,6 +93,10 @@ function pruneTestArtifacts(targetDir) {
|
|
|
90
93
|
if (pkg.dependencies) {
|
|
91
94
|
delete pkg.dependencies['@cloudbase/node-sdk'];
|
|
92
95
|
}
|
|
96
|
+
// 테스트가 없는 최소 구성이므로 vitest 도 불필요 (설치만 되고 못 돌리는 상태 방지)
|
|
97
|
+
if (pkg.devDependencies) {
|
|
98
|
+
delete pkg.devDependencies['vitest'];
|
|
99
|
+
}
|
|
93
100
|
// lodash.unset override 는 @cloudbase/database 전이 의존 대상 → 함께 제거
|
|
94
101
|
delete pkg.overrides;
|
|
95
102
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
@@ -126,6 +133,12 @@ function scaffold(projectName, targetDir, templateDir, options = {}) {
|
|
|
126
133
|
if (fs.existsSync(minReadme)) {
|
|
127
134
|
fs.copyFileSync(minReadme, path.join(targetDir, 'README.md'));
|
|
128
135
|
}
|
|
136
|
+
// 최소 구성은 예제가 basic/index.ts 한 개뿐이라, 연결된 AI 에이전트(Claude 등)가
|
|
137
|
+
// 규약을 추론할 근거가 부족하다. 오리엔테이션용 CLAUDE.md 를 함께 둔다.
|
|
138
|
+
const minClaude = path.join(templateDir, 'CLAUDE.minimal.md');
|
|
139
|
+
if (fs.existsSync(minClaude)) {
|
|
140
|
+
fs.copyFileSync(minClaude, path.join(targetDir, 'CLAUDE.md'));
|
|
141
|
+
}
|
|
129
142
|
}
|
|
130
143
|
|
|
131
144
|
// package.json name 업데이트
|
package/package.json
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
이 프로젝트는 **Axyl TCB Cloud Function** 입니다(`@axyl-tcb/middleware` 기반, 최소 구성).
|
|
4
|
+
함수를 만들거나 수정할 때 아래 규약을 따르세요.
|
|
5
|
+
|
|
6
|
+
## 핸들러 작성
|
|
7
|
+
- 진입점은 `export const main = createAxylHandler(baseHandler)`.
|
|
8
|
+
- `baseHandler: AxylBaseHandler<ReqDto, ResDto>` — `(event, context)` 를 받아 **비즈니스 데이터만** 반환하면, 미들웨어가 표준 응답 `{ success, code, metadata, data }` 로 감쌉니다.
|
|
9
|
+
- 함수 파일은 `src/functions/<theme>/<name>.ts`. `npm run build` 가 자동 인식하므로 빌드 스크립트는 손대지 않습니다.
|
|
10
|
+
|
|
11
|
+
## context — 검증 완료된 신뢰값
|
|
12
|
+
- `context.playerId` — Gateway 가 주입한 플레이어 ID.
|
|
13
|
+
- `context.aud.gameIndex` / `aud.appIndex` / `aud.companyIndex` — 서명된 `X-Hive-Aud` 파싱값.
|
|
14
|
+
- ⚠️ **데이터 격리(WHERE 절)에는 반드시 `context.aud.gameIndex` 를 사용**하세요. event body 의 `gameIndex`(= `context.gameIndex`)는 위변조 가능합니다.
|
|
15
|
+
- `context.traceId` — 로그 상관관계용(W3C `traceparent`). ⚠️ **관측 전용** — 보안 판단이나 멱등성 키로 쓰지 마세요.
|
|
16
|
+
- `context.logger?.info(msg, meta)` / `error`.
|
|
17
|
+
|
|
18
|
+
## 에러
|
|
19
|
+
- `throw new AxylMiddlewareError(ERROR_CODES.X, '메시지')`. 코드는 **다음 6개뿐이며 새로 지어내지 않습니다**:
|
|
20
|
+
`HIVE_PLAYER_ID_REQUIRED`, `HIVE_AUD_REQUIRED`, `INVALID_AUD_FORMAT`, `GAME_INDEX_REQUIRED`, `INVALID_PARAMETER`, `INTERNAL_ERROR`.
|
|
21
|
+
- 처리되지 않은 예외는 자동으로 `INTERNAL_ERROR` 로 변환됩니다.
|
|
22
|
+
|
|
23
|
+
## 데이터 모듈 (subpath)
|
|
24
|
+
- MySQL: `import { pool, transaction } from '@axyl-tcb/middleware/db'` (`mysql2` 포함). → [MYSQL.md](./MYSQL.md)
|
|
25
|
+
- Cloud Storage: `@axyl-tcb/middleware/storage` — `npm i @cloudbase/node-sdk` 필요. → [STORAGE.md](./STORAGE.md)
|
|
26
|
+
- Document DB: `@axyl-tcb/middleware/docdb` — `npm i @cloudbase/node-sdk` 필요. → [DOCDB.md](./DOCDB.md)
|
|
27
|
+
- 파라미터는 항상 `?` 플레이스홀더로 바인딩(문자열 연결 금지). 멱등성은 클라이언트가 보낸 `idempotencyKey` 를 `(playerId, idempotencyKey)` 로 스코프합니다.
|
|
28
|
+
|
|
29
|
+
## cloudbaserc.json 등록
|
|
30
|
+
새 함수는 `functions` 배열에 추가합니다.
|
|
31
|
+
```json
|
|
32
|
+
{ "name": "<name>", "dir": "./dist", "handler": "<name>.main", "runtime": "Nodejs18.15", "timeout": 30, "memorySize": 256, "installDependency": false }
|
|
33
|
+
```
|
|
34
|
+
`envVariables` 는 사용하는 모듈에 맞춰: MySQL=`DB_HOST/DB_PORT/DB_USER/DB_PASSWORD/DB_NAME`, Storage=`TCB_ENV_ID`, Document DB=`TCB_ENV_ID/TCB_DOCDB_INSTANCE/TCB_DOCDB_DATABASE`.
|
|
35
|
+
|
|
36
|
+
## 빌드 / 배포
|
|
37
|
+
- 빌드: `npm run build` (esbuild, `dist/<name>.js`).
|
|
38
|
+
- 배포: TCB CLI 필요 — `npm i -g @cloudbase/cli && tcb login` 후 `npm run deploy:build`. 대상 환경은 `cloudbaserc.json` 의 `envId`.
|
|
39
|
+
|
|
40
|
+
## 정확한 타입이 필요하면
|
|
41
|
+
모든 타입의 정답은 `@axyl-tcb/middleware` 의 타입 선언입니다 — `node_modules/@axyl-tcb/middleware/dist/*.d.ts` (예: `types.d.ts`, `factory/createAxylHandler.d.ts`, `lib/db.d.ts`). 불확실하면 추측하지 말고 여기서 확인하세요.
|
|
42
|
+
|
|
43
|
+
## 이 프로젝트의 특성
|
|
44
|
+
- **테스트가 없는 최소 구성**입니다(vitest 미설치). 테스트를 추가하려면 `npm i -D vitest` 후 MYSQL/STORAGE/DOCDB.md 의 *테스트* 섹션 mock 패턴을 사용하세요.
|
|
45
|
+
- 예제·테스트가 포함된 풀 구성이 필요하면 `npm create @axyl-tcb/template` 를 테스트 포함(Y)으로 다시 실행하면 됩니다.
|
|
@@ -49,6 +49,8 @@ export const main = createAxylHandler(baseHandler);
|
|
|
49
49
|
| Cloud Storage | [STORAGE.md](./STORAGE.md) | `npm i @cloudbase/node-sdk` 후 `@axyl-tcb/middleware/storage` 사용 |
|
|
50
50
|
| Document DB | [DOCDB.md](./DOCDB.md) | `npm i @cloudbase/node-sdk` 후 `@axyl-tcb/middleware/docdb` 사용 |
|
|
51
51
|
|
|
52
|
+
> Storage/Document DB 예제는 `src/functions/storage/` · `src/functions/docdb/` 경로를 쓰므로, 최소 구성에 추가할 때는 해당 디렉토리를 새로 만들면 됩니다(`npm run build` 가 자동 인식).
|
|
53
|
+
|
|
52
54
|
> 최소 구성은 `@cloudbase/node-sdk` 를 포함하지 않아 `npm audit` 가 깨끗합니다. Storage/Document DB 를 추가하면 `@cloudbase/node-sdk` 의 알려진 전이 취약점(high)이 함께 들어옵니다 — 불가피하며 [SECURITY.md](./SECURITY.md) 에 설명돼 있습니다.
|
|
53
55
|
|
|
54
56
|
## 배포
|