@raclettejs/core 0.1.18 → 0.1.20
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/CHANGELOG.md +23 -0
- package/bin/cli.js +1 -1
- package/dev/README.md +4 -0
- package/dist/cli.js +135 -124
- package/dist/cli.js.map +4 -4
- package/dist/index.js +9 -8
- package/dist/index.js.map +4 -4
- package/package.json +9 -5
- package/services/backend/delay-api-debugger.sh +0 -0
- package/services/backend/package.json +1 -0
- package/services/backend/src/app.ts +4 -0
- package/services/backend/src/core/config/configService.ts +10 -1
- package/services/backend/src/core/events/eventEmitter.ts +32 -7
- package/services/backend/src/core/http/request-params.plugin.ts +2 -2
- package/services/backend/src/core/pluginSystem/pluginFastifyInstance.ts +4 -1
- package/services/backend/src/core/pluginSystem/pluginTypes.ts +3 -1
- package/services/backend/src/core/sockets/createSystemEventHandlers.ts +7 -0
- package/services/backend/src/core/sockets/index.ts +61 -13
- package/services/backend/src/core/sockets/socketManager.ts +452 -105
- package/services/backend/src/core/sockets/socketTypes.ts +13 -1
- package/services/backend/src/core/sockets/workSessionJoinPayload.ts +106 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.getAll.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.hardDelete.ts +16 -19
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/account/routes/route.account.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/composition.service.ts +86 -3
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.getAll.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.hardDelete.ts +16 -19
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.post.bulk.ts +60 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/composition/routes/route.composition.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/interactionLink.service.ts +96 -12
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.getAll.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.hardDelete.ts +12 -17
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.post.bulk.ts +62 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/route.interactionLink.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/project.service.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.get.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.getAll.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.hardDelete.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.post.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/project/routes/route.project.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.get.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.getAll.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.hardDelete.ts +10 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.patch.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.post.bulk.ts +60 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.remove.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/routes/route.tag.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/tag/tag.service.ts +73 -3
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.get.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.getAll.ts +1 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.hardDelete.ts +10 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.patch.ts +4 -6
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.patchLastProject.ts +4 -2
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.post.ts +3 -1
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.remove.ts +3 -4
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.restore.ts +12 -15
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/events/index.ts +45 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/helpers/crud.ts +12 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/helpers/payload.ts +21 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/index.ts +55 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/index.ts +19 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.get.ts +53 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.getAll.ts +39 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.hardDelete.ts +53 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.patch.ts +58 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.post.ts +53 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/routes/route.workSession.remove.ts +52 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.model.ts +65 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.schema.ts +125 -0
- package/services/backend/src/corePlugins/raclette__core/backend/datatypes/workSession/workSession.service.ts +351 -0
- package/services/backend/src/corePlugins/raclette__core/backend/index.ts +2 -0
- package/services/backend/src/corePlugins/raclette__core/frontend/generated-config.ts +159 -24
- package/services/backend/src/modules/authentication/index.ts +255 -4
- package/services/backend/src/modules/hooks/rate-limiter.ts +21 -0
- package/services/backend/src/types/custom-fastify.d.ts +17 -0
- package/services/backend/src/utils/request.utils.ts +4 -1
- package/services/backend/types/index.d.ts +15 -1
- package/services/backend/yarn.lock +13 -4
- package/services/frontend/index.html +1 -1
- package/services/frontend/provision/entrypoint.sh +0 -0
- package/services/frontend/src/core/lib/configService.ts +1 -1
- package/services/frontend/src/core/lib/data/dataApi.ts +10 -1
- package/services/frontend/src/core/lib/dataHelper.ts +1 -1
- package/services/frontend/src/core/lib/eggs/snow.ts +66 -48
- package/services/frontend/src/core/lib/helpers/index.ts +1 -0
- package/services/frontend/src/core/lib/helpers/removeEmpty.ts +69 -0
- package/services/frontend/src/core/lib/httpClient.ts +19 -0
- package/services/frontend/src/core/main.ts +20 -10
- package/services/frontend/src/core/setup/socket.ts +4 -3
- package/services/frontend/src/core/setup/socketClient.ts +31 -3
- package/services/frontend/src/core/setup/socketEvents.ts +92 -8
- package/services/frontend/src/core/store/index.ts +5 -1
- package/services/frontend/src/core/store/reducers/compositions/index.ts +2 -2
- package/services/frontend/src/core/store/reducers/interactionLinks/index.ts +1 -1
- package/services/frontend/src/core/store/reducers/widgets/reducers.ts +1 -2
- package/services/frontend/src/core/store/types/index.ts +0 -1
- package/services/frontend/src/core/types/PluginRegistrar.ts +8 -6
- package/services/frontend/src/core/types/Store.ts +1 -0
- package/services/frontend/src/orchestrator/components/composition/WidgetsLayoutLoader.vue +68 -8
- package/services/frontend/src/orchestrator/components/menu/UserMenu.vue +17 -5
- package/services/frontend/src/orchestrator/components/welcomeScreen/AdminWelcomeScreen.vue +1 -1
- package/services/frontend/src/orchestrator/composables/index.ts +1 -0
- package/services/frontend/src/orchestrator/composables/usePluginApi.ts +0 -3
- package/services/frontend/src/orchestrator/composables/useRouteState.ts +23 -4
- package/services/frontend/src/orchestrator/composables/useWidgetLifecycle.ts +166 -0
- package/services/frontend/src/orchestrator/helpers/index.ts +1 -0
- package/services/frontend/src/orchestrator/i18n/de-DE.json +15 -1
- package/services/frontend/src/orchestrator/i18n/en-EU.json +15 -1
- package/services/frontend/src/orchestrator/i18n/sk.json +15 -1
- package/services/frontend/src/orchestrator/index.ts +34 -4
- package/services/frontend/src/orchestrator/router/routeParserHelper.ts +106 -1
- package/services/frontend/src/orchestrator/types/Widgets.ts +2 -0
- package/services/frontend/types.ts +1 -0
- package/src/README.md +404 -0
- package/src/types.ts +19 -5
- package/templates/README.md +0 -0
- package/types/index.ts +18 -4
- package/services/backend/.gitignore +0 -17
- package/services/frontend/.gitignore +0 -35
- package/yarn.lock +0 -2937
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
WorkSessionCreate,
|
|
3
|
+
WorkSession as WorkSessionType,
|
|
4
|
+
WorkSessionUpdate,
|
|
5
|
+
} from "./workSession.schema"
|
|
6
|
+
import type {
|
|
7
|
+
FrontendPayload,
|
|
8
|
+
FrontendPayloadRequestData,
|
|
9
|
+
} from "@c/payload/payloadTypes"
|
|
10
|
+
import type { QueryOptions } from "@m/database/providers/mongodb/service"
|
|
11
|
+
import { v4 as uuidv4, validate } from "uuid"
|
|
12
|
+
import { createWorkSessionPayload } from "./helpers/payload"
|
|
13
|
+
import type { Model } from "mongoose"
|
|
14
|
+
import type { PluginFastifyInstance } from "types"
|
|
15
|
+
import { mergeDeepRight } from "ramda"
|
|
16
|
+
|
|
17
|
+
export type WorkSessionBody = Partial<Omit<WorkSessionType, "_id">> & {
|
|
18
|
+
_id?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Using a class to preserve 'this' context
|
|
22
|
+
export class WorkSessionService {
|
|
23
|
+
private workSessionModel: Model<WorkSessionType>
|
|
24
|
+
|
|
25
|
+
constructor(model: Model<WorkSessionType>) {
|
|
26
|
+
this.workSessionModel = model
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Core function to create a new workSession (returns raw data)
|
|
30
|
+
*/
|
|
31
|
+
async _createWorkSession(
|
|
32
|
+
fastify: PluginFastifyInstance,
|
|
33
|
+
workSessionBody: WorkSessionCreate,
|
|
34
|
+
): Promise<WorkSessionType> {
|
|
35
|
+
try {
|
|
36
|
+
if (workSessionBody._id) {
|
|
37
|
+
const uuidValid = validate(workSessionBody._id)
|
|
38
|
+
|
|
39
|
+
if (!uuidValid) {
|
|
40
|
+
throw new Error("Invalid ID - not a valid uuid v4")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const duplicate = await this.workSessionModel.findById(
|
|
44
|
+
workSessionBody._id,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if (duplicate) {
|
|
48
|
+
throw new Error("An entry with this id already exists")
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
workSessionBody._id = uuidv4()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const workSession = new this.workSessionModel(workSessionBody)
|
|
55
|
+
|
|
56
|
+
await workSession.save()
|
|
57
|
+
|
|
58
|
+
fastify.log.info(`[API] Created workSession #${workSession._id}`)
|
|
59
|
+
|
|
60
|
+
return workSession.toObject ? workSession.toObject() : workSession
|
|
61
|
+
} catch (error: any) {
|
|
62
|
+
fastify.log.error(error.message)
|
|
63
|
+
throw error
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Create a new workSession with payload wrapping and event emission
|
|
69
|
+
*/
|
|
70
|
+
async createWorkSession(
|
|
71
|
+
fastify: PluginFastifyInstance,
|
|
72
|
+
requestData: FrontendPayloadRequestData,
|
|
73
|
+
workSessionBody: WorkSessionCreate,
|
|
74
|
+
): Promise<FrontendPayload<WorkSessionType[]>> {
|
|
75
|
+
const workSession = await this._createWorkSession(fastify, workSessionBody)
|
|
76
|
+
|
|
77
|
+
const payload = await createWorkSessionPayload(
|
|
78
|
+
fastify,
|
|
79
|
+
[workSession],
|
|
80
|
+
requestData,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
if (requestData.broadcast) {
|
|
84
|
+
fastify.emit("workSessionCreated", payload)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return payload
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Core function to read all workSessions (returns raw data)
|
|
92
|
+
*/
|
|
93
|
+
async _readWorkSessions(
|
|
94
|
+
fastify: PluginFastifyInstance,
|
|
95
|
+
filter: Record<string, any> = {},
|
|
96
|
+
options: QueryOptions = {},
|
|
97
|
+
): Promise<WorkSessionType[]> {
|
|
98
|
+
try {
|
|
99
|
+
// Start building the query
|
|
100
|
+
let query = this.workSessionModel.find(filter)
|
|
101
|
+
|
|
102
|
+
// Apply pagination if provided
|
|
103
|
+
if (options.limit !== undefined) {
|
|
104
|
+
query = query.limit(options.limit)
|
|
105
|
+
}
|
|
106
|
+
if (options.offset !== undefined) {
|
|
107
|
+
query = query.skip(options.offset)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Apply population if provided
|
|
111
|
+
if (options.populate && Array.isArray(options.populate)) {
|
|
112
|
+
options.populate.forEach((populateOption) => {
|
|
113
|
+
query = query.populate(populateOption as any)
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Execute query
|
|
118
|
+
return await query.lean()
|
|
119
|
+
} catch (error: any) {
|
|
120
|
+
fastify.log.error(error.message)
|
|
121
|
+
throw error
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Read all workSessions with payload wrapping
|
|
127
|
+
*/
|
|
128
|
+
async readWorkSessions(
|
|
129
|
+
fastify: PluginFastifyInstance,
|
|
130
|
+
requestData: FrontendPayloadRequestData,
|
|
131
|
+
filter?: Record<string, any>,
|
|
132
|
+
options: QueryOptions = {},
|
|
133
|
+
): Promise<FrontendPayload<WorkSessionType[]>> {
|
|
134
|
+
const workSessions = await this._readWorkSessions(fastify, filter, options)
|
|
135
|
+
|
|
136
|
+
return createWorkSessionPayload(fastify, workSessions, requestData)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Core function to get a specific workSession (returns raw data)
|
|
141
|
+
*/
|
|
142
|
+
async _readWorkSession(
|
|
143
|
+
fastify: PluginFastifyInstance,
|
|
144
|
+
id: string,
|
|
145
|
+
): Promise<WorkSessionType> {
|
|
146
|
+
try {
|
|
147
|
+
const workSession = await this.workSessionModel.findById(id).lean()
|
|
148
|
+
|
|
149
|
+
if (!workSession) {
|
|
150
|
+
throw new Error(`WorkSession with ID ${id} not found`)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return workSession
|
|
154
|
+
} catch (error: any) {
|
|
155
|
+
fastify.log.error(error.message)
|
|
156
|
+
throw error
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Get a specific workSession with payload wrapping
|
|
162
|
+
*/
|
|
163
|
+
async readWorkSession(
|
|
164
|
+
fastify: PluginFastifyInstance,
|
|
165
|
+
requestData: FrontendPayloadRequestData,
|
|
166
|
+
id: string,
|
|
167
|
+
): Promise<FrontendPayload<WorkSessionType[]>> {
|
|
168
|
+
const workSession = await this._readWorkSession(fastify, id)
|
|
169
|
+
|
|
170
|
+
return createWorkSessionPayload(fastify, [workSession], requestData)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Core function to update an existing workSession (returns raw data)
|
|
175
|
+
*/
|
|
176
|
+
async _updateWorkSession(
|
|
177
|
+
fastify: PluginFastifyInstance,
|
|
178
|
+
id: string,
|
|
179
|
+
workSessionBody: Partial<WorkSessionUpdate>,
|
|
180
|
+
userId: string,
|
|
181
|
+
): Promise<{ updated: WorkSessionType; original: WorkSessionType }> {
|
|
182
|
+
try {
|
|
183
|
+
const originalWorkSession = await this.workSessionModel
|
|
184
|
+
.findById(id)
|
|
185
|
+
.lean()
|
|
186
|
+
|
|
187
|
+
if (!originalWorkSession) {
|
|
188
|
+
throw new Error(`WorkSession with ID ${id} not found`)
|
|
189
|
+
}
|
|
190
|
+
// Remove protected fields
|
|
191
|
+
const mergedWorkSession = mergeDeepRight(
|
|
192
|
+
originalWorkSession,
|
|
193
|
+
workSessionBody,
|
|
194
|
+
)
|
|
195
|
+
const updatedWorkSession = await this.workSessionModel
|
|
196
|
+
.findByIdAndUpdate(
|
|
197
|
+
id,
|
|
198
|
+
{
|
|
199
|
+
pluginData: mergedWorkSession.pluginData,
|
|
200
|
+
updatedBy: userId,
|
|
201
|
+
},
|
|
202
|
+
{ new: true },
|
|
203
|
+
)
|
|
204
|
+
.lean()
|
|
205
|
+
|
|
206
|
+
if (!updatedWorkSession) {
|
|
207
|
+
throw new Error(`Failed to update workSession with ID ${id}`)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
fastify.log.info(`[API] Updated workSession #${updatedWorkSession._id}`)
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
updated: updatedWorkSession,
|
|
214
|
+
original: originalWorkSession,
|
|
215
|
+
}
|
|
216
|
+
} catch (error: any) {
|
|
217
|
+
fastify.log.error(error.message)
|
|
218
|
+
throw error
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Update an existing workSession with payload wrapping and event emission
|
|
224
|
+
*/
|
|
225
|
+
async updateWorkSession(
|
|
226
|
+
fastify: PluginFastifyInstance,
|
|
227
|
+
requestData: FrontendPayloadRequestData,
|
|
228
|
+
id: string,
|
|
229
|
+
workSessionBody: Partial<WorkSessionUpdate>,
|
|
230
|
+
userId: string,
|
|
231
|
+
): Promise<FrontendPayload<WorkSessionType[]>> {
|
|
232
|
+
const { updated, original } = await this._updateWorkSession(
|
|
233
|
+
fastify,
|
|
234
|
+
id,
|
|
235
|
+
workSessionBody,
|
|
236
|
+
userId,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
const payload = await createWorkSessionPayload(
|
|
240
|
+
fastify,
|
|
241
|
+
[updated],
|
|
242
|
+
requestData,
|
|
243
|
+
)
|
|
244
|
+
payload.workSessionId = `session_${id}`
|
|
245
|
+
payload.body.prevVersion = original
|
|
246
|
+
|
|
247
|
+
if (requestData.broadcast) {
|
|
248
|
+
// TODO Discuss if we want to send the full payload here or only the actual changed pluginData, or maybe even introduce a "workstate" object in the workSession document which get's broadcasted and keeps all the worksession relevant state data
|
|
249
|
+
fastify.emit("workSessionUpdated", payload)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return payload
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Core function to soft delete a workSession (returns raw data)
|
|
257
|
+
*/
|
|
258
|
+
async _removeWorkSession(
|
|
259
|
+
fastify: PluginFastifyInstance,
|
|
260
|
+
id: string,
|
|
261
|
+
): Promise<WorkSessionType> {
|
|
262
|
+
try {
|
|
263
|
+
const workSession = await this.workSessionModel
|
|
264
|
+
.findByIdAndUpdate(id, { isActive: false }, { new: true })
|
|
265
|
+
.lean()
|
|
266
|
+
|
|
267
|
+
if (!workSession) {
|
|
268
|
+
throw new Error(`WorkSession with ID ${id} not found`)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return workSession
|
|
272
|
+
} catch (error: any) {
|
|
273
|
+
fastify.log.error(error.message)
|
|
274
|
+
throw error
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Soft delete a workSession with payload wrapping and event emission
|
|
280
|
+
*/
|
|
281
|
+
async removeWorkSession(
|
|
282
|
+
fastify: PluginFastifyInstance,
|
|
283
|
+
requestData: FrontendPayloadRequestData,
|
|
284
|
+
id: string,
|
|
285
|
+
): Promise<FrontendPayload<WorkSessionType[]>> {
|
|
286
|
+
const workSession = await this._removeWorkSession(fastify, id)
|
|
287
|
+
|
|
288
|
+
const payload = await createWorkSessionPayload(fastify, [workSession], {
|
|
289
|
+
...requestData,
|
|
290
|
+
type: "dataDelete",
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
payload.body.deleted = [workSession._id]
|
|
294
|
+
fastify.emit("workSessionDeleted", payload)
|
|
295
|
+
|
|
296
|
+
return payload
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Core function to hard delete a workSession (returns raw data)
|
|
301
|
+
*/
|
|
302
|
+
async _hardDeleteWorkSession(
|
|
303
|
+
fastify: PluginFastifyInstance,
|
|
304
|
+
id: string,
|
|
305
|
+
): Promise<WorkSessionType> {
|
|
306
|
+
try {
|
|
307
|
+
const workSession = await this.workSessionModel.findById(id)
|
|
308
|
+
|
|
309
|
+
if (!workSession) {
|
|
310
|
+
throw new Error(`WorkSession with ID ${id} not found`)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const res = await workSession.deleteOne()
|
|
314
|
+
|
|
315
|
+
if (res?.deletedCount === 1) {
|
|
316
|
+
return workSession.toObject ? workSession.toObject() : workSession
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
throw new Error(
|
|
320
|
+
`Deletion of WorkSession with ID ${id} was not successful.`,
|
|
321
|
+
)
|
|
322
|
+
} catch (error: any) {
|
|
323
|
+
fastify.log.error(error.message)
|
|
324
|
+
throw error
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Hard delete a workSession with payload wrapping and event emission
|
|
330
|
+
*/
|
|
331
|
+
async hardDeleteWorkSession(
|
|
332
|
+
fastify: PluginFastifyInstance,
|
|
333
|
+
requestData: FrontendPayloadRequestData,
|
|
334
|
+
id: string,
|
|
335
|
+
): Promise<FrontendPayload<WorkSessionType[]>> {
|
|
336
|
+
const workSession = await this._hardDeleteWorkSession(fastify, id)
|
|
337
|
+
|
|
338
|
+
const payload = await createWorkSessionPayload(fastify, [workSession], {
|
|
339
|
+
...requestData,
|
|
340
|
+
type: "dataHardDeleted",
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
payload.body.deleted = [workSession._id]
|
|
344
|
+
fastify.emit("workSessionHardDeleted", payload)
|
|
345
|
+
|
|
346
|
+
return payload
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export const createWorkSessionService = (model: Model<WorkSessionType>) =>
|
|
351
|
+
new WorkSessionService(model)
|
|
@@ -5,6 +5,7 @@ import registerInteractionLink from "./datatypes/interactionLink"
|
|
|
5
5
|
import registerTag from "./datatypes/tag"
|
|
6
6
|
import registerUser from "./datatypes/user"
|
|
7
7
|
import registerProject from "./datatypes/project"
|
|
8
|
+
import registerWorkSession from "./datatypes/workSession"
|
|
8
9
|
import { PluginContract } from "@c/contracting/contractTypes"
|
|
9
10
|
|
|
10
11
|
const racletteCorePlugin = async (
|
|
@@ -21,6 +22,7 @@ const racletteCorePlugin = async (
|
|
|
21
22
|
registerProject(fastify),
|
|
22
23
|
registerTag(fastify),
|
|
23
24
|
registerUser(fastify),
|
|
25
|
+
registerWorkSession(fastify),
|
|
24
26
|
])
|
|
25
27
|
|
|
26
28
|
// Combine all contract snippets into one plugin contract
|
|
@@ -102,6 +102,18 @@ export default {
|
|
|
102
102
|
}
|
|
103
103
|
]
|
|
104
104
|
},
|
|
105
|
+
updateRestore: {
|
|
106
|
+
target: (payload) => `/raclette__core/interactionLink/${payload._id}/restore`,
|
|
107
|
+
method: "patch",
|
|
108
|
+
storeActionType: "dataRestore",
|
|
109
|
+
channels: [
|
|
110
|
+
{
|
|
111
|
+
channel: "raclette__core--interactionLinkRestored",
|
|
112
|
+
channelKey: "interactionLinkRestored",
|
|
113
|
+
prefix: "raclette__core"
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
105
117
|
create: {
|
|
106
118
|
target: "/raclette__core/interactionLink",
|
|
107
119
|
method: "post",
|
|
@@ -114,6 +126,18 @@ export default {
|
|
|
114
126
|
}
|
|
115
127
|
]
|
|
116
128
|
},
|
|
129
|
+
createBulk: {
|
|
130
|
+
target: "/raclette__core/interactionLink/bulk",
|
|
131
|
+
method: "post",
|
|
132
|
+
storeActionType: "dataCreate",
|
|
133
|
+
channels: [
|
|
134
|
+
{
|
|
135
|
+
channel: "raclette__core--interactionLinksCreated",
|
|
136
|
+
channelKey: "interactionLinksCreated",
|
|
137
|
+
prefix: "raclette__core"
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
},
|
|
117
141
|
delete: {
|
|
118
142
|
target: (payload) => `/raclette__core/interactionLink/${payload._id}`,
|
|
119
143
|
method: "delete",
|
|
@@ -176,30 +200,6 @@ export default {
|
|
|
176
200
|
prefix: "raclette__core"
|
|
177
201
|
}
|
|
178
202
|
]
|
|
179
|
-
},
|
|
180
|
-
delete: {
|
|
181
|
-
target: (payload) => `/raclette__core/project/${payload._id}`,
|
|
182
|
-
method: "delete",
|
|
183
|
-
storeActionType: "dataUpdate",
|
|
184
|
-
channels: [
|
|
185
|
-
{
|
|
186
|
-
channel: "raclette__core--projectDeleted",
|
|
187
|
-
channelKey: "projectDeleted",
|
|
188
|
-
prefix: "raclette__core"
|
|
189
|
-
}
|
|
190
|
-
]
|
|
191
|
-
},
|
|
192
|
-
deleteHard: {
|
|
193
|
-
target: (payload) => `/raclette__core/project/${payload._id}/hard`,
|
|
194
|
-
method: "delete",
|
|
195
|
-
storeActionType: "dataHardDeleted",
|
|
196
|
-
channels: [
|
|
197
|
-
{
|
|
198
|
-
channel: "raclette__core--projectHardDeleted",
|
|
199
|
-
channelKey: "projectHardDeleted",
|
|
200
|
-
prefix: "raclette__core"
|
|
201
|
-
}
|
|
202
|
-
]
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
},
|
|
@@ -228,6 +228,18 @@ export default {
|
|
|
228
228
|
}
|
|
229
229
|
]
|
|
230
230
|
},
|
|
231
|
+
updateRestore: {
|
|
232
|
+
target: (payload) => `/raclette__core/tag/${payload._id}/restore`,
|
|
233
|
+
method: "patch",
|
|
234
|
+
storeActionType: "dataRestore",
|
|
235
|
+
channels: [
|
|
236
|
+
{
|
|
237
|
+
channel: "raclette__core--tagRestored",
|
|
238
|
+
channelKey: "tagRestored",
|
|
239
|
+
prefix: "raclette__core"
|
|
240
|
+
}
|
|
241
|
+
]
|
|
242
|
+
},
|
|
231
243
|
create: {
|
|
232
244
|
target: (payload) => `/raclette__core/tag/${payload.project}/${payload._id}`,
|
|
233
245
|
method: "post",
|
|
@@ -240,6 +252,18 @@ export default {
|
|
|
240
252
|
}
|
|
241
253
|
]
|
|
242
254
|
},
|
|
255
|
+
createBulk: {
|
|
256
|
+
target: "/raclette__core/tag/bulk",
|
|
257
|
+
method: "post",
|
|
258
|
+
storeActionType: "dataCreate",
|
|
259
|
+
channels: [
|
|
260
|
+
{
|
|
261
|
+
channel: "raclette__core--tagsCreated",
|
|
262
|
+
channelKey: "tagsCreated",
|
|
263
|
+
prefix: "raclette__core"
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
},
|
|
243
267
|
delete: {
|
|
244
268
|
target: (payload) => `/raclette__core/tag/${payload._id}`,
|
|
245
269
|
method: "delete",
|
|
@@ -291,6 +315,18 @@ export default {
|
|
|
291
315
|
}
|
|
292
316
|
]
|
|
293
317
|
},
|
|
318
|
+
updateRestore: {
|
|
319
|
+
target: (payload) => `/raclette__core/user/${payload._id}/restore`,
|
|
320
|
+
method: "patch",
|
|
321
|
+
storeActionType: "dataRestore",
|
|
322
|
+
channels: [
|
|
323
|
+
{
|
|
324
|
+
channel: "raclette__core--userRestored",
|
|
325
|
+
channelKey: "userRestored",
|
|
326
|
+
prefix: "raclette__core"
|
|
327
|
+
}
|
|
328
|
+
]
|
|
329
|
+
},
|
|
294
330
|
create: {
|
|
295
331
|
target: "/raclette__core/user",
|
|
296
332
|
method: "post",
|
|
@@ -315,6 +351,18 @@ export default {
|
|
|
315
351
|
}
|
|
316
352
|
]
|
|
317
353
|
},
|
|
354
|
+
deleteHard: {
|
|
355
|
+
target: (payload) => `/raclette__core/user/${payload._id}/hard`,
|
|
356
|
+
method: "delete",
|
|
357
|
+
storeActionType: "dataHardDeleted",
|
|
358
|
+
channels: [
|
|
359
|
+
{
|
|
360
|
+
channel: "raclette__core--userHardDeleted",
|
|
361
|
+
channelKey: "userHardDeleted",
|
|
362
|
+
prefix: "raclette__core"
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
},
|
|
318
366
|
updateLastProject: {
|
|
319
367
|
target: (payload) => `/raclette__core/user/last-project/${payload.projectId}`,
|
|
320
368
|
method: "patch",
|
|
@@ -329,6 +377,69 @@ export default {
|
|
|
329
377
|
}
|
|
330
378
|
}
|
|
331
379
|
},
|
|
380
|
+
workSession: {
|
|
381
|
+
type: "workSession",
|
|
382
|
+
operations: {
|
|
383
|
+
getAll: {
|
|
384
|
+
target: "/raclette__core/workSession/all",
|
|
385
|
+
method: "get",
|
|
386
|
+
storeActionType: "dataRead"
|
|
387
|
+
},
|
|
388
|
+
get: {
|
|
389
|
+
target: (payload) => `/raclette__core/workSession/${payload._id}`,
|
|
390
|
+
method: "get",
|
|
391
|
+
storeActionType: "dataRead"
|
|
392
|
+
},
|
|
393
|
+
create: {
|
|
394
|
+
target: "/raclette__core/workSession",
|
|
395
|
+
method: "post",
|
|
396
|
+
storeActionType: "dataCreate",
|
|
397
|
+
channels: [
|
|
398
|
+
{
|
|
399
|
+
channel: "raclette__core--workSessionCreated",
|
|
400
|
+
channelKey: "workSessionCreated",
|
|
401
|
+
prefix: "raclette__core"
|
|
402
|
+
}
|
|
403
|
+
]
|
|
404
|
+
},
|
|
405
|
+
update: {
|
|
406
|
+
target: (payload) => `/raclette__core/workSession/${payload._id}`,
|
|
407
|
+
method: "patch",
|
|
408
|
+
storeActionType: "dataUpdate",
|
|
409
|
+
channels: [
|
|
410
|
+
{
|
|
411
|
+
channel: "raclette__core--workSessionUpdated",
|
|
412
|
+
channelKey: "workSessionUpdated",
|
|
413
|
+
prefix: "raclette__core"
|
|
414
|
+
}
|
|
415
|
+
]
|
|
416
|
+
},
|
|
417
|
+
delete: {
|
|
418
|
+
target: (payload) => `/raclette__core/workSession/${payload._id}`,
|
|
419
|
+
method: "delete",
|
|
420
|
+
storeActionType: "dataUpdate",
|
|
421
|
+
channels: [
|
|
422
|
+
{
|
|
423
|
+
channel: "raclette__core--workSessionDeleted",
|
|
424
|
+
channelKey: "workSessionDeleted",
|
|
425
|
+
prefix: "raclette__core"
|
|
426
|
+
}
|
|
427
|
+
]
|
|
428
|
+
},
|
|
429
|
+
deleteHard: {
|
|
430
|
+
target: (payload) => `/raclette__core/workSession/${payload._id}/hard`,
|
|
431
|
+
method: "delete",
|
|
432
|
+
storeActionType: "dataHardDeleted",
|
|
433
|
+
channels: [
|
|
434
|
+
{
|
|
435
|
+
channel: "raclette__core--workSessionHardDeleted",
|
|
436
|
+
channelKey: "workSessionHardDeleted",
|
|
437
|
+
prefix: "raclette__core"
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
},
|
|
332
443
|
composition: {
|
|
333
444
|
type: "composition",
|
|
334
445
|
operations: {
|
|
@@ -354,6 +465,18 @@ export default {
|
|
|
354
465
|
}
|
|
355
466
|
]
|
|
356
467
|
},
|
|
468
|
+
updateRestore: {
|
|
469
|
+
target: (payload) => `/raclette__core/composition/${payload._id}/restore`,
|
|
470
|
+
method: "patch",
|
|
471
|
+
storeActionType: "dataRestore",
|
|
472
|
+
channels: [
|
|
473
|
+
{
|
|
474
|
+
channel: "raclette__core--compositionRestored",
|
|
475
|
+
channelKey: "compositionRestored",
|
|
476
|
+
prefix: "raclette__core"
|
|
477
|
+
}
|
|
478
|
+
]
|
|
479
|
+
},
|
|
357
480
|
create: {
|
|
358
481
|
target: "/raclette__core/composition",
|
|
359
482
|
method: "post",
|
|
@@ -366,6 +489,18 @@ export default {
|
|
|
366
489
|
}
|
|
367
490
|
]
|
|
368
491
|
},
|
|
492
|
+
createBulk: {
|
|
493
|
+
target: "/raclette__core/composition/bulk",
|
|
494
|
+
method: "post",
|
|
495
|
+
storeActionType: "dataCreate",
|
|
496
|
+
channels: [
|
|
497
|
+
{
|
|
498
|
+
channel: "raclette__core--compositionsCreated",
|
|
499
|
+
channelKey: "compositionsCreated",
|
|
500
|
+
prefix: "raclette__core"
|
|
501
|
+
}
|
|
502
|
+
]
|
|
503
|
+
},
|
|
369
504
|
delete: {
|
|
370
505
|
target: (payload) => `/raclette__core/composition/${payload._id}`,
|
|
371
506
|
method: "delete",
|