@mbc-cqrs-serverless/sequence
Version:
Generate increment sequence with time-rotation
269 lines (208 loc) • 7.61 kB
Markdown

[](https://www.npmjs.com/package/@mbc-cqrs-serverless/sequence)
[](https://opensource.org/licenses/MIT)
Robust sequence number generation for the MBC CQRS Serverless framework. Generate unique, formatted sequence numbers with automatic rotation support for invoices, orders, tickets, and more.
- **Atomic Counter**: DynamoDB-based atomic operations ensure no duplicates
- **Flexible Rotation**: Reset sequences by fiscal year, year, month, or day
- **Custom Formatting**: Configure prefixes, padding, and format patterns
- **Multi-tenant**: Isolated sequences per tenant
- **Hierarchical Codes**: Support up to 5 levels of code hierarchy
```bash
npm install @mbc-cqrs-serverless/sequence
```
```typescript
import { Module } from '@nestjs/common';
import { SequencesModule } from '@mbc-cqrs-serverless/sequence';
@Module({
imports: [
SequencesModule.register({
enableController: true, // Optional: enable REST endpoints
}),
],
})
export class AppModule {}
```
```typescript
import { Injectable } from '@nestjs/common';
import { SequencesService, RotateByEnum } from '@mbc-cqrs-serverless/sequence';
import { getUserContext, IInvoke } from '@mbc-cqrs-serverless/core';
@Injectable()
export class InvoiceService {
constructor(private readonly sequencesService: SequencesService) {}
async createInvoice(opts: { invokeContext: IInvoke }) {
const { tenantCode } = getUserContext(opts.invokeContext);
const seq = await this.sequencesService.generateSequenceItem(
{
tenantCode,
typeCode: 'INVOICE',
rotateBy: RotateByEnum.FISCAL_YEARLY,
},
opts,
);
console.log(seq.no); // 1
console.log(seq.formattedNo); // "INV-0001" (based on master data format)
console.log(seq.issuedAt); // Date object
return seq;
}
}
```
| Method | Description |
|--------|-------------|
| `generateSequenceItem(dto, options)` | Generate sequence using master data configuration |
| `generateSequenceItemWithProvideSetting(dto, options)` | Generate sequence with inline settings |
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `tenantCode` | string | Yes | Tenant identifier |
| `typeCode` | string | Yes | Sequence type (e.g., 'INVOICE', 'ORDER') |
| `rotateBy` | RotateByEnum | No | Rotation strategy |
| `date` | Date | No | Date for sequence (default: now) |
| `prefix` | string | No | Prefix to add before formatted number |
| `postfix` | string | No | Postfix to add after formatted number |
| `params` | object | No | Additional parameters (code1-code5) |
### RotateByEnum
| Value | Description | Example Reset |
|-------|-------------|---------------|
| `FISCAL_YEARLY` | Reset on fiscal year start (April 1st in Japan) | Apr 1, 2024 |
| `YEARLY` | Reset on calendar year | Jan 1, 2024 |
| `MONTHLY` | Reset each month | First of each month |
| `DAILY` | Reset each day | Every day |
| `NONE` | Never reset, continuous increment | Never |
### SequenceEntity (Return Type)
```typescript
{
id: string; // Unique identifier
no: number; // Raw sequence number
formattedNo: string; // Formatted sequence string
issuedAt: Date; // Timestamp of generation
}
```
Sequences reset on April 1st:
```typescript
const seq = await this.sequencesService.generateSequenceItem(
{
tenantCode: 'MBC',
typeCode: 'INVOICE',
rotateBy: RotateByEnum.FISCAL_YEARLY,
},
opts,
);
// FY2024: INV-0001, INV-0002, ...
// FY2025 (after Apr 1): INV-0001, INV-0002, ...
```
Sequences reset on the first of each month:
```typescript
const seq = await this.sequencesService.generateSequenceItem(
{
tenantCode: 'MBC',
typeCode: 'ORDER',
rotateBy: RotateByEnum.MONTHLY,
},
opts,
);
// January: ORD-202401-0001, ORD-202401-0002
// February: ORD-202402-0001, ORD-202402-0002
```
Sequences reset every day:
```typescript
const seq = await this.sequencesService.generateSequenceItem(
{
tenantCode: 'MBC',
typeCode: 'TICKET',
rotateBy: RotateByEnum.DAILY,
},
opts,
);
// Day 1: TKT-20240115-001, TKT-20240115-002
// Day 2: TKT-20240116-001, TKT-20240116-002
```
Use code1-code5 for hierarchical sequence numbers:
```typescript
const seq = await this.sequencesService.generateSequenceItem(
{
tenantCode: 'MBC',
typeCode: 'PRODUCT',
params: {
code1: 'ELECTRONICS',
code2: 'PHONES',
},
rotateBy: RotateByEnum.YEARLY,
},
opts,
);
// Each category has its own sequence: ELECTRONICS-PHONES-0001
```
Provide format settings directly without master data lookup:
```typescript
const seq = await this.sequencesService.generateSequenceItemWithProvideSetting(
{
tenantCode: 'MBC',
typeCode: 'CUSTOM',
format: '%%year%%-%%month#:0>2%%-%%no#:0>4%%',
rotateBy: RotateByEnum.MONTHLY,
prefix: 'DOC-',
},
opts,
);
// Result: DOC-2024-01-0001
```
Format strings use `%%key%%` syntax with optional padding:
| Pattern | Output | Description |
|---------|--------|-------------|
| `%%no%%` | `1` | Raw number |
| `%%no
| `%%year%%` | `2024` | Current year |
| `%%month%%` | `1` | Current month (1-12) |
| `%%month#:0>2%%` | `01` | Zero-padded month |
| `%%day%%` | `15` | Current day |
| `%%fiscal_year%%` | `71` | Fiscal year number |
| `%%code1%%` | `DEPT` | Hierarchical code 1 |
## Master Data Configuration
The `generateSequenceItem` method reads format configuration from master data:
```json
{
"pk": "MASTER#MBC",
"sk": "MASTER_DATA#INVOICE",
"format": "%%year%%-%%no#:0>4%%",
"startMonth": 4,
"registerDate": "2024-04-01"
}
```
All sequence operations use DynamoDB atomic counters, ensuring thread-safe generation:
```typescript
// Safe for concurrent requests
const results = await Promise.all([
sequencesService.generateSequenceItem({ tenantCode, typeCode: 'ORDER' }, opts),
sequencesService.generateSequenceItem({ tenantCode, typeCode: 'ORDER' }, opts),
sequencesService.generateSequenceItem({ tenantCode, typeCode: 'ORDER' }, opts),
]);
// Results: [{ no: 1 }, { no: 2 }, { no: 3 }] - guaranteed unique
```
| Package | Description |
|---------|-------------|
| [@mbc-cqrs-serverless/core](https://www.npmjs.com/package/@mbc-cqrs-serverless/core) | Core CQRS framework |
| [@mbc-cqrs-serverless/master](https://www.npmjs.com/package/@mbc-cqrs-serverless/master) | Master data for sequence formats |
Full documentation available at [https://mbc-cqrs-serverless.mbc-net.com/](https://mbc-cqrs-serverless.mbc-net.com/)
- [Sequence Service Guide](https://mbc-cqrs-serverless.mbc-net.com/docs/sequence-service)
- [Build a Todo App Tutorial](https://mbc-cqrs-serverless.mbc-net.com/docs/build-todo-app)
Copyright © 2024-2025, Murakami Business Consulting, Inc. [https://www.mbc-net.com/](https://www.mbc-net.com/)
This project is under the [MIT License](../../LICENSE.txt).