@kms545487/contracts 0.1.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/dist/account.d.ts +14 -0
- package/dist/account.js +2 -0
- package/dist/catalog.d.ts +14 -0
- package/dist/catalog.js +2 -0
- package/dist/common.d.ts +6 -0
- package/dist/common.js +2 -0
- package/dist/counsel.d.ts +40 -0
- package/dist/counsel.js +2 -0
- package/dist/enrollment.d.ts +13 -0
- package/dist/enrollment.js +2 -0
- package/dist/event.d.ts +13 -0
- package/dist/event.js +2 -0
- package/dist/finance.d.ts +51 -0
- package/dist/finance.js +2 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +26 -0
- package/dist/inputs.d.ts +58 -0
- package/dist/inputs.js +2 -0
- package/dist/people.d.ts +35 -0
- package/dist/people.js +2 -0
- package/dist/session.d.ts +28 -0
- package/dist/session.js +2 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# @kms545487/contracts
|
|
2
|
+
|
|
3
|
+
프론트엔드(Next.js)와 백엔드(NestJS)가 공유하는 **도메인 계약** 단일 소스. 도메인 타입·enum·요청 DTO 형상을 담습니다.
|
|
4
|
+
|
|
5
|
+
빌드 시 `dist/`에 `.d.ts`(+빈 `.js`)를 emit합니다. 소비측은 `import type`으로만 가져가 런타임 의존이 없습니다.
|
|
6
|
+
|
|
7
|
+
## 빌드
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
npm run build # → dist/index.d.ts, dist/index.js
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 배포 (npm 레지스트리)
|
|
15
|
+
|
|
16
|
+
repo가 분리되어 있어 **원격/CI 빌드에서는 `file:../contracts`가 동작하지 않습니다** (옆에 contracts 폴더가 없음).
|
|
17
|
+
따라서 이 패키지를 배포하고, 소비측은 **버전**으로 의존해야 합니다.
|
|
18
|
+
|
|
19
|
+
> ⚠️ `@taco` 스코프: 공개 npm에 올리려면 `@taco` 조직을 소유해야 합니다.
|
|
20
|
+
> 소유하지 않으면 (a) 본인 스코프(`@yourorg/contracts`)로 이름을 바꾸거나,
|
|
21
|
+
> (b) **GitHub Packages**(조직 스코프) 사용을 권장합니다.
|
|
22
|
+
|
|
23
|
+
### 1) 배포
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd contracts
|
|
27
|
+
npm version patch # 0.1.0 → 0.1.1 (변경 시마다)
|
|
28
|
+
npm publish --access public # prepublishOnly가 자동 build
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### 2FA 오류(E403) 해결
|
|
32
|
+
npm은 publish에 2단계 인증을 요구합니다. 둘 중 하나:
|
|
33
|
+
|
|
34
|
+
- **일회성(OTP)**: 인증앱 6자리 코드로 즉시 publish
|
|
35
|
+
```bash
|
|
36
|
+
npm publish --access public --otp=123456
|
|
37
|
+
```
|
|
38
|
+
- **토큰(반복·CI 권장)**: npmjs.com → Access Tokens → **Granular/Automation token**
|
|
39
|
+
(publish 시 2FA bypass 가능)를 발급 → 환경변수로 주입 (이 폴더의 `.npmrc`가 `${NPM_TOKEN}` 사용)
|
|
40
|
+
```bash
|
|
41
|
+
export NPM_TOKEN=npm_xxxxx
|
|
42
|
+
npm publish --access public
|
|
43
|
+
```
|
|
44
|
+
CI에서는 `NPM_TOKEN`을 시크릿으로 등록하면 됩니다.
|
|
45
|
+
|
|
46
|
+
> 비공개로 두려면 `--access public` 대신 `publishConfig.access: "restricted"`(유료 플랜 필요).
|
|
47
|
+
|
|
48
|
+
### 2) 소비측(frontend·backend) 의존 전환
|
|
49
|
+
|
|
50
|
+
```jsonc
|
|
51
|
+
// package.json
|
|
52
|
+
{ "dependencies": { "@kms545487/contracts": "^0.1.0" } } // file:../contracts → 버전
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install # 레지스트리에서 설치 → CI 빌드 통과
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 로컬 개발 (미배포 변경분 사용)
|
|
60
|
+
|
|
61
|
+
배포 전 로컬에서 최신 계약을 쓰려면 `npm link` 사용:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
cd contracts && npm run build && npm link
|
|
65
|
+
cd ../frontend && npm link @kms545487/contracts
|
|
66
|
+
cd ../backend && npm link @kms545487/contracts
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 구성
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
src/
|
|
73
|
+
├─ common.ts # ID, ISODate, Audited
|
|
74
|
+
├─ account.ts # Account, AccountRole, WebIdCheckResult
|
|
75
|
+
├─ people.ts # Student, Parent, ParentStudent, Instructor
|
|
76
|
+
├─ catalog.ts # Subject, Course(hourlyRate)
|
|
77
|
+
├─ enrollment.ts # Enrollment
|
|
78
|
+
├─ session.ts # ClassSession, Attendance, SessionReport
|
|
79
|
+
├─ finance.ts # Payment, Transaction, Expense(ApprovalStatus), InstructorPayout
|
|
80
|
+
├─ counsel.ts # CounselForm, CounselRound
|
|
81
|
+
├─ event.ts # AcademyEvent, EventType, EventPriority
|
|
82
|
+
└─ inputs.ts # Create*Input (요청 DTO 형상)
|
|
83
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ID } from './common';
|
|
2
|
+
export type AccountRole = 'student' | 'parent' | 'instructor' | 'manager' | 'admin' | 'super_admin';
|
|
3
|
+
export type Account = {
|
|
4
|
+
id: ID;
|
|
5
|
+
webId: string;
|
|
6
|
+
name: string;
|
|
7
|
+
role: AccountRole;
|
|
8
|
+
};
|
|
9
|
+
export type WebIdCheckResult = {
|
|
10
|
+
webId: string;
|
|
11
|
+
exists: boolean;
|
|
12
|
+
name?: string;
|
|
13
|
+
role?: AccountRole;
|
|
14
|
+
};
|
package/dist/account.js
ADDED
package/dist/catalog.js
ADDED
package/dist/common.d.ts
ADDED
package/dist/common.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ID, ISODate } from './common';
|
|
2
|
+
export type CounselStatus = 'requested' | 'pending' | 'registered' | 'dropped';
|
|
3
|
+
export type CounselSource = 'internal_form' | 'naver_form' | 'google_form' | 'manual' | 'etc';
|
|
4
|
+
export type DesiredStartTime = 'immediately' | 'within_1_month' | 'within_2_3_months' | 'undecided';
|
|
5
|
+
export type LearningAtmosphere = 'self_directed' | 'normal' | 'needs_management';
|
|
6
|
+
export type StudentIntention = 'student_wants' | 'parent_only' | 'unknown';
|
|
7
|
+
export type CounselResult = 'positive' | 'neutral' | 'negative' | 'no_response' | 'registered';
|
|
8
|
+
export type CounselForm = {
|
|
9
|
+
id: ID;
|
|
10
|
+
applicantName: string;
|
|
11
|
+
applicantPhone?: string;
|
|
12
|
+
parentId?: ID;
|
|
13
|
+
studentId?: ID;
|
|
14
|
+
assignedStaffId?: ID;
|
|
15
|
+
status: CounselStatus;
|
|
16
|
+
source: CounselSource;
|
|
17
|
+
interestSubjectId?: ID;
|
|
18
|
+
interestCourseId?: ID;
|
|
19
|
+
academyExpectation?: string;
|
|
20
|
+
desiredStartTime?: DesiredStartTime;
|
|
21
|
+
learningAtmosphere?: LearningAtmosphere;
|
|
22
|
+
studentIntention?: StudentIntention;
|
|
23
|
+
weakness?: string;
|
|
24
|
+
nextContactAt?: ISODate;
|
|
25
|
+
createdAt: ISODate;
|
|
26
|
+
};
|
|
27
|
+
export type CounselRound = {
|
|
28
|
+
id: ID;
|
|
29
|
+
counselFormId: ID;
|
|
30
|
+
roundNo: number;
|
|
31
|
+
counselorId?: ID;
|
|
32
|
+
scheduledAt?: ISODate;
|
|
33
|
+
completedAt?: ISODate;
|
|
34
|
+
isCompleted: boolean;
|
|
35
|
+
summary?: string;
|
|
36
|
+
detail?: string;
|
|
37
|
+
result?: CounselResult;
|
|
38
|
+
nextAction?: string;
|
|
39
|
+
nextContactAt?: ISODate;
|
|
40
|
+
};
|
package/dist/counsel.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ID, ISODate, Audited } from './common';
|
|
2
|
+
export type EnrollmentStatus = 'active' | 'paused' | 'completed' | 'canceled';
|
|
3
|
+
export type Enrollment = {
|
|
4
|
+
id: ID;
|
|
5
|
+
studentId: ID;
|
|
6
|
+
courseId: ID;
|
|
7
|
+
roadmapId?: ID;
|
|
8
|
+
status: EnrollmentStatus;
|
|
9
|
+
totalSessions?: number;
|
|
10
|
+
completedSessions?: number;
|
|
11
|
+
memo?: string;
|
|
12
|
+
enrolledAt: ISODate;
|
|
13
|
+
} & Audited;
|
package/dist/event.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ID, ISODate, Audited } from './common';
|
|
2
|
+
export type EventType = 'notice' | 'exam' | 'holiday' | 'closure' | 'event';
|
|
3
|
+
export type EventPriority = 'low' | 'normal' | 'high';
|
|
4
|
+
export type AcademyEvent = {
|
|
5
|
+
id: ID;
|
|
6
|
+
title: string;
|
|
7
|
+
type: EventType;
|
|
8
|
+
priority: EventPriority;
|
|
9
|
+
startDate: ISODate;
|
|
10
|
+
endDate: ISODate;
|
|
11
|
+
allDay?: boolean;
|
|
12
|
+
memo?: string;
|
|
13
|
+
} & Audited;
|
package/dist/event.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ID, ISODate, Audited } from './common';
|
|
2
|
+
export type PaymentStatus = 'pending' | 'paid' | 'overdue' | 'refunded' | 'partial_refund';
|
|
3
|
+
export type PaymentMethod = 'card' | 'transfer' | 'cash' | 'point' | 'etc';
|
|
4
|
+
export type Payment = {
|
|
5
|
+
id: ID;
|
|
6
|
+
enrollmentId?: ID;
|
|
7
|
+
studentId: ID;
|
|
8
|
+
payerParentId?: ID;
|
|
9
|
+
amount: number;
|
|
10
|
+
paidAmount?: number;
|
|
11
|
+
status: PaymentStatus;
|
|
12
|
+
paymentMethod?: PaymentMethod;
|
|
13
|
+
dueAt?: ISODate;
|
|
14
|
+
paidAt?: ISODate;
|
|
15
|
+
memo?: string;
|
|
16
|
+
} & Audited;
|
|
17
|
+
export type TxDirection = 'in' | 'out';
|
|
18
|
+
export type Transaction = {
|
|
19
|
+
id: ID;
|
|
20
|
+
direction: TxDirection;
|
|
21
|
+
category: string;
|
|
22
|
+
label: string;
|
|
23
|
+
amount: number;
|
|
24
|
+
method?: string;
|
|
25
|
+
occurredAt: ISODate;
|
|
26
|
+
};
|
|
27
|
+
export type ApprovalStatus = 'requested' | 'approved' | 'rejected';
|
|
28
|
+
export type ExpenseCategory = 'supplies' | 'equipment' | 'books' | 'rent' | 'utility' | 'marketing' | 'meal' | 'etc';
|
|
29
|
+
export type Expense = {
|
|
30
|
+
id: ID;
|
|
31
|
+
category: ExpenseCategory;
|
|
32
|
+
title: string;
|
|
33
|
+
amount: number;
|
|
34
|
+
spentAt: ISODate;
|
|
35
|
+
vendor?: string;
|
|
36
|
+
memo?: string;
|
|
37
|
+
receiptUrl?: string;
|
|
38
|
+
status: ApprovalStatus;
|
|
39
|
+
} & Audited;
|
|
40
|
+
export type PayoutStatus = 'pending' | 'confirmed' | 'paid';
|
|
41
|
+
export type InstructorPayout = {
|
|
42
|
+
id: ID;
|
|
43
|
+
instructorId: ID;
|
|
44
|
+
periodStart: ISODate;
|
|
45
|
+
periodEnd: ISODate;
|
|
46
|
+
sessionCount?: number;
|
|
47
|
+
totalMinutes?: number;
|
|
48
|
+
amount: number;
|
|
49
|
+
status: PayoutStatus;
|
|
50
|
+
paidAt?: ISODate;
|
|
51
|
+
};
|
package/dist/finance.js
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './common';
|
|
2
|
+
export * from './account';
|
|
3
|
+
export * from './people';
|
|
4
|
+
export * from './catalog';
|
|
5
|
+
export * from './enrollment';
|
|
6
|
+
export * from './session';
|
|
7
|
+
export * from './finance';
|
|
8
|
+
export * from './counsel';
|
|
9
|
+
export * from './event';
|
|
10
|
+
export * from './inputs';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./common"), exports);
|
|
18
|
+
__exportStar(require("./account"), exports);
|
|
19
|
+
__exportStar(require("./people"), exports);
|
|
20
|
+
__exportStar(require("./catalog"), exports);
|
|
21
|
+
__exportStar(require("./enrollment"), exports);
|
|
22
|
+
__exportStar(require("./session"), exports);
|
|
23
|
+
__exportStar(require("./finance"), exports);
|
|
24
|
+
__exportStar(require("./counsel"), exports);
|
|
25
|
+
__exportStar(require("./event"), exports);
|
|
26
|
+
__exportStar(require("./inputs"), exports);
|
package/dist/inputs.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ID, ISODate } from './common';
|
|
2
|
+
import type { StudentStatus, ResidenceType } from './people';
|
|
3
|
+
import type { PaymentMethod, ExpenseCategory } from './finance';
|
|
4
|
+
import type { EventType, EventPriority } from './event';
|
|
5
|
+
export type CreateStudentInput = {
|
|
6
|
+
name: string;
|
|
7
|
+
englishName?: string;
|
|
8
|
+
phone?: string;
|
|
9
|
+
grade?: number;
|
|
10
|
+
schoolName?: string;
|
|
11
|
+
residenceType?: ResidenceType;
|
|
12
|
+
status?: StudentStatus;
|
|
13
|
+
memo?: string;
|
|
14
|
+
webId?: string;
|
|
15
|
+
};
|
|
16
|
+
export type CreateEnrollmentInput = {
|
|
17
|
+
studentId: ID;
|
|
18
|
+
courseId: ID;
|
|
19
|
+
roadmapId?: ID;
|
|
20
|
+
totalSessions?: number;
|
|
21
|
+
memo?: string;
|
|
22
|
+
};
|
|
23
|
+
export type CreatePaymentInput = {
|
|
24
|
+
studentId: ID;
|
|
25
|
+
enrollmentId?: ID;
|
|
26
|
+
payerParentId?: ID;
|
|
27
|
+
amount: number;
|
|
28
|
+
paymentMethod?: PaymentMethod;
|
|
29
|
+
};
|
|
30
|
+
export type CreateExpenseInput = {
|
|
31
|
+
category: ExpenseCategory;
|
|
32
|
+
title: string;
|
|
33
|
+
amount: number;
|
|
34
|
+
spentAt: ISODate;
|
|
35
|
+
vendor?: string;
|
|
36
|
+
memo?: string;
|
|
37
|
+
receiptUrl?: string;
|
|
38
|
+
};
|
|
39
|
+
export type CreateSubjectInput = {
|
|
40
|
+
code: string;
|
|
41
|
+
name: string;
|
|
42
|
+
};
|
|
43
|
+
export type CreateCourseInput = {
|
|
44
|
+
name: string;
|
|
45
|
+
subjectId: ID;
|
|
46
|
+
instructorId: ID;
|
|
47
|
+
price: number;
|
|
48
|
+
hourlyRate: number;
|
|
49
|
+
};
|
|
50
|
+
export type CreateEventInput = {
|
|
51
|
+
title: string;
|
|
52
|
+
type: EventType;
|
|
53
|
+
priority?: EventPriority;
|
|
54
|
+
startDate: ISODate;
|
|
55
|
+
endDate: ISODate;
|
|
56
|
+
allDay?: boolean;
|
|
57
|
+
memo?: string;
|
|
58
|
+
};
|
package/dist/inputs.js
ADDED
package/dist/people.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ID, Audited } from './common';
|
|
2
|
+
export type StudentStatus = 'lead' | 'active' | 'paused' | 'completed' | 'canceled';
|
|
3
|
+
export type ResidenceType = 'domestic' | 'overseas';
|
|
4
|
+
export type Student = {
|
|
5
|
+
id: ID;
|
|
6
|
+
name: string;
|
|
7
|
+
englishName?: string;
|
|
8
|
+
grade?: number;
|
|
9
|
+
phone?: string;
|
|
10
|
+
status: StudentStatus;
|
|
11
|
+
schoolName?: string;
|
|
12
|
+
residenceType?: ResidenceType;
|
|
13
|
+
memo?: string;
|
|
14
|
+
webId?: string;
|
|
15
|
+
} & Audited;
|
|
16
|
+
export type Parent = {
|
|
17
|
+
id: ID;
|
|
18
|
+
name: string;
|
|
19
|
+
phone: string;
|
|
20
|
+
kakaoAvailable: boolean;
|
|
21
|
+
webId?: string;
|
|
22
|
+
} & Audited;
|
|
23
|
+
export type ParentStudent = {
|
|
24
|
+
id: ID;
|
|
25
|
+
parentId: ID;
|
|
26
|
+
studentId: ID;
|
|
27
|
+
relation?: string;
|
|
28
|
+
isPayer: boolean;
|
|
29
|
+
isPrimary: boolean;
|
|
30
|
+
};
|
|
31
|
+
export type Instructor = {
|
|
32
|
+
id: ID;
|
|
33
|
+
name: string;
|
|
34
|
+
subjectName?: string;
|
|
35
|
+
};
|
package/dist/people.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ID, ISODate } from './common';
|
|
2
|
+
export type SessionStatus = 'scheduled' | 'held' | 'canceled' | 'no_show' | 'makeup';
|
|
3
|
+
export type ClassSession = {
|
|
4
|
+
id: ID;
|
|
5
|
+
courseId: ID;
|
|
6
|
+
instructorId: ID;
|
|
7
|
+
sessionDate: ISODate;
|
|
8
|
+
durationMinutes: number;
|
|
9
|
+
status: SessionStatus;
|
|
10
|
+
topic?: string;
|
|
11
|
+
};
|
|
12
|
+
export type AttendanceStatus = 'present' | 'late' | 'absent' | 'excused';
|
|
13
|
+
export type Attendance = {
|
|
14
|
+
id: ID;
|
|
15
|
+
sessionId: ID;
|
|
16
|
+
studentId: ID;
|
|
17
|
+
status: AttendanceStatus;
|
|
18
|
+
};
|
|
19
|
+
export type ReportStatus = 'draft' | 'submitted' | 'sent';
|
|
20
|
+
export type SessionReport = {
|
|
21
|
+
id: ID;
|
|
22
|
+
sessionId: ID;
|
|
23
|
+
studentId: ID;
|
|
24
|
+
instructorId: ID;
|
|
25
|
+
content: string;
|
|
26
|
+
homework?: string;
|
|
27
|
+
status: ReportStatus;
|
|
28
|
+
};
|
package/dist/session.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kms545487/contracts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TACO 공유 도메인 계약(타입·enum·DTO). 프론트/백 단일 소스.",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.build.json",
|
|
20
|
+
"prepublishOnly": "npm run build",
|
|
21
|
+
"typecheck": "tsc --noEmit"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"typescript": "^5.6.2"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
}
|
|
29
|
+
}
|