ワンクリックで
create-model
Effect Schema 기반 모델/요청 타입을 프로젝트 패턴에 맞게 스캐폴딩. barrel export, 테스트 파일 포함.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Effect Schema 기반 모델/요청 타입을 프로젝트 패턴에 맞게 스캐폴딩. barrel export, 테스트 파일 포함.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | create-model |
| description | Effect Schema 기반 모델/요청 타입을 프로젝트 패턴에 맞게 스캐폴딩. barrel export, 테스트 파일 포함. |
| disable-model-invocation | true |
Effect Schema(https://effect.website/docs/schema/introduction/) 원칙에 따라 모델을 생성합니다. 프로젝트 검증 규칙은 CLAUDE.md "Mandatory Validation" 참조.
/create-model <ModelName> [--type base|request|response] [--domain <domain>]
| type | 유효 도메인 |
|---|---|
| base | messages, kakao, kakao/bms*, naver, rcs |
* kakao/bms 주의: BMS 모델은 스키마 파일 + barrel export 외에 src/models/base/kakao/kakaoOption.ts의 bmsChatBubbleTypeSchema, baseBmsSchema, BMS_REQUIRED_FIELDS에도 통합이 필요합니다.
| request | common, iam, kakao, messages, voice |
| response | iam, kakao (또는 responses/ 루트에 직접 배치) |
# 예시
/create-model VoiceOption --type request --domain voice
생성 전 반드시 동일 도메인의 기존 모델을 Read 도구로 읽어서 일관성을 유지합니다.
import {Schema} from 'effect';
export const <modelName>Schema = Schema.Struct({
fieldName: Schema.String,
optionalField: Schema.optional(Schema.String),
// optional: 키 자체가 없을 수 있음 + NullOr: 값이 null일 수 있음
nullableField: Schema.optional(Schema.NullOr(Schema.String)),
status: Schema.Literal('ACTIVE', 'INACTIVE'),
});
export type <ModelName> = Schema.Schema.Type<typeof <modelName>Schema>;
| 대상 | 패턴 | 예시 |
|---|---|---|
| Schema 변수 | camelCase + Schema 접미사 | kakaoButtonSchema |
| Type | PascalCase | KakaoButton |
| 파일명 | camelCase | kakaoButton.ts |
export const buttonSchema = Schema.Union(
webButtonSchema,
appButtonSchema,
);
// 주의: normalize 목적의 transform은 round-trip을 보장하지 않음
export const phoneSchema = Schema.String.pipe(
Schema.transform(Schema.String, {
decode: removeHyphens,
encode: s => s,
}),
Schema.filter(s => /^[0-9]+$/.test(s), {
message: () => '숫자만 포함해야 합니다.',
}),
);
barrel-checker 에이전트 규칙에 따라 가장 가까운 index.ts에 re-export 추가.
체인이 src/index.ts까지 연결되는지 확인.
export {
type <ModelName>,
<modelName>Schema,
} from './<path>/<modelName>';
test/models/ 하위에 대응하는 테스트 파일:
import {Schema} from 'effect';
import {describe, expect, it} from 'vitest';
import {<modelName>Schema} from '@models/<path>/<modelName>';
describe('<modelName>Schema', () => {
it('should decode valid input', () => {
const result = Schema.decodeUnknownEither(<modelName>Schema)({ /* valid */ });
expect(result._tag).toBe('Right');
});
it('should reject invalid input', () => {
const result = Schema.decodeUnknownEither(<modelName>Schema)({ /* invalid */ });
expect(result._tag).toBe('Left');
});
it.each([
['null field', { field: null }],
['empty string', { field: '' }],
['missing required', {}],
])('should handle edge case: %s', (_label, input) => {
const result = Schema.decodeUnknownEither(<modelName>Schema)(input);
// assert based on schema definition
});
});
CLAUDE.md "Mandatory Validation" 순서대로 pnpm lint → pnpm test → pnpm build 실행.