Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Sequence] Sequence Package #76

Merged
merged 5 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "0.1.33-beta.0",
"version": "0.1.35-beta.0",
"packages": ["packages/*"]
}
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mbc-cqrs-serverless/cli",
"version": "0.1.33-beta.0",
"version": "0.1.35-beta.0",
"description": "a CLI to get started with MBC CQRS serverless framework",
"keywords": [
"mbc",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mbc-cqrs-serverless/core",
"version": "0.1.33-beta.0",
"version": "0.1.35-beta.0",
"description": "CQRS and event base core",
"keywords": [
"mbc",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/constants/tenant.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const HEADER_TENANT_CODE = 'x-tenant-code'
export const TENANT_COMMON = 'common'
export const DEFAULT_TENANT_CODE = 'single'
7 changes: 7 additions & 0 deletions packages/core/src/helpers/key.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DEFAULT_TENANT_CODE } from '../constants'
import { KEY_SEPARATOR, VER_SEPARATOR } from '../constants/key'

export function addSortKeyVersion(sk: string, version: number) {
Expand Down Expand Up @@ -40,3 +41,9 @@ export function parseS3AttributeKey(s3Uri: string) {
key,
}
}

export const masterPk = (tenantCode?: string) =>
`MASTER${KEY_SEPARATOR}${tenantCode || DEFAULT_TENANT_CODE}`

export const seqPk = (tenantCode?: string) =>
`SEQ${KEY_SEPARATOR}${tenantCode || DEFAULT_TENANT_CODE}`
1 change: 1 addition & 0 deletions packages/core/src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from './event.interface'
export * from './event-factory.interface'
export * from './event-handler.interface'
export * from './event-raw.interface'
export * from './master.interface'
export * from './notification.interface'
export * from './paginate.dto'
export * from './search.dto'
10 changes: 10 additions & 0 deletions packages/core/src/interfaces/master.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { DetailKey } from './detail-key.interface'

export interface IMasterDataProvider {
/**
* Get the data for a specific key.
* @param key - The key to identify the data.
* @returns A promise that resolves to the data.
*/
getData(key: DetailKey): Promise<any>
}
4 changes: 2 additions & 2 deletions packages/sequence/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mbc-cqrs-serverless/sequence",
"version": "0.1.33-beta.0",
"version": "0.1.35-beta.0",
"description": "Generate increment sequence with time-rotation",
"keywords": [
"mbc",
Expand Down Expand Up @@ -41,6 +41,6 @@
"access": "public"
},
"dependencies": {
"@mbc-cqrs-serverless/core": "^0.1.33-beta.0"
"@mbc-cqrs-serverless/core": "^0.1.35-beta.0"
}
}
13 changes: 13 additions & 0 deletions packages/sequence/src/constants/sequence.constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
type MasterDataType = {
typeCode: string
format: string
startMonth?: number
registerDate?: Date
}

export const DEFAULT_MASTER_DATA = Symbol('DEFAULT_MASTER_DATA')

export const DEFAULT_VALUE_MASTER_DATA: MasterDataType = {
typeCode: 'sequence',
format: '%%no%%',
}
79 changes: 56 additions & 23 deletions packages/sequence/src/dto/gen-sequence.dto.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { ApiProperty } from '@nestjs/swagger'
import {
IsEnum,
IsNumber,
IsObject,
IsOptional,
IsString,
} from 'class-validator'
import { Type } from 'class-transformer'
import { IsEnum, IsObject, IsOptional, IsString } from 'class-validator'

import { RotateByEnum } from '../enums/rotate-by.enum'

