Sequence
1. Purpose
SequenceModule is a service for managing dynamic sequences in the system using DynamoDB as the primary database.
This service is designed to:
- Generate unique sequence numbers based on parameters such as sequence type, tenant, or date.
- Automatically reset sequences based on cycles like:
- Daily.
- Monthly.
- Yearly.
- Fiscal Yearly.
Format sequence numbers according to specific system requirements (e.g., TODO-PERSONAL-72-001). Ensure data consistency and integrity in multi-tenant systems.
How It Works
2. Usage
The solution for customizing the behavior of the SequenceModule is to pass it an options object in the static register() method. The options object is only contain one property:
enableController: enable or disable default sequence controller.
We will create a simple example demonstrating how to use the sequence module and customize authentication for the sequence controller.
// seq.controller.ts
import { SequencesController } from "@mbc-cqrs-serverless/sequence";
import { Controller } from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { Auth } from "src/auth/auth.decorator";
import { ROLE } from "src/auth/role.enum";
@Controller("api/sequence")
@ApiTags("sequence")
@Auth(ROLE.JCCI_ADMIN)
export class SeqController extends SequencesController {}
// seq.module.ts
import { SequencesModule } from "@mbc-cqrs-serverless/sequence";
import { Module } from "@nestjs/common";
import { SeqController } from "./seq.controller";
@Module({
imports: [SequencesModule.register({ enableController: false })],
controllers: [SeqController],
exports: [SequencesModule],
})
export class SeqModule {}
Beside controller, we can directly use SequencesService to generating sequence by injecting service.
The SequencesService has four public methods (two current, one deprecated, one removed in v1.1.0):
async generateSequenceItem( dto: GenerateFormattedSequenceDto, options?: {invokeContext:IInvoke}): Promise<SequenceEntity>
Generates a new sequence based on the parameters provided in the GenerateFormattedSequenceDto object.
Parameters
dto: GenerateFormattedSequenceDto
The data transfer object that customizes the behavior of the sequence generation. Its properties include:
-
date?: Date- Default: Current date.
- Description: Specifies the date for which the sequence is generated.
-
rotateBy?: RotateByEnum- Default: NONE.
- Options
- FISCAL_YEARLY (
'fiscal_yearly') - YEARLY (
'yearly') - MONTHLY (
'monthly') - DAILY (
'daily') - NONE (
'none')
- FISCAL_YEARLY (
- Description: Determines the rotation type for the sequence.
-
tenantCode: string- Required: Yes.
- Description: Identifies the tenant and type code for the intended usage.
-
typeCode: string- Required: Yes.
- Description: Identifies the tenant and type code for the intended usage.
-
params?: SequenceParamsDto- Required: No.
- Description: Defines parameters to identify the sequence.
export class SequenceParamsDto {
@IsString()
code1: string
@IsString()
@IsOptional()
code2?: string
@IsOptional()
@IsString()
code3?: string
@IsOptional()
@IsString()
code4?: string
@IsOptional()
@IsString()
code5?: string
constructor(partial: Partial<SequenceParamsDto>) {
Object.assign(this, partial)
}
}
-
prefix?: string- Required: No.
- Description: Optional prefix to prepend to the formatted sequence. The prefix is added before the formatted pattern.
- Example: If prefix is
'INV-'and format produces'2024-001', the result will be'INV-2024-001'.
-
postfix?: string- Required: No.
- Description: Optional postfix to append to the formatted sequence. The postfix is added after the formatted pattern.
- Example: If postfix is
'-DRAFT'and format produces'2024-001', the result will be'2024-001-DRAFT'.
Response
The return value of this function has type of SequenceEntity as follows:
export class SequenceEntity {
id: string
no: number
formattedNo: string
issuedAt: Date
constructor(partial: Partial<SequenceEntity>) {
Object.assign(this, partial)
}
}
Customizable
By default, the returned data includes the formattedNo field with the format %%no%%, where no represents the sequence number. If you want to define your own custom format, you can update the master data in DynamoDB with the following parameters:
- PK:
MASTER${KEY_SEPARATOR}${tenantCode} - SK:
MASTER_DATA${KEY_SEPARATOR}${typeCode}
The data structure should be as follows:
{
"format": "string",
"startMonth": "number",
"registerDate": "string"
}