opensoma 0.2.1 → 0.4.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/dist/package.json +2 -2
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +2 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/client.d.ts +24 -1
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +159 -4
- package/dist/src/client.js.map +1 -1
- package/dist/src/commands/auth.d.ts +5 -1
- package/dist/src/commands/auth.d.ts.map +1 -1
- package/dist/src/commands/auth.js +83 -4
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/helpers.d.ts +5 -1
- package/dist/src/commands/helpers.d.ts.map +1 -1
- package/dist/src/commands/helpers.js +28 -3
- package/dist/src/commands/helpers.js.map +1 -1
- package/dist/src/commands/index.d.ts +1 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +1 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/mentoring.d.ts.map +1 -1
- package/dist/src/commands/mentoring.js +44 -2
- package/dist/src/commands/mentoring.js.map +1 -1
- package/dist/src/commands/report.d.ts +27 -0
- package/dist/src/commands/report.d.ts.map +1 -0
- package/dist/src/commands/report.js +224 -0
- package/dist/src/commands/report.js.map +1 -0
- package/dist/src/commands/room.d.ts.map +1 -1
- package/dist/src/commands/room.js +25 -2
- package/dist/src/commands/room.js.map +1 -1
- package/dist/src/constants.d.ts +14 -9
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +25 -9
- package/dist/src/constants.js.map +1 -1
- package/dist/src/formatters.d.ts +4 -1
- package/dist/src/formatters.d.ts.map +1 -1
- package/dist/src/formatters.js +128 -24
- package/dist/src/formatters.js.map +1 -1
- package/dist/src/http.d.ts +5 -0
- package/dist/src/http.d.ts.map +1 -1
- package/dist/src/http.js +107 -2
- package/dist/src/http.js.map +1 -1
- package/dist/src/shared/utils/html.d.ts +3 -0
- package/dist/src/shared/utils/html.d.ts.map +1 -0
- package/dist/src/shared/utils/html.js +12 -0
- package/dist/src/shared/utils/html.js.map +1 -0
- package/dist/src/shared/utils/report-params.d.ts +11 -0
- package/dist/src/shared/utils/report-params.d.ts.map +1 -0
- package/dist/src/shared/utils/report-params.js +27 -0
- package/dist/src/shared/utils/report-params.js.map +1 -0
- package/dist/src/shared/utils/swmaestro.d.ts +26 -0
- package/dist/src/shared/utils/swmaestro.d.ts.map +1 -1
- package/dist/src/shared/utils/swmaestro.js +77 -6
- package/dist/src/shared/utils/swmaestro.js.map +1 -1
- package/dist/src/token-extractor.d.ts.map +1 -1
- package/dist/src/token-extractor.js +38 -8
- package/dist/src/token-extractor.js.map +1 -1
- package/dist/src/types.d.ts +156 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +90 -1
- package/dist/src/types.js.map +1 -1
- package/package.json +2 -2
- package/src/cli.ts +2 -0
- package/src/client.test.ts +92 -20
- package/src/client.ts +192 -4
- package/src/commands/auth.test.ts +40 -1
- package/src/commands/auth.ts +91 -3
- package/src/commands/helpers.test.ts +108 -4
- package/src/commands/helpers.ts +30 -3
- package/src/commands/index.ts +1 -0
- package/src/commands/mentoring.ts +64 -1
- package/src/commands/report.test.ts +49 -0
- package/src/commands/report.ts +322 -0
- package/src/commands/room.ts +31 -3
- package/src/constants.ts +26 -9
- package/src/formatters.test.ts +293 -2
- package/src/formatters.ts +152 -28
- package/src/http.test.ts +373 -1
- package/src/http.ts +122 -2
- package/src/shared/utils/html.ts +12 -0
- package/src/shared/utils/report-params.ts +41 -0
- package/src/shared/utils/swmaestro.test.ts +44 -0
- package/src/shared/utils/swmaestro.ts +106 -9
- package/src/token-extractor.ts +59 -20
- package/src/types.test.ts +101 -1
- package/src/types.ts +106 -1
package/dist/src/types.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
2
|
const DateRangeSchema = z.object({ start: z.string(), end: z.string() });
|
|
3
3
|
const TimeRangeSchema = z.object({ start: z.string(), end: z.string() });
|
|
4
|
-
const
|
|
4
|
+
const RoomTimeSlotReservationSchema = z.object({ title: z.string(), bookedBy: z.string() });
|
|
5
|
+
const RoomTimeSlotSchema = z.object({
|
|
6
|
+
time: z.string(),
|
|
7
|
+
available: z.boolean(),
|
|
8
|
+
reservation: RoomTimeSlotReservationSchema.optional(),
|
|
9
|
+
});
|
|
5
10
|
const DashboardStatusItemSchema = z.object({
|
|
6
11
|
title: z.string(),
|
|
7
12
|
url: z.string(),
|
|
@@ -30,9 +35,16 @@ export const MentoringListItemSchema = z.object({
|
|
|
30
35
|
author: z.string(),
|
|
31
36
|
createdAt: z.string(),
|
|
32
37
|
});
|
|
38
|
+
export const MentoringApplicantSchema = z.object({
|
|
39
|
+
name: z.string(),
|
|
40
|
+
appliedAt: z.string(),
|
|
41
|
+
cancelledAt: z.string(),
|
|
42
|
+
status: z.string(),
|
|
43
|
+
});
|
|
33
44
|
export const MentoringDetailSchema = MentoringListItemSchema.extend({
|
|
34
45
|
content: z.string(),
|
|
35
46
|
venue: z.string(),
|
|
47
|
+
applicants: z.array(MentoringApplicantSchema),
|
|
36
48
|
});
|
|
37
49
|
export const RoomCardSchema = z.object({
|
|
38
50
|
itemId: z.number(),
|
|
@@ -114,4 +126,81 @@ export const CredentialsSchema = z.object({
|
|
|
114
126
|
password: z.string().optional(),
|
|
115
127
|
loggedInAt: z.string().optional(),
|
|
116
128
|
});
|
|
129
|
+
export const ReportListItemSchema = z.object({
|
|
130
|
+
id: z.number(),
|
|
131
|
+
category: z.string(),
|
|
132
|
+
title: z.string(),
|
|
133
|
+
progressDate: z.string(),
|
|
134
|
+
status: z.string(),
|
|
135
|
+
author: z.string(),
|
|
136
|
+
createdAt: z.string(),
|
|
137
|
+
acceptedTime: z.string(),
|
|
138
|
+
payAmount: z.string(),
|
|
139
|
+
});
|
|
140
|
+
export const ReportDetailSchema = ReportListItemSchema.extend({
|
|
141
|
+
content: z.string(),
|
|
142
|
+
subject: z.string(),
|
|
143
|
+
menteeRegion: z.string(),
|
|
144
|
+
reportType: z.string(),
|
|
145
|
+
teamNames: z.string(),
|
|
146
|
+
venue: z.string(),
|
|
147
|
+
attendanceCount: z.number(),
|
|
148
|
+
attendanceNames: z.string(),
|
|
149
|
+
progressStartTime: z.string(),
|
|
150
|
+
progressEndTime: z.string(),
|
|
151
|
+
exceptStartTime: z.string(),
|
|
152
|
+
exceptEndTime: z.string(),
|
|
153
|
+
exceptReason: z.string(),
|
|
154
|
+
mentorOpinion: z.string(),
|
|
155
|
+
nonAttendanceNames: z.string(),
|
|
156
|
+
etc: z.string(),
|
|
157
|
+
files: z.array(z.string()),
|
|
158
|
+
});
|
|
159
|
+
export const ApprovalListItemSchema = z.object({
|
|
160
|
+
id: z.number(),
|
|
161
|
+
category: z.string(),
|
|
162
|
+
title: z.string(),
|
|
163
|
+
progressDate: z.string(),
|
|
164
|
+
status: z.string(),
|
|
165
|
+
author: z.string(),
|
|
166
|
+
createdAt: z.string(),
|
|
167
|
+
acceptedTime: z.string(),
|
|
168
|
+
travelExpense: z.string(),
|
|
169
|
+
mentoringAllowance: z.string(),
|
|
170
|
+
});
|
|
171
|
+
export const ReportCreateOptionsSchema = z.object({
|
|
172
|
+
menteeRegion: z.enum(['S', 'B']),
|
|
173
|
+
reportType: z.enum(['MRC010', 'MRC020']),
|
|
174
|
+
progressDate: z.string(),
|
|
175
|
+
teamNames: z.string().optional(),
|
|
176
|
+
venue: z.string(),
|
|
177
|
+
attendanceCount: z.number(),
|
|
178
|
+
attendanceNames: z.string(),
|
|
179
|
+
progressStartTime: z.string(),
|
|
180
|
+
progressEndTime: z.string(),
|
|
181
|
+
exceptStartTime: z.string().optional(),
|
|
182
|
+
exceptEndTime: z.string().optional(),
|
|
183
|
+
exceptReason: z.string().optional(),
|
|
184
|
+
subject: z.string().min(10),
|
|
185
|
+
content: z.string().min(100),
|
|
186
|
+
mentorOpinion: z.string().optional(),
|
|
187
|
+
nonAttendanceNames: z.string().optional(),
|
|
188
|
+
etc: z.string().optional(),
|
|
189
|
+
});
|
|
190
|
+
export const ReportUpdateOptionsSchema = ReportCreateOptionsSchema.partial().extend({
|
|
191
|
+
id: z.number(),
|
|
192
|
+
});
|
|
193
|
+
export const MentoringCreateOptionsSchema = z.object({
|
|
194
|
+
title: z.string(),
|
|
195
|
+
type: z.enum(['public', 'lecture']),
|
|
196
|
+
date: z.string(),
|
|
197
|
+
startTime: z.string(),
|
|
198
|
+
endTime: z.string(),
|
|
199
|
+
venue: z.string(),
|
|
200
|
+
maxAttendees: z.number().optional(),
|
|
201
|
+
regStart: z.string().optional(),
|
|
202
|
+
regEnd: z.string().optional(),
|
|
203
|
+
content: z.string().optional(),
|
|
204
|
+
});
|
|
205
|
+
export const MentoringUpdateOptionsSchema = MentoringCreateOptionsSchema.partial();
|
|
117
206
|
//# sourceMappingURL=types.js.map
|
package/dist/src/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AACxE,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AACxE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opensoma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "SWMaestro MyPage CLI & SDK for AI agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/
|
|
8
|
+
"url": "git+https://github.com/opensoma/opensoma.git"
|
|
9
9
|
},
|
|
10
10
|
"bin": {
|
|
11
11
|
"opensoma": "dist/src/cli.js"
|
package/src/cli.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
memberCommand,
|
|
11
11
|
mentoringCommand,
|
|
12
12
|
noticeCommand,
|
|
13
|
+
reportCommand,
|
|
13
14
|
roomCommand,
|
|
14
15
|
teamCommand,
|
|
15
16
|
} from './commands/index'
|
|
@@ -51,6 +52,7 @@ program.addCommand(noticeCommand)
|
|
|
51
52
|
program.addCommand(teamCommand)
|
|
52
53
|
program.addCommand(memberCommand)
|
|
53
54
|
program.addCommand(eventCommand)
|
|
55
|
+
program.addCommand(reportCommand)
|
|
54
56
|
|
|
55
57
|
program.parse(process.argv)
|
|
56
58
|
|
package/src/client.test.ts
CHANGED
|
@@ -72,14 +72,19 @@ describe('SomaClient', () => {
|
|
|
72
72
|
})
|
|
73
73
|
|
|
74
74
|
test('mutating operations post expected payloads', async () => {
|
|
75
|
+
const mentoringDetailHtml =
|
|
76
|
+
'<div class="group"><strong class="t">모집 명</strong><div class="c">[자유 멘토링] 기존 멘토링</div></div><div class="group"><strong class="t">접수 기간</strong><div class="c">2026.03.01 ~ 2026.03.15</div></div><div class="group"><strong class="t">강의날짜</strong><div class="c"><span>2026.03.20 10:00시 ~ 12:00시</span></div></div><div class="group"><strong class="t">장소</strong><div class="c">온라인(Webex)</div></div><div class="group"><strong class="t">모집인원</strong><div class="c">5명</div></div><div class="group"><strong class="t">작성자</strong><div class="c">전수열</div></div><div class="group"><strong class="t">등록일</strong><div class="c">2026.03.01</div></div><div class="cont"><p>기존 내용</p></div>'
|
|
75
77
|
const client = new SomaClient()
|
|
76
|
-
const calls: Array<{ path: string; data: Record<string, string> }> = []
|
|
78
|
+
const calls: Array<{ method: string; path: string; data: Record<string, string> }> = []
|
|
79
|
+
const captor = (method: string) => async (path: string, data: Record<string, string>) => {
|
|
80
|
+
calls.push({ method, path, data })
|
|
81
|
+
return ''
|
|
82
|
+
}
|
|
77
83
|
Reflect.set(client, 'http', {
|
|
78
84
|
checkLogin: async () => ({ userId: 'user@example.com', userNm: 'Test' }),
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
},
|
|
85
|
+
get: async () => mentoringDetailHtml,
|
|
86
|
+
post: captor('post'),
|
|
87
|
+
postForm: captor('postForm'),
|
|
83
88
|
})
|
|
84
89
|
|
|
85
90
|
await client.mentoring.create({
|
|
@@ -91,6 +96,14 @@ describe('SomaClient', () => {
|
|
|
91
96
|
venue: '온라인(Webex)',
|
|
92
97
|
maxAttendees: 10,
|
|
93
98
|
})
|
|
99
|
+
await client.mentoring.update(42, {
|
|
100
|
+
title: '수정된 멘토링',
|
|
101
|
+
type: 'public',
|
|
102
|
+
date: '2026-05-01',
|
|
103
|
+
startTime: '14:00',
|
|
104
|
+
endTime: '15:00',
|
|
105
|
+
venue: '오프라인',
|
|
106
|
+
})
|
|
94
107
|
await client.mentoring.delete(7)
|
|
95
108
|
await client.mentoring.apply(8)
|
|
96
109
|
await client.mentoring.cancel({ applySn: 9, qustnrSn: 10 })
|
|
@@ -102,43 +115,50 @@ describe('SomaClient', () => {
|
|
|
102
115
|
})
|
|
103
116
|
await client.event.apply(11)
|
|
104
117
|
|
|
105
|
-
expect(calls.map((call) => call.path)).toEqual([
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
'/
|
|
109
|
-
'/
|
|
110
|
-
'
|
|
111
|
-
'/
|
|
118
|
+
expect(calls.map((call) => `${call.method}:${call.path}`)).toEqual([
|
|
119
|
+
'postForm:/mypage/mentoLec/insert.do',
|
|
120
|
+
'postForm:/mypage/mentoLec/update.do',
|
|
121
|
+
'post:/mypage/mentoLec/delete.do',
|
|
122
|
+
'post:/application/application/application.do',
|
|
123
|
+
'post:/mypage/userAnswer/cancel.do',
|
|
124
|
+
'post:/mypage/itemRent/insert.do',
|
|
125
|
+
'post:/application/application/application.do',
|
|
112
126
|
])
|
|
113
127
|
expect(calls[0]?.data).toMatchObject({
|
|
114
128
|
menuNo: MENU_NO.MENTORING,
|
|
115
129
|
reportCd: 'MRC020',
|
|
116
130
|
qustnrSj: '새 멘토링',
|
|
117
131
|
})
|
|
118
|
-
expect(calls[1]?.data).
|
|
132
|
+
expect(calls[1]?.data).toMatchObject({
|
|
133
|
+
menuNo: MENU_NO.MENTORING,
|
|
134
|
+
reportCd: 'MRC010',
|
|
135
|
+
qustnrSj: '수정된 멘토링',
|
|
136
|
+
qustnrSn: '42',
|
|
137
|
+
})
|
|
138
|
+
expect(calls[2]?.data).toEqual({
|
|
119
139
|
menuNo: MENU_NO.MENTORING,
|
|
120
140
|
qustnrSn: '7',
|
|
121
141
|
pageQueryString: '',
|
|
122
142
|
})
|
|
123
|
-
expect(calls[
|
|
143
|
+
expect(calls[3]?.data).toEqual({
|
|
124
144
|
menuNo: MENU_NO.EVENT,
|
|
125
145
|
qustnrSn: '8',
|
|
126
146
|
applyGb: 'C',
|
|
127
147
|
stepHeader: '0',
|
|
128
148
|
})
|
|
129
|
-
expect(calls[
|
|
149
|
+
expect(calls[4]?.data).toEqual({
|
|
130
150
|
menuNo: MENU_NO.APPLICATION_HISTORY,
|
|
131
151
|
applySn: '9',
|
|
132
152
|
qustnrSn: '10',
|
|
133
153
|
})
|
|
134
|
-
expect(calls[
|
|
154
|
+
expect(calls[5]?.data).toMatchObject({
|
|
135
155
|
menuNo: MENU_NO.ROOM,
|
|
136
156
|
itemId: '17',
|
|
137
157
|
title: '회의',
|
|
138
158
|
'time[0]': '10:00',
|
|
139
159
|
'time[1]': '10:30',
|
|
140
160
|
})
|
|
141
|
-
expect(calls[
|
|
161
|
+
expect(calls[6]?.data).toEqual({
|
|
142
162
|
menuNo: MENU_NO.EVENT,
|
|
143
163
|
qustnrSn: '11',
|
|
144
164
|
applyGb: 'C',
|
|
@@ -146,6 +166,38 @@ describe('SomaClient', () => {
|
|
|
146
166
|
})
|
|
147
167
|
})
|
|
148
168
|
|
|
169
|
+
test('mentoring.update merges partial params with existing data', async () => {
|
|
170
|
+
const mentoringDetailHtml =
|
|
171
|
+
'<div class="group"><strong class="t">모집 명</strong><div class="c">[멘토 특강] 웹 성능 특강</div></div><div class="group"><strong class="t">접수 기간</strong><div class="c">2026.04.01 ~ 2026.04.10</div></div><div class="group"><strong class="t">강의날짜</strong><div class="c"><span>2026.04.11 14:00시 ~ 15:30시</span></div></div><div class="group"><strong class="t">장소</strong><div class="c">온라인(Webex)</div></div><div class="group"><strong class="t">모집인원</strong><div class="c">20명</div></div><div class="group"><strong class="t">작성자</strong><div class="c">전수열</div></div><div class="group"><strong class="t">등록일</strong><div class="c">2026.04.01</div></div><div class="cont"><p>세션 본문</p></div>'
|
|
172
|
+
const client = new SomaClient()
|
|
173
|
+
const postFormCalls: Array<{ path: string; data: Record<string, string> }> = []
|
|
174
|
+
Reflect.set(client, 'http', {
|
|
175
|
+
checkLogin: async () => ({ userId: 'user@example.com', userNm: 'Test' }),
|
|
176
|
+
get: async () => mentoringDetailHtml,
|
|
177
|
+
postForm: async (path: string, data: Record<string, string>) => {
|
|
178
|
+
postFormCalls.push({ path, data })
|
|
179
|
+
return ''
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
await client.mentoring.update(9572, { title: '변경된 제목' })
|
|
184
|
+
|
|
185
|
+
expect(postFormCalls).toHaveLength(1)
|
|
186
|
+
expect(postFormCalls[0]?.data).toMatchObject({
|
|
187
|
+
qustnrSj: '변경된 제목',
|
|
188
|
+
qustnrSn: '9572',
|
|
189
|
+
reportCd: 'MRC020',
|
|
190
|
+
eventDt: '2026-04-11',
|
|
191
|
+
eventStime: '14:00',
|
|
192
|
+
eventEtime: '15:30',
|
|
193
|
+
place: '온라인(Webex)',
|
|
194
|
+
applyCnt: '20',
|
|
195
|
+
bgnde: '2026-04-01',
|
|
196
|
+
endde: '2026-04-10',
|
|
197
|
+
qestnarCn: '<p>세션 본문</p>',
|
|
198
|
+
})
|
|
199
|
+
})
|
|
200
|
+
|
|
149
201
|
test('room, dashboard, notice, team, member, event, and history routes use expected endpoints', async () => {
|
|
150
202
|
const client = new SomaClient()
|
|
151
203
|
const calls: Array<{ method: string; path: string; data: Record<string, string> | undefined }> = []
|
|
@@ -182,13 +234,13 @@ describe('SomaClient', () => {
|
|
|
182
234
|
post: async (path: string, data: Record<string, string>) => {
|
|
183
235
|
calls.push({ method: 'post', path, data })
|
|
184
236
|
if (path === '/mypage/officeMng/rentTime.do') {
|
|
185
|
-
return '<
|
|
237
|
+
return '<span class="ck-st2 disabled" data-hour="09" data-minute="00"><input type="checkbox" disabled="disabled"><label title="아침 회의<br>예약자 : 김오픈">오전 09:00</label></span>'
|
|
186
238
|
}
|
|
187
239
|
return '<ul class="bbs-reserve"><li class="item"><a href="javascript:void(0);" onclick="location.href=\'/sw/mypage/officeMng/view.do?itemId=17\';"><div class="cont"><h4 class="tit">스페이스 A1</h4><ul class="txt bul-dot grey"><li>이용기간 : 2026-04-01 ~ 2026-12-31</li><li><p>설명 : 4인</p></li><li class="time-list"><div class="time-grid"><span>09:00</span></div></li></ul></div></a></li></ul>'
|
|
188
240
|
},
|
|
189
241
|
})
|
|
190
242
|
|
|
191
|
-
const roomList = await client.room.list({ date: '2026-04-01', room: 'A1' })
|
|
243
|
+
const roomList = await client.room.list({ date: '2026-04-01', room: 'A1', includeReservations: true })
|
|
192
244
|
const roomSlots = await client.room.available(17, '2026-04-01')
|
|
193
245
|
const dashboard = await client.dashboard.get()
|
|
194
246
|
const noticeList = await client.notice.list({ page: 2 })
|
|
@@ -200,7 +252,12 @@ describe('SomaClient', () => {
|
|
|
200
252
|
const history = await client.mentoring.history({ page: 4 })
|
|
201
253
|
|
|
202
254
|
expect(roomList[0]?.itemId).toBe(17)
|
|
203
|
-
expect(
|
|
255
|
+
expect(roomList[0]?.timeSlots).toEqual([
|
|
256
|
+
{ time: '09:00', available: false, reservation: { title: '아침 회의', bookedBy: '김오픈' } },
|
|
257
|
+
])
|
|
258
|
+
expect(roomSlots).toEqual([
|
|
259
|
+
{ time: '09:00', available: false, reservation: { title: '아침 회의', bookedBy: '김오픈' } },
|
|
260
|
+
])
|
|
204
261
|
expect(dashboard.name).toBe('전수열')
|
|
205
262
|
expect(dashboard.mentoringSessions).toEqual([
|
|
206
263
|
{
|
|
@@ -234,6 +291,11 @@ describe('SomaClient', () => {
|
|
|
234
291
|
|
|
235
292
|
const dashboardCallIndex = calls.findIndex((c) => c.path === '/mypage/myMain/dashboard.do')
|
|
236
293
|
expect(dashboardCallIndex).toBeGreaterThanOrEqual(0)
|
|
294
|
+
expect(calls).toContainEqual({
|
|
295
|
+
method: 'post',
|
|
296
|
+
path: '/mypage/officeMng/rentTime.do',
|
|
297
|
+
data: { viewType: 'CONTBODY', itemId: '17', rentDt: '2026-04-01' },
|
|
298
|
+
})
|
|
237
299
|
const mentoringListCall = calls.find((c) => c.path === '/mypage/mentoLec/list.do')
|
|
238
300
|
expect(mentoringListCall?.data).toEqual({
|
|
239
301
|
menuNo: MENU_NO.MENTORING,
|
|
@@ -337,6 +399,16 @@ describe('SomaClient', () => {
|
|
|
337
399
|
venue: 'Test',
|
|
338
400
|
}),
|
|
339
401
|
).rejects.toBeInstanceOf(AuthenticationError)
|
|
402
|
+
await expect(
|
|
403
|
+
client.mentoring.update(1, {
|
|
404
|
+
title: 'Test',
|
|
405
|
+
type: 'public',
|
|
406
|
+
date: '2026-04-01',
|
|
407
|
+
startTime: '10:00',
|
|
408
|
+
endTime: '11:00',
|
|
409
|
+
venue: 'Test',
|
|
410
|
+
}),
|
|
411
|
+
).rejects.toBeInstanceOf(AuthenticationError)
|
|
340
412
|
await expect(client.mentoring.delete(1)).rejects.toBeInstanceOf(AuthenticationError)
|
|
341
413
|
await expect(client.mentoring.apply(1)).rejects.toBeInstanceOf(AuthenticationError)
|
|
342
414
|
await expect(client.mentoring.cancel({ applySn: 1, qustnrSn: 2 })).rejects.toBeInstanceOf(AuthenticationError)
|
package/src/client.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
|
|
1
3
|
import { MENU_NO } from './constants'
|
|
2
4
|
import { CredentialManager } from './credential-manager'
|
|
3
5
|
import { AuthenticationError } from './errors'
|
|
@@ -9,20 +11,31 @@ import {
|
|
|
9
11
|
buildCancelApplicationPayload,
|
|
10
12
|
buildDeleteMentoringPayload,
|
|
11
13
|
buildMentoringPayload,
|
|
14
|
+
buildReportPayload,
|
|
12
15
|
buildRoomReservationPayload,
|
|
16
|
+
buildUpdateMentoringPayload,
|
|
13
17
|
parseEventDetail,
|
|
14
18
|
resolveRoomId,
|
|
19
|
+
toMentoringType,
|
|
20
|
+
toRegionCode,
|
|
21
|
+
toReportTypeCd,
|
|
15
22
|
} from './shared/utils/swmaestro'
|
|
16
23
|
import type {
|
|
17
24
|
ApplicationHistoryItem,
|
|
25
|
+
ApprovalListItem,
|
|
18
26
|
Dashboard,
|
|
19
27
|
EventListItem,
|
|
20
28
|
MemberInfo,
|
|
21
29
|
MentoringDetail,
|
|
22
30
|
MentoringListItem,
|
|
31
|
+
MentoringUpdateOptions,
|
|
23
32
|
NoticeDetail,
|
|
24
33
|
NoticeListItem,
|
|
25
34
|
Pagination,
|
|
35
|
+
ReportCreateOptions,
|
|
36
|
+
ReportDetail,
|
|
37
|
+
ReportListItem,
|
|
38
|
+
ReportUpdateOptions,
|
|
26
39
|
RoomCard,
|
|
27
40
|
TeamInfo,
|
|
28
41
|
} from './types'
|
|
@@ -60,6 +73,7 @@ export class SomaClient {
|
|
|
60
73
|
regEnd?: string
|
|
61
74
|
content?: string
|
|
62
75
|
}): Promise<void>
|
|
76
|
+
update(id: number, params: MentoringUpdateOptions): Promise<void>
|
|
63
77
|
delete(id: number): Promise<void>
|
|
64
78
|
apply(id: number): Promise<void>
|
|
65
79
|
cancel(params: { applySn: number; qustnrSn: number }): Promise<void>
|
|
@@ -67,7 +81,7 @@ export class SomaClient {
|
|
|
67
81
|
}
|
|
68
82
|
|
|
69
83
|
readonly room: {
|
|
70
|
-
list(options?: { date?: string; room?: string }): Promise<RoomCard[]>
|
|
84
|
+
list(options?: { date?: string; room?: string; includeReservations?: boolean }): Promise<RoomCard[]>
|
|
71
85
|
available(roomId: number, date: string): Promise<RoomCard['timeSlots']>
|
|
72
86
|
reserve(params: {
|
|
73
87
|
roomId: number
|
|
@@ -88,6 +102,27 @@ export class SomaClient {
|
|
|
88
102
|
get(id: number): Promise<NoticeDetail>
|
|
89
103
|
}
|
|
90
104
|
|
|
105
|
+
readonly report: {
|
|
106
|
+
list(options?: {
|
|
107
|
+
page?: number
|
|
108
|
+
searchField?: string
|
|
109
|
+
searchKeyword?: string
|
|
110
|
+
}): Promise<{ items: ReportListItem[]; pagination: Pagination }>
|
|
111
|
+
get(id: number): Promise<ReportDetail>
|
|
112
|
+
create(options: ReportCreateOptions, file: Buffer | string, fileName?: string): Promise<void>
|
|
113
|
+
update(
|
|
114
|
+
id: number,
|
|
115
|
+
options: Omit<ReportUpdateOptions, 'id'>,
|
|
116
|
+
file?: Buffer | string,
|
|
117
|
+
fileName?: string,
|
|
118
|
+
): Promise<void>
|
|
119
|
+
approval(options?: {
|
|
120
|
+
page?: number
|
|
121
|
+
month?: string
|
|
122
|
+
reportType?: string
|
|
123
|
+
}): Promise<{ items: ApprovalListItem[]; pagination: Pagination }>
|
|
124
|
+
}
|
|
125
|
+
|
|
91
126
|
readonly team: {
|
|
92
127
|
show(): Promise<TeamInfo>
|
|
93
128
|
}
|
|
@@ -143,11 +178,31 @@ export class SomaClient {
|
|
|
143
178
|
},
|
|
144
179
|
create: async (params) => {
|
|
145
180
|
await this.requireAuth()
|
|
146
|
-
const html = await this.http.
|
|
181
|
+
const html = await this.http.postForm('/mypage/mentoLec/insert.do', buildMentoringPayload(params))
|
|
147
182
|
if (this.containsErrorIndicator(html)) {
|
|
148
183
|
throw new Error(this.extractErrorMessage(html) || '멘토링 등록에 실패했습니다.')
|
|
149
184
|
}
|
|
150
185
|
},
|
|
186
|
+
update: async (id, params) => {
|
|
187
|
+
await this.requireAuth()
|
|
188
|
+
const existing = await this.mentoring.get(id)
|
|
189
|
+
const merged = buildUpdateMentoringPayload(id, {
|
|
190
|
+
title: params.title ?? existing.title,
|
|
191
|
+
type: params.type ?? toMentoringType(existing.type),
|
|
192
|
+
date: params.date ?? existing.sessionDate,
|
|
193
|
+
startTime: params.startTime ?? existing.sessionTime.start,
|
|
194
|
+
endTime: params.endTime ?? existing.sessionTime.end,
|
|
195
|
+
venue: params.venue ?? existing.venue,
|
|
196
|
+
maxAttendees: params.maxAttendees ?? existing.attendees.max,
|
|
197
|
+
regStart: params.regStart ?? existing.registrationPeriod.start,
|
|
198
|
+
regEnd: params.regEnd ?? existing.registrationPeriod.end,
|
|
199
|
+
content: params.content ?? existing.content,
|
|
200
|
+
})
|
|
201
|
+
const html = await this.http.postForm('/mypage/mentoLec/update.do', merged)
|
|
202
|
+
if (this.containsErrorIndicator(html)) {
|
|
203
|
+
throw new Error(this.extractErrorMessage(html) || '멘토링 수정에 실패했습니다.')
|
|
204
|
+
}
|
|
205
|
+
},
|
|
151
206
|
delete: async (id) => {
|
|
152
207
|
await this.requireAuth()
|
|
153
208
|
await this.http.post('/mypage/mentoLec/delete.do', buildDeleteMentoringPayload(id))
|
|
@@ -176,13 +231,35 @@ export class SomaClient {
|
|
|
176
231
|
this.room = {
|
|
177
232
|
list: async (options) => {
|
|
178
233
|
await this.requireAuth()
|
|
179
|
-
|
|
234
|
+
const date = options?.date ?? new Date().toISOString().slice(0, 10)
|
|
235
|
+
const rooms = formatters.parseRoomList(
|
|
180
236
|
await this.http.post('/mypage/officeMng/list.do', {
|
|
181
237
|
menuNo: MENU_NO.ROOM,
|
|
182
|
-
sdate:
|
|
238
|
+
sdate: date,
|
|
183
239
|
searchItemId: options?.room ? String(resolveRoomId(options.room)) : '',
|
|
184
240
|
}),
|
|
185
241
|
)
|
|
242
|
+
|
|
243
|
+
if (!options?.includeReservations) return rooms
|
|
244
|
+
|
|
245
|
+
return Promise.all(
|
|
246
|
+
rooms.map(async (room) => {
|
|
247
|
+
try {
|
|
248
|
+
const html = await this.http.post('/mypage/officeMng/rentTime.do', {
|
|
249
|
+
viewType: 'CONTBODY',
|
|
250
|
+
itemId: String(room.itemId),
|
|
251
|
+
rentDt: date,
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
...room,
|
|
256
|
+
timeSlots: formatters.parseRoomSlots(html),
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
259
|
+
return room
|
|
260
|
+
}
|
|
261
|
+
}),
|
|
262
|
+
)
|
|
186
263
|
},
|
|
187
264
|
available: async (roomId, date) => {
|
|
188
265
|
await this.requireAuth()
|
|
@@ -244,6 +321,117 @@ export class SomaClient {
|
|
|
244
321
|
},
|
|
245
322
|
}
|
|
246
323
|
|
|
324
|
+
this.report = {
|
|
325
|
+
list: async (options) => {
|
|
326
|
+
await this.requireAuth()
|
|
327
|
+
const params: Record<string, string> = {
|
|
328
|
+
menuNo: MENU_NO.REPORT,
|
|
329
|
+
pageIndex: String(options?.page ?? 1),
|
|
330
|
+
}
|
|
331
|
+
if (options?.searchField !== undefined) params.searchCnd = options.searchField
|
|
332
|
+
if (options?.searchKeyword) params.searchWrd = options.searchKeyword
|
|
333
|
+
const html = await this.http.get('/mypage/mentoringReport/list.do', params)
|
|
334
|
+
return {
|
|
335
|
+
items: formatters.parseReportList(html),
|
|
336
|
+
pagination: formatters.parsePagination(html),
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
get: async (id) => {
|
|
340
|
+
await this.requireAuth()
|
|
341
|
+
const html = await this.http.get('/mypage/mentoringReport/view.do', {
|
|
342
|
+
menuNo: MENU_NO.REPORT,
|
|
343
|
+
reportId: String(id),
|
|
344
|
+
})
|
|
345
|
+
return formatters.parseReportDetail(html, id)
|
|
346
|
+
},
|
|
347
|
+
create: async (options, file, fileName) => {
|
|
348
|
+
await this.requireAuth()
|
|
349
|
+
const payload = buildReportPayload({
|
|
350
|
+
menteeRegion: options.menteeRegion,
|
|
351
|
+
reportType: options.reportType,
|
|
352
|
+
progressDate: options.progressDate,
|
|
353
|
+
teamNames: options.teamNames,
|
|
354
|
+
venue: options.venue,
|
|
355
|
+
attendanceCount: options.attendanceCount,
|
|
356
|
+
attendanceNames: options.attendanceNames,
|
|
357
|
+
progressStartTime: options.progressStartTime,
|
|
358
|
+
progressEndTime: options.progressEndTime,
|
|
359
|
+
exceptStartTime: options.exceptStartTime,
|
|
360
|
+
exceptEndTime: options.exceptEndTime,
|
|
361
|
+
exceptReason: options.exceptReason,
|
|
362
|
+
subject: options.subject,
|
|
363
|
+
content: options.content,
|
|
364
|
+
mentorOpinion: options.mentorOpinion,
|
|
365
|
+
nonAttendanceNames: options.nonAttendanceNames,
|
|
366
|
+
etc: options.etc,
|
|
367
|
+
})
|
|
368
|
+
const formData = new FormData()
|
|
369
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
370
|
+
formData.append(key, value)
|
|
371
|
+
}
|
|
372
|
+
const isBuffer = Buffer.isBuffer(file)
|
|
373
|
+
const fileBuffer = isBuffer ? file : await readFile(file)
|
|
374
|
+
const resolvedFileName = isBuffer ? (fileName ?? 'file') : (file.split('/').pop() ?? 'file')
|
|
375
|
+
const uint8Array = new Uint8Array(fileBuffer.buffer, fileBuffer.byteOffset, fileBuffer.byteLength)
|
|
376
|
+
formData.append('file_1_1', new Blob([uint8Array as unknown as ArrayBuffer]), resolvedFileName)
|
|
377
|
+
formData.append('fileFieldNm_1', 'file_1')
|
|
378
|
+
formData.append('atchFileId', '')
|
|
379
|
+
await this.http.postMultipart('/mypage/mentoringReport/insert.do', formData)
|
|
380
|
+
},
|
|
381
|
+
update: async (id, options, file, fileName) => {
|
|
382
|
+
await this.requireAuth()
|
|
383
|
+
const existing = await this.report.get(id)
|
|
384
|
+
const payload = buildReportPayload({
|
|
385
|
+
menteeRegion: options.menteeRegion ?? toRegionCode(existing.menteeRegion),
|
|
386
|
+
reportType: options.reportType ?? toReportTypeCd(existing.reportType),
|
|
387
|
+
progressDate: options.progressDate ?? existing.progressDate,
|
|
388
|
+
teamNames: options.teamNames ?? existing.teamNames,
|
|
389
|
+
venue: options.venue ?? existing.venue,
|
|
390
|
+
attendanceCount: options.attendanceCount ?? existing.attendanceCount,
|
|
391
|
+
attendanceNames: options.attendanceNames ?? existing.attendanceNames,
|
|
392
|
+
progressStartTime: options.progressStartTime ?? existing.progressStartTime,
|
|
393
|
+
progressEndTime: options.progressEndTime ?? existing.progressEndTime,
|
|
394
|
+
exceptStartTime: options.exceptStartTime ?? existing.exceptStartTime,
|
|
395
|
+
exceptEndTime: options.exceptEndTime ?? existing.exceptEndTime,
|
|
396
|
+
exceptReason: options.exceptReason ?? existing.exceptReason,
|
|
397
|
+
subject: options.subject ?? existing.subject,
|
|
398
|
+
content: options.content ?? existing.content,
|
|
399
|
+
mentorOpinion: options.mentorOpinion ?? existing.mentorOpinion,
|
|
400
|
+
nonAttendanceNames: options.nonAttendanceNames ?? existing.nonAttendanceNames,
|
|
401
|
+
etc: options.etc ?? existing.etc,
|
|
402
|
+
reportId: id,
|
|
403
|
+
})
|
|
404
|
+
const formData = new FormData()
|
|
405
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
406
|
+
formData.append(key, value)
|
|
407
|
+
}
|
|
408
|
+
if (file) {
|
|
409
|
+
const isBuffer = Buffer.isBuffer(file)
|
|
410
|
+
const fileBuffer = isBuffer ? file : await readFile(file)
|
|
411
|
+
const resolvedFileName = isBuffer ? (fileName ?? 'file') : (file.split('/').pop() ?? 'file')
|
|
412
|
+
const uint8Array = new Uint8Array(fileBuffer.buffer, fileBuffer.byteOffset, fileBuffer.byteLength)
|
|
413
|
+
formData.append('file_1_1', new Blob([uint8Array as unknown as ArrayBuffer]), resolvedFileName)
|
|
414
|
+
formData.append('fileFieldNm_1', 'file_1')
|
|
415
|
+
formData.append('atchFileId', '')
|
|
416
|
+
}
|
|
417
|
+
await this.http.postMultipart('/mypage/mentoringReport/update.do', formData)
|
|
418
|
+
},
|
|
419
|
+
approval: async (options) => {
|
|
420
|
+
await this.requireAuth()
|
|
421
|
+
const params: Record<string, string> = {
|
|
422
|
+
menuNo: MENU_NO.REPORT_APPROVAL,
|
|
423
|
+
pageIndex: String(options?.page ?? 1),
|
|
424
|
+
}
|
|
425
|
+
if (options?.month) params.searchMonth = options.month
|
|
426
|
+
if (options?.reportType !== undefined) params.searchReport = options.reportType
|
|
427
|
+
const html = await this.http.get('/mypage/mentoringReport/resultList.do', params)
|
|
428
|
+
return {
|
|
429
|
+
items: formatters.parseApprovalList(html),
|
|
430
|
+
pagination: formatters.parsePagination(html),
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
}
|
|
434
|
+
|
|
247
435
|
this.team = {
|
|
248
436
|
show: async () => {
|
|
249
437
|
await this.requireAuth()
|