Expand All @@ -16,7 +11,8 @@ export class SequenceParamsDto {
code1: string

@IsString()
code2: string
@IsOptional()
code2?: string

@IsOptional()
@IsString()
Expand All @@ -36,42 +32,79 @@ export class SequenceParamsDto {
}

export class GenSequenceDto {
@IsString()
/**
* Date for sequence generation (optional).
*/
@IsOptional()
@Type(() => Date)
@ApiProperty({
type: Date,
required: false,
description: 'Date for sequence generation.',
})
date?: Date

/**
* Rotation criteria for the sequence (e.g., yearly, fiscal-yearly).
*/
@ApiProperty({ enum: RotateByEnum, example: RotateByEnum.FISCAL_YEARLY })
@IsOptional()
@IsEnum(RotateByEnum)
rotateBy?: RotateByEnum

/**
* Tenant code for identifying the organization.
*/
@IsString()
@ApiProperty({ description: 'Code of the tenant (organization).' })
tenantCode: string

@IsObject()
params: SequenceParamsDto

/**
* Format of no
* Type code for specific sequence classification.
*/

@IsString()
@IsOptional()
format?: string
@ApiProperty({
required: true,
description: 'Type code for specific classification.',
})
typeCode: string
}

export class GenerateFormattedSequenceDto {
/**
* Start month of fiscal year (default: 4)
* Date for sequence generation (optional).
*/

@IsNumber()
@IsOptional()
startMonth?: number
@Type(() => Date)
@ApiProperty({
type: Date,
required: false,
description: 'Date for sequence generation.',
})
date?: Date

/**
* Company registration date
* Rotation criteria for the sequence (e.g., yearly, fiscal-yearly).
*/
@ApiProperty({ enum: RotateByEnum, example: RotateByEnum.FISCAL_YEARLY })
@IsOptional()
@IsEnum(RotateByEnum)
rotateBy?: RotateByEnum

/**
* Tenant code for identifying the organization.
*/
@IsString()
@IsOptional()
registerDate?: Date
tenantCode: string

/**
* Type code for specific sequence classification.
*/
@IsObject()
@ApiProperty({
type: SequenceParamsDto,
description:
'Parameters for generating the sequence. code1, code2,code3, code4, code5',
})
params: SequenceParamsDto
}
10 changes: 10 additions & 0 deletions packages/sequence/src/entities/sequence.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export class SequenceEntity {
id: string
no: number
formattedNo: string
issuedAt: Date

constructor(partial: Partial<SequenceEntity>) {
Object.assign(this, partial)
}
}
32 changes: 30 additions & 2 deletions packages/sequence/src/interfaces/sequence-service.interface.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
import { DataEntity, DetailKey, IInvoke } from '@mbc-cqrs-serverless/core'

import { GenSequenceDto } from '../dto/gen-sequence.dto'
import {
GenerateFormattedSequenceDto,
GenSequenceDto,
} from '../dto/gen-sequence.dto'
import { SequenceEntity } from '../entities/sequence.entity'

export interface ISequenceService {
/**
* Get the current sequence by a specific key.
* @param key - The key to identify the sequence details.
* @returns A promise that resolves to the current sequence's data entity.
*/
getCurrentSequence(key: DetailKey): Promise<DataEntity>

/**
* Generate a new sequence based on the provided parameters.
* @param dto - The data transfer object containing generation parameters.
* @param opts - Additional options including invocation context.
* @returns A promise that resolves to the newly generated sequence's data entity.
*/
genNewSequence(
dto: GenSequenceDto,
opts: {
options: {
invokeContext: IInvoke
},
): Promise<DataEntity>

/**
* Generate a new sequence with a specified format.
* @param dto - The data transfer object containing parameters for formatted sequence generation.
* @param opts - Additional options including invocation context.
* @returns A promise that resolves to the newly generated formatted sequence's data entity.
*/
generateSequenceItem(
dto: GenerateFormattedSequenceDto,
options: {
invokeContext: IInvoke
},
): Promise<SequenceEntity>
}
32 changes: 32 additions & 0 deletions packages/sequence/src/sequence-master-factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
DetailKey,
DynamoDbService,
IMasterDataProvider,
} from '@mbc-cqrs-serverless/core'
import { Inject, Injectable, Optional } from '@nestjs/common'

import { DEFAULT_MASTER_DATA } from './constants/sequence.constant'

Injectable()
export class SequenceMasterDataProvider implements IMasterDataProvider {
private tableName
constructor(
private readonly dynamoDbService: DynamoDbService,
@Inject(DEFAULT_MASTER_DATA)
@Optional()
private readonly defaultValue: Record<string, any>,
) {
this.tableName = dynamoDbService.getTableName('master', 'data')
}
async getData(key: DetailKey): Promise<any> {
try {
const item = await this.dynamoDbService.getItem(this.tableName, key)
if (!item) {
return this.defaultValue
}
return item
} catch (error) {
return this.defaultValue
}
}
}
14 changes: 13 additions & 1 deletion packages/sequence/src/sequence.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { DataStoreModule } from '@mbc-cqrs-serverless/core'
import { DynamicModule, Module } from '@nestjs/common'

import {
DEFAULT_MASTER_DATA,
DEFAULT_VALUE_MASTER_DATA,
} from './constants/sequence.constant'
import { SequenceMasterDataProvider } from './sequence-master-factory'
import { SequencesController } from './sequences.controller'
import {
ConfigurableModuleClass,
Expand All @@ -10,7 +15,14 @@ import { SequencesService } from './sequences.service'

@Module({
imports: [DataStoreModule],
providers: [SequencesService],
providers: [
SequencesService,
SequenceMasterDataProvider,
{
provide: DEFAULT_MASTER_DATA,
useValue: DEFAULT_VALUE_MASTER_DATA,
},
],
exports: [SequencesService],
})
export class SequencesModule extends ConfigurableModuleClass {
Expand Down
Loading