Skip to content

Commit 9fd2d63

Browse files
committed
Add LifecycleRefId constant and update lifecycle history retrieval to include total count
1 parent 3f5cc90 commit 9fd2d63

File tree

3 files changed

+102
-19
lines changed

3 files changed

+102
-19
lines changed

src/management/lifecycle/_schemas/lifecycle.schema.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { IdentityLifecycle } from '~/management/identities/_enums/lifecycle.enum
55

66
export type LifecycleDocument = Lifecycle & Document;
77

8+
export const LifecycleRefId = 'refId';
9+
810
@Schema({ versionKey: false, minimize: false })
911
export class Lifecycle extends AbstractSchema {
1012
@Prop({

src/management/lifecycle/lifecycle.controller.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@ export class LifecycleController extends AbstractController {
3535
public async getLifecycleHistory(
3636
@Param('identityId', ObjectIdValidationPipe) identityId: Types.ObjectId,
3737
@Res() res: Response,
38+
@SearchFilterOptions() searchFilterOptions: FilterOptions,
3839
): Promise<Response<Lifecycle[]>> {
40+
const [total, data] = await this._service.getLifecycleHistory(identityId, searchFilterOptions);
41+
3942
return res.status(HttpStatus.OK).json({
4043
statusCode: HttpStatus.OK,
41-
data: await this._service.getLifecycleHistory(identityId),
44+
data,
45+
total,
4246
});
4347
}
4448

src/management/lifecycle/lifecycle.service.ts

Lines changed: 95 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import { FilterOptions } from '@the-software-compagny/nestjs_module_restools';
55
import { Model, Query, Types } from 'mongoose';
66
import { AbstractServiceSchema } from '~/_common/abstracts/abstract.service.schema';
77
import { Identities } from '../identities/_schemas/identities.schema';
8-
import { Lifecycle } from './_schemas/lifecycle.schema';
8+
import { Lifecycle, LifecycleRefId } from './_schemas/lifecycle.schema';
99
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
1010
import { parse } from 'yaml';
1111
import { plainToInstance } from 'class-transformer';
1212
import { ConfigObjectIdentitiesDTO, ConfigObjectSchemaDTO } from './_dto/config.dto';
1313
import { validateOrReject } from 'class-validator';
1414
import { omit } from 'radash';
15+
import { IdentitiesCrudService } from '../identities/identities-crud.service';
1516

1617
interface LifecycleSource {
1718
[source: string]: Partial<ConfigObjectIdentitiesDTO>[];
@@ -21,7 +22,10 @@ interface LifecycleSource {
2122
export class LifecycleService extends AbstractServiceSchema implements OnApplicationBootstrap, OnModuleInit {
2223
protected lifecycleSources: LifecycleSource = {};
2324

24-
public constructor(@InjectModel(Lifecycle.name) protected _model: Model<Lifecycle>) {
25+
public constructor(
26+
@InjectModel(Lifecycle.name) protected _model: Model<Lifecycle>,
27+
protected readonly identitiesService: IdentitiesCrudService,
28+
) {
2529
super();
2630
}
2731

@@ -153,40 +157,112 @@ export class LifecycleService extends AbstractServiceSchema implements OnApplica
153157
return lifecycleRules;
154158
}
155159

160+
/**
161+
* Handle identity update events
162+
* This method listens for events emitted after an identity is updated.
163+
* It checks if the identity has a valid ID and then processes the lifecycle event.
164+
* If the identity's lifecycle has changed, it creates a new lifecycle event.
165+
* It also logs the event handling process, including any warnings if the identity data is invalid.
166+
* This method is triggered by the 'management.identities.service.afterUpdate' event.
167+
*
168+
* @param event - The event containing the identity update data
169+
* @returns A promise that resolves when the lifecycle event is created
170+
*/
171+
@OnEvent('management.identities.service.afterUpdate')
172+
public async handle(event: { updated: Identities, before?: Identities }): Promise<void> {
173+
this.logger.verbose(`Handling identity update event for identity <${event.updated._id}>`);
174+
175+
if (!event.updated || !event.updated._id) {
176+
this.logger.warn('No valid identity found in event data');
177+
return;
178+
}
179+
180+
await this.fireLifecycleEvent(event.before, event.updated);
181+
}
182+
156183
/**
157184
* Handle identity upsert events
158185
* This method listens for events emitted after an identity is upserted.
186+
* It checks if the identity has a valid ID and then processes the lifecycle event.
187+
* If the identity's lifecycle has changed, it creates a new lifecycle event.
188+
* It also logs the event handling process, including any warnings if the identity data is invalid.
189+
* This method is triggered by the 'management.identities.service.afterUpsert' event.
159190
*
160191
* @param event - The event containing the identity upsert data
161192
* @returns A promise that resolves when the lifecycle event is created
162193
*/
163194
@OnEvent('management.identities.service.afterUpsert')
164195
public async handleOrderCreatedEvent(event: { result: Identities, before?: Identities }): Promise<void> {
165196
this.logger.verbose(`Handling identity upsert event for identity <${event.result._id}>`);
197+
166198
if (!event.result || !event.result._id) {
167199
this.logger.warn('No valid identity found in event data');
168200
return;
169201
}
170202

171-
if (event.before && event.before.lifecycle !== event.result.lifecycle) {
203+
await this.fireLifecycleEvent(event.before, event.result);
204+
}
205+
206+
/**
207+
* Fire a lifecycle event
208+
* This method is responsible for processing the lifecycle event for a given identity.
209+
* It checks if the lifecycle has changed and creates a new lifecycle event if necessary.
210+
* It also processes the lifecycle sources associated with the new lifecycle.
211+
* If the lifecycle has changed, it updates the identity's lifecycle based on the rules defined in the lifecycle sources.
212+
* It logs the lifecycle event processing and any updates made to the identity.
213+
* This method is called when an identity's lifecycle changes.
214+
*
215+
* @param before - The identity data before the update
216+
* @param after - The identity data after the update
217+
* @returns A promise that resolves when the lifecycle event is processed
218+
*/
219+
private async fireLifecycleEvent(before: Identities, after: Identities): Promise<void> {
220+
if (before.lifecycle !== after.lifecycle) {
172221
await this.create({
173-
refId: event.result._id,
174-
lifecycle: event.result.lifecycle,
222+
refId: after._id,
223+
lifecycle: after.lifecycle,
175224
date: new Date(),
176225
});
177-
this.logger.debug(`Lifecycle event manualy recorded for identity <${event.result._id}>: ${event.result.lifecycle}`);
178-
return;
226+
this.logger.debug(`Lifecycle event manualy recorded for identity <${after._id}>: ${after.lifecycle}`);
227+
// If the lifecycle has changed, we need to process the new lifecycle
179228
}
180229

181-
if (this.lifecycleSources[event.result.lifecycle]) {
182-
for (const rule of this.lifecycleSources[event.result.lifecycle]) {
183-
// TODO: changer le lifecycle de l'identité si la rule match avec un findOneAndUpdate
230+
if (this.lifecycleSources[after.lifecycle]) {
231+
this.logger.debug(`Processing lifecycle sources for identity <${after._id}> with lifecycle <${after.lifecycle}>`);
232+
233+
for (const lcs of this.lifecycleSources[after.lifecycle]) {
234+
this.logger.verbose(`Processing lifecycle source <${after.lifecycle}> with rules: ${JSON.stringify(lcs.rules)}`);
235+
236+
const res = await this.identitiesService.model.findOneAndUpdate(
237+
{
238+
...lcs.rules,
239+
_id: after._id,
240+
ignoreLifecycle: { $ne: true },
241+
},
242+
{
243+
$set: {
244+
lifecycle: lcs.target,
245+
},
246+
},
247+
{
248+
new: true, // Return the updated document
249+
upsert: false, // Do not create a new document if no match is found
250+
}
251+
);
184252

185-
// await this.create({
186-
// refId: event.result._id,
187-
// lifecycle: event.result.lifecycle,
188-
// date: new Date(),
189-
// });
253+
if (!res) {
254+
this.logger.debug(`No identity found matching rules for lifecycle <${after.lifecycle}>`);
255+
continue;
256+
}
257+
258+
await this.create({
259+
refId: after._id,
260+
lifecycle: lcs.target,
261+
date: new Date(),
262+
});
263+
264+
this.logger.log(`Identity <${res._id}> updated to lifecycle <${lcs.target}> based on rules from source <${after.lifecycle}>`);
265+
return;
190266
}
191267
}
192268
}
@@ -202,18 +278,19 @@ export class LifecycleService extends AbstractServiceSchema implements OnApplica
202278
public async getLifecycleHistory(
203279
refId: Types.ObjectId,
204280
options?: FilterOptions,
205-
): Promise<Query<Array<Lifecycle>, Lifecycle, any, Lifecycle>[]> {
281+
): Promise<[number, Query<Array<Lifecycle>, Lifecycle, any, Lifecycle>[]]> {
206282
const result = await this.find<Lifecycle>({ refId }, null, {
207-
populate: 'refId',
283+
populate: LifecycleRefId,
208284
sort: {
209285
...options?.sort,
210286
createdAt: -1,
211287
},
212288
skip: options?.skip || 0,
213289
limit: options?.limit || 100,
214290
});
291+
const total = await this.count({ refId });
215292

216-
return result;
293+
return [total, result];
217294
}
218295

219296
/**

0 commit comments

Comments
 (0)