사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
모듈 규칙▾
스칼라 Constant
constant 파일 (*.constant.ts)은 스칼라의 스키마를 정의하는 곳입니다. via() 함수와 enumOf() 헬퍼를 사용하여 다른 모델에 임베드할 수 있는 타입 안전하고 재사용 가능한 값 객체를 생성합니다.
파일 구조 및 위치
Scalar 상수는 엄격한 명명 규칙과 디렉토리 구조를 따릅니다:
field설명
디렉토리
camelCase
파일
<scalarName>.constant.ts
스칼라 클래스
PascalCase
Enum 클래스
PascalCase
Enum 값
camelCase
via()를 사용한 기본 문법
via() 함수는 스칼라를 정의하는 기반입니다. field() 함수를 받는 콜백을 취하며, 이를 사용하여 각 필드의 타입과 옵션을 정의합니다.
기본 구조
간단한 실제 예시입니다:
restrictInfo.constant.ts
method설명
via((field) => ({...}))
타입이 지정된 필드를 가진 클래스를 생성합니다. 콜백은 field() 헬퍼 함수를 받습니다.
field(Type)
단일 필드를 정의합니다. 첫 번째 인수는 타입입니다 (String, Number, Date 등).
field(Type, { options })
선택적인 두 번째 인수는 기본값, 유효성 검사 등을 위한 옵션 객체입니다.
사용 가능한 필드 타입
Akan.js는 field() 함수와 함께 사용할 수 있는 여러 내장 타입을 제공합니다:
기본 타입
배열 타입은 타입을 대괄호로 감싸서 정의합니다:
배열 타입
선택적 필드는 .optional() 체인을 사용하여 정의할 수 있습니다:
fileMeta.constant.ts
enumOf()로 Enum 정의하기
enumOf() 함수는 타입이 지정된 enum 클래스를 생성합니다. 스칼라 필드에서 사용하기 전에 enum을 정의하세요.
기본 Enum
더 복잡한 enum의 경우 더 나은 타입 추론을 위해 "as const"를 사용하세요:
as const를 사용한 여러 enum
field설명
enumOf(name, values)
첫 번째 인수는 enum 이름 (dictionary/GraphQL에서 사용됨). 두 번째는 값 배열입니다.
camelCase 값
항상 enum 값에 camelCase를 사용하세요 (예: "waitPay", "WAIT_PAY" 아님).
as const
더 나은 TypeScript 타입 추론을 위해 값 배열에 'as const'를 추가하세요.
필드 옵션
field()의 두 번째 인수는 기본값, 유효성 검사 및 동작을 구성하는 옵션 객체입니다:
defaultAny | Function기본값 undefined
기본 필드 값 (정적 또는 팩토리 함수)
minNumber기본값 -
최소 숫자 값
maxNumber기본값 -
최대 숫자 값
minlengthNumber기본값 -
최소 문자열 길이
maxlengthNumber기본값 -
최대 문자열 길이
validateFunction기본값 -
커스텀 유효성 검사 함수
exampleAny기본값 -
문서화를 위한 예시 값
다양한 옵션 사용 방법입니다:
옵션 예시
🎯정적 vs 동적 기본값
상수에는 정적 값을 사용하세요 (0, "active"). 생성 시 계산되어야 하는 값에는 팩토리 함수를 사용하세요 (dayjs(), new ObjectId()).
✅커스텀 유효성 검사
validate 옵션은 true/false를 반환하거나 오류를 던지는 함수를 받습니다. 복잡한 유효성 검사 로직에 사용하세요.
인스턴스 메서드 추가하기
계산된 속성과 유틸리티 함수를 위해 스칼라 클래스에 인스턴스 메서드를 직접 추가할 수 있습니다:
인스턴스 메서드
💡
인스턴스 메서드는 'this'를 통해 모든 필드에 접근할 수 있습니다. 필드 값을 기반으로 한 계산에 사용하세요.
🔧
constant.ts에 정의된 메서드는 서버와 클라이언트 모두에서 사용 가능합니다. 서버 전용 로직은 document.ts를 대신 사용하세요.
흔한 실수
스칼라 상수를 정의할 때 다음과 같은 흔한 실수를 피하세요:
| 문제 | 잘못된 예 | 올바른 예 |
|---|---|---|
| Enum 케이스 | enumOf('status', ['ACTIVE']) | enumOf('status', ['active']) |
| 배열 문법 | field(Array<Int>) | field([Int]) |
| 동적 기본값 | { default: dayjs() } | { default: () => dayjs() } |
| 누락된 export | class Status extends enumOf(...) | export class Status extends enumOf(...) |
| 선택적 필드 | field(ID, { nullable: true }) | field(ID).optional() |
중요: 생성 시 계산되어야 하는 Date 기본값은 항상 팩토리 함수를 사용하세요: { default: () => dayjs() }
구현 체크리스트
- 파일 위치: __scalar/<camelCase>/<camelCase>.constant.ts
- '@akanjs/constant'에서 via import
- '@akanjs/base'에서 enumOf import (enum 사용 시)
- 모든 클래스 export (스칼라 및 enum)
- 클래스 이름에 PascalCase 사용
- enum 값에 camelCase 사용
- 배열에 [Type] 문법 사용
- 동적 기본값에 팩토리 함수 사용
- nullable 필드에 .optional() 사용
- 큰 enum 값 배열에 'as const' 추가
💡 프로 팁:
- • 스칼라를 집중적으로 유지하세요 - 너무 커지면 여러 스칼라로 분리
- • 스칼라는 값 객체입니다 - ID나 타임스탬프 필드 추가를 피하세요 (Model을 사용)
- • enum을 사용하는 스칼라 클래스 전에 enum을 정의하세요
- • i18n 지원을 위한 dictionary.ts 생성을 잊지 마세요