extract config files
This commit is contained in:
parent
376260d903
commit
f960299565
18
.env.dist
18
.env.dist
|
@ -10,3 +10,21 @@ DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=configur
|
||||||
MESSAGE_BROKER_URI=amqp://v3-broker:5672
|
MESSAGE_BROKER_URI=amqp://v3-broker:5672
|
||||||
MESSAGE_BROKER_EXCHANGE=mobicoop
|
MESSAGE_BROKER_EXCHANGE=mobicoop
|
||||||
MESSAGE_BROKER_EXCHANGE_DURABILITY=true
|
MESSAGE_BROKER_EXCHANGE_DURABILITY=true
|
||||||
|
|
||||||
|
|
||||||
|
# DEFAULT CONFIGURATION
|
||||||
|
|
||||||
|
# CARPOOL
|
||||||
|
# default carpool departure time margin (in seconds)
|
||||||
|
DEPARTURE_TIME_MARGIN=900
|
||||||
|
# default role
|
||||||
|
ROLE=passenger
|
||||||
|
# seats proposed as driver / requested as passenger
|
||||||
|
SEATS_PROPOSED=3
|
||||||
|
SEATS_REQUESTED=1
|
||||||
|
# accept only same frequency requests
|
||||||
|
STRICT_FREQUENCY=false
|
||||||
|
|
||||||
|
# PAGINATION
|
||||||
|
# number of results per page
|
||||||
|
PER_PAGE=10
|
||||||
|
|
|
@ -2687,6 +2687,12 @@
|
||||||
"pretty-format": "^29.0.0"
|
"pretty-format": "^29.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/js-yaml": {
|
||||||
|
"version": "4.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.8.tgz",
|
||||||
|
"integrity": "sha512-m6jnPk1VhlYRiLFm3f8X9Uep761f+CK8mHyS65LutH2OhmBF0BeMEjHgg05usH8PLZMWWc/BUR9RPmkvpWnyRA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.14",
|
"version": "7.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz",
|
||||||
|
@ -5559,20 +5565,6 @@
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/fsevents": {
|
|
||||||
"version": "2.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
|
||||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
|
||||||
"dev": true,
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
|
|
@ -16,10 +16,24 @@ import { MESSAGE_PUBLISHER } from '@modules/messager/messager.di-tokens';
|
||||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||||
import { ConfigurationModule } from '@modules/configuration/configuration.module';
|
import { ConfigurationModule } from '@modules/configuration/configuration.module';
|
||||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||||
|
import brokerConfig from './config/broker.config';
|
||||||
|
import carpoolConfig from './config/carpool.config';
|
||||||
|
import databaseConfig from './config/database.config';
|
||||||
|
import paginationConfig from './config/pagination.config';
|
||||||
|
import serviceConfig from './config/service.config';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({ isGlobal: true }),
|
ConfigModule.forRoot({
|
||||||
|
isGlobal: true,
|
||||||
|
load: [
|
||||||
|
brokerConfig,
|
||||||
|
carpoolConfig,
|
||||||
|
databaseConfig,
|
||||||
|
paginationConfig,
|
||||||
|
serviceConfig,
|
||||||
|
],
|
||||||
|
}),
|
||||||
EventEmitterModule.forRoot(),
|
EventEmitterModule.forRoot(),
|
||||||
HealthModule.forRootAsync({
|
HealthModule.forRootAsync({
|
||||||
imports: [ConfigurationModule, MessagerModule],
|
imports: [ConfigurationModule, MessagerModule],
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { registerAs } from '@nestjs/config';
|
||||||
|
|
||||||
|
export default registerAs('broker', () => ({
|
||||||
|
uri: process.env.MESSAGE_BROKER_URI ?? 'amqp://v3-broker:5672',
|
||||||
|
exchange: process.env.MESSAGE_BROKER_EXCHANGE ?? 'mobicoop',
|
||||||
|
durability: process.env.MESSAGE_BROKER_EXCHANGE_DURABILITY
|
||||||
|
? process.env.MESSAGE_BROKER_EXCHANGE_DURABILITY === 'false'
|
||||||
|
? false
|
||||||
|
: true
|
||||||
|
: true,
|
||||||
|
}));
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { registerAs } from '@nestjs/config';
|
||||||
|
|
||||||
|
export default registerAs('carpool', () => ({
|
||||||
|
departureTimeMargin: process.env.DEPARTURE_TIME_MARGIN
|
||||||
|
? parseInt(process.env.DEPARTURE_TIME_MARGIN, 10)
|
||||||
|
: 900,
|
||||||
|
role: process.env.ROLE ?? 'passenger',
|
||||||
|
seatsProposed: process.env.SEATS_PROPOSED
|
||||||
|
? parseInt(process.env.SEATS_PROPOSED, 10)
|
||||||
|
: 3,
|
||||||
|
seatsRequested: process.env.SEATS_REQUESTED
|
||||||
|
? parseInt(process.env.SEATS_REQUESTED, 10)
|
||||||
|
: 1,
|
||||||
|
strictFrequency: process.env.STRICT_FREQUENCY
|
||||||
|
? process.env.STRICT_FREQUENCY === 'false'
|
||||||
|
? false
|
||||||
|
: true
|
||||||
|
: false,
|
||||||
|
}));
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { registerAs } from '@nestjs/config';
|
||||||
|
|
||||||
|
export default registerAs('database', () => ({
|
||||||
|
url:
|
||||||
|
process.env.DATABASE_URL ??
|
||||||
|
'postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=configuration',
|
||||||
|
}));
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { registerAs } from '@nestjs/config';
|
||||||
|
|
||||||
|
export default registerAs('pagination', () => ({
|
||||||
|
perPage: process.env.PER_PAGE ? parseInt(process.env.PER_PAGE, 10) : 10,
|
||||||
|
}));
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { registerAs } from '@nestjs/config';
|
||||||
|
|
||||||
|
export default registerAs('service', () => ({
|
||||||
|
url: process.env.SERVICE_URL ?? '0.0.0.0',
|
||||||
|
port: process.env.SERVICE_PORT
|
||||||
|
? parseInt(process.env.SERVICE_PORT, 10)
|
||||||
|
: 5003,
|
||||||
|
}));
|
|
@ -6,6 +6,10 @@ import {
|
||||||
ConfigurationWriteModel,
|
ConfigurationWriteModel,
|
||||||
} from './infrastructure/configuration.repository';
|
} from './infrastructure/configuration.repository';
|
||||||
import { ConfigurationResponseDto } from './interface/dtos/configuration.response.dto';
|
import { ConfigurationResponseDto } from './interface/dtos/configuration.response.dto';
|
||||||
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from './core/domain/configuration.types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mapper constructs objects that are used in different layers:
|
* Mapper constructs objects that are used in different layers:
|
||||||
|
@ -28,9 +32,10 @@ export class ConfigurationMapper
|
||||||
const copy = entity.getProps();
|
const copy = entity.getProps();
|
||||||
const record: ConfigurationWriteModel = {
|
const record: ConfigurationWriteModel = {
|
||||||
uuid: entity.id,
|
uuid: entity.id,
|
||||||
domain: copy.domain,
|
domain: copy.identifier.domain,
|
||||||
key: copy.key,
|
key: copy.identifier.key,
|
||||||
value: copy.value,
|
value: copy.value,
|
||||||
|
type: copy.type,
|
||||||
};
|
};
|
||||||
return record;
|
return record;
|
||||||
};
|
};
|
||||||
|
@ -41,9 +46,12 @@ export class ConfigurationMapper
|
||||||
createdAt: new Date(record.createdAt),
|
createdAt: new Date(record.createdAt),
|
||||||
updatedAt: new Date(record.updatedAt),
|
updatedAt: new Date(record.updatedAt),
|
||||||
props: {
|
props: {
|
||||||
domain: record.domain,
|
identifier: {
|
||||||
|
domain: record.domain as ConfigurationDomain,
|
||||||
key: record.key,
|
key: record.key,
|
||||||
|
},
|
||||||
value: record.value,
|
value: record.value,
|
||||||
|
type: record.type as ConfigurationType,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return entity;
|
return entity;
|
||||||
|
@ -52,9 +60,10 @@ export class ConfigurationMapper
|
||||||
toResponse = (entity: ConfigurationEntity): ConfigurationResponseDto => {
|
toResponse = (entity: ConfigurationEntity): ConfigurationResponseDto => {
|
||||||
const props = entity.getProps();
|
const props = entity.getProps();
|
||||||
const response = new ConfigurationResponseDto(entity);
|
const response = new ConfigurationResponseDto(entity);
|
||||||
response.domain = props.domain;
|
response.domain = props.identifier.domain;
|
||||||
response.key = props.key;
|
response.key = props.identifier.key;
|
||||||
response.value = props.value;
|
response.value = props.value;
|
||||||
|
response.type = props.type;
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ import { SetConfigurationCommand } from './set-configuration.command';
|
||||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||||
import { ConfigurationRepositoryPort } from '../../ports/configuration.repository.port';
|
import { ConfigurationRepositoryPort } from '../../ports/configuration.repository.port';
|
||||||
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
||||||
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
|
|
||||||
@CommandHandler(SetConfigurationCommand)
|
@CommandHandler(SetConfigurationCommand)
|
||||||
export class SetConfigurationService implements ICommandHandler {
|
export class SetConfigurationService implements ICommandHandler {
|
||||||
|
@ -29,7 +33,14 @@ export class SetConfigurationService implements ICommandHandler {
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error instanceof NotFoundException) {
|
if (error instanceof NotFoundException) {
|
||||||
try {
|
try {
|
||||||
const newConfiguration = ConfigurationEntity.create(command);
|
const newConfiguration = ConfigurationEntity.create({
|
||||||
|
identifier: {
|
||||||
|
domain: command.domain as ConfigurationDomain,
|
||||||
|
key: command.key,
|
||||||
|
},
|
||||||
|
value: command.value,
|
||||||
|
type: ConfigurationType.STRING,
|
||||||
|
});
|
||||||
await this.repository.insert(newConfiguration);
|
await this.repository.insert(newConfiguration);
|
||||||
return newConfiguration.id;
|
return newConfiguration.id;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
|
|
@ -21,8 +21,8 @@ export class PublishMessageWhenConfigurationIsDeletedDomainEventHandler {
|
||||||
const configurationDeletedIntegrationEvent =
|
const configurationDeletedIntegrationEvent =
|
||||||
new ConfigurationDeletedIntegrationEvent({
|
new ConfigurationDeletedIntegrationEvent({
|
||||||
id: event.aggregateId,
|
id: event.aggregateId,
|
||||||
domain: event.domain,
|
domain: event.identifier.domain,
|
||||||
key: event.key,
|
key: event.identifier.key,
|
||||||
metadata: event.metadata,
|
metadata: event.metadata,
|
||||||
});
|
});
|
||||||
this.messagePublisher.publish(
|
this.messagePublisher.publish(
|
||||||
|
|
|
@ -18,8 +18,8 @@ export class PublishMessageWhenConfigurationIsSetDomainEventHandler {
|
||||||
const configurationSetIntegrationEvent =
|
const configurationSetIntegrationEvent =
|
||||||
new ConfigurationSetIntegrationEvent({
|
new ConfigurationSetIntegrationEvent({
|
||||||
id: event.aggregateId,
|
id: event.aggregateId,
|
||||||
domain: event.domain,
|
domain: event.identifier.domain,
|
||||||
key: event.key,
|
key: event.identifier.key,
|
||||||
value: event.value,
|
value: event.value,
|
||||||
metadata: event.metadata,
|
metadata: event.metadata,
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
ConfigurationItems,
|
||||||
|
} from './configuration.types';
|
||||||
|
|
||||||
|
export const configurationItems: ConfigurationItems = {
|
||||||
|
[ConfigurationDomain.CARPOOL]: {
|
||||||
|
seatsProposed: {
|
||||||
|
value: '3',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
|
},
|
||||||
|
seatsRequested: {
|
||||||
|
value: '1',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
|
},
|
||||||
|
strictFrequency: {
|
||||||
|
value: 'false',
|
||||||
|
type: ConfigurationType.BOOLEAN,
|
||||||
|
},
|
||||||
|
departureTimeMargin: {
|
||||||
|
value: '900',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
|
},
|
||||||
|
role: {
|
||||||
|
value: 'passenger',
|
||||||
|
type: ConfigurationType.STRING,
|
||||||
|
enum: ['driver', 'passenger'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[ConfigurationDomain.USER]: {},
|
||||||
|
};
|
|
@ -18,9 +18,9 @@ export class ConfigurationEntity extends AggregateRoot<ConfigurationProps> {
|
||||||
configuration.addEvent(
|
configuration.addEvent(
|
||||||
new ConfigurationSetDomainEvent({
|
new ConfigurationSetDomainEvent({
|
||||||
aggregateId: id,
|
aggregateId: id,
|
||||||
domain: props.domain,
|
identifier: props.identifier,
|
||||||
key: props.key,
|
|
||||||
value: props.value,
|
value: props.value,
|
||||||
|
type: props.type,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
return configuration;
|
return configuration;
|
||||||
|
@ -31,9 +31,9 @@ export class ConfigurationEntity extends AggregateRoot<ConfigurationProps> {
|
||||||
this.addEvent(
|
this.addEvent(
|
||||||
new ConfigurationSetDomainEvent({
|
new ConfigurationSetDomainEvent({
|
||||||
aggregateId: this._id,
|
aggregateId: this._id,
|
||||||
domain: this.props.domain,
|
identifier: this.props.identifier,
|
||||||
key: this.props.key,
|
|
||||||
value: props.value,
|
value: props.value,
|
||||||
|
type: this.props.type,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,7 @@ export class ConfigurationEntity extends AggregateRoot<ConfigurationProps> {
|
||||||
this.addEvent(
|
this.addEvent(
|
||||||
new ConfigurationDeletedDomainEvent({
|
new ConfigurationDeletedDomainEvent({
|
||||||
aggregateId: this.id,
|
aggregateId: this.id,
|
||||||
domain: this.props.domain,
|
identifier: this.props.identifier,
|
||||||
key: this.props.key,
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,48 @@
|
||||||
// All properties that a Configuration has
|
// All properties that a Configuration has
|
||||||
export interface ConfigurationProps {
|
export interface ConfigurationProps {
|
||||||
domain: string;
|
identifier: ConfigurationIdentifier;
|
||||||
key: string;
|
value: ConfigurationValue;
|
||||||
value: string;
|
type: ConfigurationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties that are needed for a Configuration creation
|
// Properties that are needed for a Configuration creation
|
||||||
export interface CreateConfigurationProps {
|
export interface CreateConfigurationProps {
|
||||||
domain: string;
|
identifier: ConfigurationIdentifier;
|
||||||
key: string;
|
value: ConfigurationValue;
|
||||||
value: string;
|
type: ConfigurationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateConfigurationProps {
|
export interface UpdateConfigurationProps {
|
||||||
value: string;
|
value: ConfigurationValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Domain {
|
export enum ConfigurationDomain {
|
||||||
AD = 'AD',
|
CARPOOL = 'CARPOOL',
|
||||||
MATCHER = 'MATCHER',
|
|
||||||
USER = 'USER',
|
USER = 'USER',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ConfigurationType {
|
||||||
|
BOOLEAN = 'BOOLEAN',
|
||||||
|
NUMBER = 'NUMBER',
|
||||||
|
STRING = 'STRING',
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ConfigurationIdentifier = {
|
||||||
|
domain: ConfigurationDomain;
|
||||||
|
key: ConfigurationKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConfigurationKey = string;
|
||||||
|
export type ConfigurationValue = string;
|
||||||
|
|
||||||
|
export type ConfigurationItems = Record<
|
||||||
|
ConfigurationDomain,
|
||||||
|
Record<
|
||||||
|
ConfigurationKey,
|
||||||
|
{
|
||||||
|
value: ConfigurationValue;
|
||||||
|
type: ConfigurationType;
|
||||||
|
enum?: Array<string>;
|
||||||
|
}
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
|
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
|
||||||
|
import { ConfigurationIdentifier } from '../configuration.types';
|
||||||
|
|
||||||
export class ConfigurationDeletedDomainEvent extends DomainEvent {
|
export class ConfigurationDeletedDomainEvent extends DomainEvent {
|
||||||
readonly domain: string;
|
readonly identifier: ConfigurationIdentifier;
|
||||||
readonly key: string;
|
|
||||||
|
|
||||||
constructor(props: DomainEventProps<ConfigurationDeletedDomainEvent>) {
|
constructor(props: DomainEventProps<ConfigurationDeletedDomainEvent>) {
|
||||||
super(props);
|
super(props);
|
||||||
this.domain = props.domain;
|
this.identifier = props.identifier;
|
||||||
this.key = props.key;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
|
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
|
||||||
|
import {
|
||||||
|
ConfigurationIdentifier,
|
||||||
|
ConfigurationType,
|
||||||
|
ConfigurationValue,
|
||||||
|
} from '../configuration.types';
|
||||||
|
|
||||||
export class ConfigurationSetDomainEvent extends DomainEvent {
|
export class ConfigurationSetDomainEvent extends DomainEvent {
|
||||||
readonly domain: string;
|
readonly identifier: ConfigurationIdentifier;
|
||||||
readonly key: string;
|
readonly value: ConfigurationValue;
|
||||||
readonly value: string;
|
readonly type: ConfigurationType;
|
||||||
|
|
||||||
constructor(props: DomainEventProps<ConfigurationSetDomainEvent>) {
|
constructor(props: DomainEventProps<ConfigurationSetDomainEvent>) {
|
||||||
super(props);
|
super(props);
|
||||||
this.domain = props.domain;
|
this.identifier = props.identifier;
|
||||||
this.key = props.key;
|
this.type = props.type;
|
||||||
this.value = props.value;
|
this.value = props.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ export type ConfigurationBaseModel = {
|
||||||
domain: string;
|
domain: string;
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
|
type: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConfigurationReadModel = ConfigurationBaseModel & {
|
export type ConfigurationReadModel = ConfigurationBaseModel & {
|
||||||
|
|
|
@ -4,4 +4,5 @@ export class ConfigurationResponseDto extends ResponseBase {
|
||||||
domain: string;
|
domain: string;
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import { ConfigurationDomain } from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class DeleteConfigurationRequestDto {
|
export class DeleteConfigurationRequestDto {
|
||||||
@IsEnum(Domain)
|
@IsEnum(ConfigurationDomain)
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
domain: Domain;
|
domain: ConfigurationDomain;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import { ConfigurationDomain } from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class GetConfigurationRequestDto {
|
export class GetConfigurationRequestDto {
|
||||||
@IsEnum(Domain)
|
@IsEnum(ConfigurationDomain)
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
domain: Domain;
|
domain: ConfigurationDomain;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import { ConfigurationDomain } from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class SetConfigurationRequestDto {
|
export class SetConfigurationRequestDto {
|
||||||
@IsEnum(Domain)
|
@IsEnum(ConfigurationDomain)
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
domain: Domain;
|
domain: ConfigurationDomain;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { ConfigurationMapper } from '@modules/configuration/configuration.mapper
|
||||||
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
||||||
import {
|
import {
|
||||||
CreateConfigurationProps,
|
CreateConfigurationProps,
|
||||||
Domain,
|
ConfigurationDomain,
|
||||||
} from '@modules/configuration/core/domain/configuration.types';
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { ConfigurationRepository } from '@modules/configuration/infrastructure/configuration.repository';
|
import { ConfigurationRepository } from '@modules/configuration/infrastructure/configuration.repository';
|
||||||
import { PrismaService } from '@modules/configuration/infrastructure/prisma.service';
|
import { PrismaService } from '@modules/configuration/infrastructure/prisma.service';
|
||||||
|
@ -36,7 +36,7 @@ describe('Configuration Repository', () => {
|
||||||
for (let i = 0; i < nbToCreate; i++) {
|
for (let i = 0; i < nbToCreate; i++) {
|
||||||
const configurationToCreate = {
|
const configurationToCreate = {
|
||||||
uuid: getSeed(i, baseUuid.uuid),
|
uuid: getSeed(i, baseUuid.uuid),
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.AD,
|
||||||
key: `key${i}`,
|
key: `key${i}`,
|
||||||
value: `value${i}`,
|
value: `value${i}`,
|
||||||
createdAt: '2023-07-24 13:07:05.000',
|
createdAt: '2023-07-24 13:07:05.000',
|
||||||
|
@ -98,7 +98,7 @@ describe('Configuration Repository', () => {
|
||||||
it('should return a configuration', async () => {
|
it('should return a configuration', async () => {
|
||||||
await createConfigurations(1);
|
await createConfigurations(1);
|
||||||
const result = await configurationRepository.findOne({
|
const result = await configurationRepository.findOne({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.AD,
|
||||||
key: 'key0',
|
key: 'key0',
|
||||||
});
|
});
|
||||||
expect(result.getProps().value).toBe('value0');
|
expect(result.getProps().value).toBe('value0');
|
||||||
|
@ -119,7 +119,7 @@ describe('Configuration Repository', () => {
|
||||||
const beforeCount = await prismaService.configuration.count();
|
const beforeCount = await prismaService.configuration.count();
|
||||||
|
|
||||||
const createConfigurationProps: CreateConfigurationProps = {
|
const createConfigurationProps: CreateConfigurationProps = {
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.AD,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
value: '3',
|
value: '3',
|
||||||
};
|
};
|
||||||
|
@ -139,7 +139,7 @@ describe('Configuration Repository', () => {
|
||||||
await createConfigurations(1);
|
await createConfigurations(1);
|
||||||
const configurationToUpdate: ConfigurationEntity =
|
const configurationToUpdate: ConfigurationEntity =
|
||||||
await configurationRepository.findOne({
|
await configurationRepository.findOne({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.AD,
|
||||||
key: 'key0',
|
key: 'key0',
|
||||||
});
|
});
|
||||||
configurationToUpdate.update({ value: 'newValue' });
|
configurationToUpdate.update({ value: 'newValue' });
|
||||||
|
@ -149,7 +149,7 @@ describe('Configuration Repository', () => {
|
||||||
);
|
);
|
||||||
const result: ConfigurationEntity = await configurationRepository.findOne(
|
const result: ConfigurationEntity = await configurationRepository.findOne(
|
||||||
{
|
{
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.AD,
|
||||||
key: 'key0',
|
key: 'key0',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -163,7 +163,7 @@ describe('Configuration Repository', () => {
|
||||||
const beforeCount = await prismaService.configuration.count();
|
const beforeCount = await prismaService.configuration.count();
|
||||||
const configurationToDelete: ConfigurationEntity =
|
const configurationToDelete: ConfigurationEntity =
|
||||||
await configurationRepository.findOne({
|
await configurationRepository.findOne({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.AD,
|
||||||
key: 'key4',
|
key: 'key4',
|
||||||
});
|
});
|
||||||
await configurationRepository.delete(configurationToDelete);
|
await configurationRepository.delete(configurationToDelete);
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { ConfigurationMapper } from '@modules/configuration/configuration.mapper';
|
import { ConfigurationMapper } from '@modules/configuration/configuration.mapper';
|
||||||
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import {
|
import {
|
||||||
ConfigurationReadModel,
|
ConfigurationReadModel,
|
||||||
ConfigurationWriteModel,
|
ConfigurationWriteModel,
|
||||||
|
@ -12,9 +15,12 @@ const now = new Date('2023-06-21 06:00:00');
|
||||||
const configurationEntity: ConfigurationEntity = new ConfigurationEntity({
|
const configurationEntity: ConfigurationEntity = new ConfigurationEntity({
|
||||||
id: 'c160cf8c-f057-4962-841f-3ad68346df44',
|
id: 'c160cf8c-f057-4962-841f-3ad68346df44',
|
||||||
props: {
|
props: {
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
|
},
|
||||||
value: '3',
|
value: '3',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
},
|
},
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
|
@ -24,6 +30,7 @@ const configurationReadModel: ConfigurationReadModel = {
|
||||||
domain: 'AD',
|
domain: 'AD',
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
value: '4',
|
value: '4',
|
||||||
|
type: 'NUMBER',
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
||||||
import {
|
import {
|
||||||
CreateConfigurationProps,
|
CreateConfigurationProps,
|
||||||
Domain,
|
ConfigurationDomain,
|
||||||
UpdateConfigurationProps,
|
UpdateConfigurationProps,
|
||||||
|
ConfigurationType,
|
||||||
} from '@modules/configuration/core/domain/configuration.types';
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { ConfigurationDeletedDomainEvent } from '@modules/configuration/core/domain/events/configuration-deleted.domain-event';
|
import { ConfigurationDeletedDomainEvent } from '@modules/configuration/core/domain/events/configuration-deleted.domain-event';
|
||||||
import { ConfigurationSetDomainEvent } from '@modules/configuration/core/domain/events/configuration-set.domain-event';
|
import { ConfigurationSetDomainEvent } from '@modules/configuration/core/domain/events/configuration-set.domain-event';
|
||||||
|
|
||||||
const createConfigurationProps: CreateConfigurationProps = {
|
const createConfigurationProps: CreateConfigurationProps = {
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
|
},
|
||||||
value: '3',
|
value: '3',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateConfigurationProps: UpdateConfigurationProps = {
|
const updateConfigurationProps: UpdateConfigurationProps = {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||||
import { DeleteConfigurationCommand } from '@modules/configuration/core/application/commands/delete-configuration/delete-configuration.command';
|
import { DeleteConfigurationCommand } from '@modules/configuration/core/application/commands/delete-configuration/delete-configuration.command';
|
||||||
import { DeleteConfigurationService } from '@modules/configuration/core/application/commands/delete-configuration/delete-configuration.service';
|
import { DeleteConfigurationService } from '@modules/configuration/core/application/commands/delete-configuration/delete-configuration.service';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import { ConfigurationDomain } from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { DeleteConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/delete-configuration.request.dto';
|
import { DeleteConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/delete-configuration.request.dto';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
const deleteConfigurationRequest: DeleteConfigurationRequestDto = {
|
const deleteConfigurationRequest: DeleteConfigurationRequestDto = {
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { GetConfigurationQueryHandler } from '@modules/configuration/core/application/queries/get-configuration/get-configuration.query-handler';
|
import { GetConfigurationQueryHandler } from '@modules/configuration/core/application/queries/get-configuration/get-configuration.query-handler';
|
||||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||||
import { GetConfigurationQuery } from '@modules/configuration/core/application/queries/get-configuration/get-configuration.query';
|
import { GetConfigurationQuery } from '@modules/configuration/core/application/queries/get-configuration/get-configuration.query';
|
||||||
|
@ -9,9 +12,12 @@ const now = new Date('2023-06-21 06:00:00');
|
||||||
const configuration: ConfigurationEntity = new ConfigurationEntity({
|
const configuration: ConfigurationEntity = new ConfigurationEntity({
|
||||||
id: 'c160cf8c-f057-4962-841f-3ad68346df44',
|
id: 'c160cf8c-f057-4962-841f-3ad68346df44',
|
||||||
props: {
|
props: {
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
|
},
|
||||||
value: '3',
|
value: '3',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
},
|
},
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
|
@ -47,7 +53,7 @@ describe('Get Configuration Query Handler', () => {
|
||||||
describe('execution', () => {
|
describe('execution', () => {
|
||||||
it('should return a configuration item', async () => {
|
it('should return a configuration item', async () => {
|
||||||
const getConfigurationQuery = new GetConfigurationQuery(
|
const getConfigurationQuery = new GetConfigurationQuery(
|
||||||
Domain.AD,
|
ConfigurationDomain.CARPOOL,
|
||||||
'seatsProposed',
|
'seatsProposed',
|
||||||
);
|
);
|
||||||
const configuration: ConfigurationEntity =
|
const configuration: ConfigurationEntity =
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import {
|
import {
|
||||||
CONFIGURATION_MESSAGE_PUBLISHER,
|
CONFIGURATION_MESSAGE_PUBLISHER,
|
||||||
CONFIGURATION_REPOSITORY,
|
CONFIGURATION_REPOSITORY,
|
||||||
|
@ -17,9 +20,12 @@ const configurationEntities = [
|
||||||
new ConfigurationEntity({
|
new ConfigurationEntity({
|
||||||
id: '047a6ecf-23d4-4d3e-877c-3225d560a8da',
|
id: '047a6ecf-23d4-4d3e-877c-3225d560a8da',
|
||||||
props: {
|
props: {
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
|
},
|
||||||
value: '3',
|
value: '3',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
},
|
},
|
||||||
createdAt: new Date('2023-10-23T07:00:00Z'),
|
createdAt: new Date('2023-10-23T07:00:00Z'),
|
||||||
updatedAt: new Date('2023-10-23T07:00:00Z'),
|
updatedAt: new Date('2023-10-23T07:00:00Z'),
|
||||||
|
@ -27,9 +33,12 @@ const configurationEntities = [
|
||||||
new ConfigurationEntity({
|
new ConfigurationEntity({
|
||||||
id: '047a6ecf-23d4-4d3e-877c-3225d560a8db',
|
id: '047a6ecf-23d4-4d3e-877c-3225d560a8db',
|
||||||
props: {
|
props: {
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsRequested',
|
key: 'seatsRequested',
|
||||||
|
},
|
||||||
value: '1',
|
value: '1',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
},
|
},
|
||||||
createdAt: new Date('2023-10-23T07:00:00Z'),
|
createdAt: new Date('2023-10-23T07:00:00Z'),
|
||||||
updatedAt: new Date('2023-10-23T07:00:00Z'),
|
updatedAt: new Date('2023-10-23T07:00:00Z'),
|
||||||
|
@ -40,14 +49,16 @@ const mockConfigurationMapper = {
|
||||||
toResponse: jest
|
toResponse: jest
|
||||||
.fn()
|
.fn()
|
||||||
.mockImplementationOnce(() => ({
|
.mockImplementationOnce(() => ({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
value: '3',
|
value: '3',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
}))
|
}))
|
||||||
.mockImplementationOnce(() => ({
|
.mockImplementationOnce(() => ({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsRequested',
|
key: 'seatsRequested',
|
||||||
value: '1',
|
value: '1',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,7 +104,7 @@ describe('Propagate Configurations Service', () => {
|
||||||
expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
|
expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
|
||||||
expect(mockMessagePublisher.publish).toHaveBeenCalledWith(
|
expect(mockMessagePublisher.publish).toHaveBeenCalledWith(
|
||||||
CONFIGURATION_PROPAGATED_ROUTING_KEY,
|
CONFIGURATION_PROPAGATED_ROUTING_KEY,
|
||||||
'[{"domain":"AD","key":"seatsProposed","value":"3"},{"domain":"AD","key":"seatsRequested","value":"1"}]',
|
'[{"domain":"CARPOOL","key":"seatsProposed","value":"3","type":"NUMBER"},{"domain":"CARPOOL","key":"seatsRequested","value":"1","type":"NUMBER"}]',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { CONFIGURATION_MESSAGE_PUBLISHER } from '@modules/configuration/configuration.di-tokens';
|
import { CONFIGURATION_MESSAGE_PUBLISHER } from '@modules/configuration/configuration.di-tokens';
|
||||||
import { PublishMessageWhenConfigurationIsDeletedDomainEventHandler } from '@modules/configuration/core/application/event-handlers/publish-message-when-configuration-is-deleted.domain-event-handler';
|
import { PublishMessageWhenConfigurationIsDeletedDomainEventHandler } from '@modules/configuration/core/application/event-handlers/publish-message-when-configuration-is-deleted.domain-event-handler';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import { ConfigurationDomain } from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { ConfigurationDeletedDomainEvent } from '@modules/configuration/core/domain/events/configuration-deleted.domain-event';
|
import { ConfigurationDeletedDomainEvent } from '@modules/configuration/core/domain/events/configuration-deleted.domain-event';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { CONFIGURATION_DELETED_ROUTING_KEY } from '@src/app.constants';
|
import { CONFIGURATION_DELETED_ROUTING_KEY } from '@src/app.constants';
|
||||||
|
@ -33,8 +33,10 @@ describe('Publish message when configuration is deleted domain event handler', (
|
||||||
jest.spyOn(mockMessagePublisher, 'publish');
|
jest.spyOn(mockMessagePublisher, 'publish');
|
||||||
const configurationDeletedDomainEvent: ConfigurationDeletedDomainEvent = {
|
const configurationDeletedDomainEvent: ConfigurationDeletedDomainEvent = {
|
||||||
id: 'some-domain-event-id',
|
id: 'some-domain-event-id',
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
|
},
|
||||||
aggregateId: 'some-aggregate-id',
|
aggregateId: 'some-aggregate-id',
|
||||||
metadata: {
|
metadata: {
|
||||||
timestamp: new Date('2023-06-28T05:00:00Z').getTime(),
|
timestamp: new Date('2023-06-28T05:00:00Z').getTime(),
|
||||||
|
@ -50,7 +52,7 @@ describe('Publish message when configuration is deleted domain event handler', (
|
||||||
expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
|
expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
|
||||||
expect(mockMessagePublisher.publish).toHaveBeenCalledWith(
|
expect(mockMessagePublisher.publish).toHaveBeenCalledWith(
|
||||||
CONFIGURATION_DELETED_ROUTING_KEY,
|
CONFIGURATION_DELETED_ROUTING_KEY,
|
||||||
'{"id":"some-aggregate-id","metadata":{"correlationId":"some-correlation-id","timestamp":1687928400000},"domain":"AD","key":"seatsProposed"}',
|
'{"id":"some-aggregate-id","metadata":{"correlationId":"some-correlation-id","timestamp":1687928400000},"domain":"CARPOOL","key":"seatsProposed"}',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { CONFIGURATION_MESSAGE_PUBLISHER } from '@modules/configuration/configuration.di-tokens';
|
import { CONFIGURATION_MESSAGE_PUBLISHER } from '@modules/configuration/configuration.di-tokens';
|
||||||
import { PublishMessageWhenConfigurationIsSetDomainEventHandler } from '@modules/configuration/core/application/event-handlers/publish-message-when-configuration-is-set.domain-event-handler';
|
import { PublishMessageWhenConfigurationIsSetDomainEventHandler } from '@modules/configuration/core/application/event-handlers/publish-message-when-configuration-is-set.domain-event-handler';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { ConfigurationSetDomainEvent } from '@modules/configuration/core/domain/events/configuration-set.domain-event';
|
import { ConfigurationSetDomainEvent } from '@modules/configuration/core/domain/events/configuration-set.domain-event';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { CONFIGURATION_SET_ROUTING_KEY } from '@src/app.constants';
|
import { CONFIGURATION_SET_ROUTING_KEY } from '@src/app.constants';
|
||||||
|
@ -34,8 +37,11 @@ describe('Publish message when configuration is set domain event handler', () =>
|
||||||
const configurationSetDomainEvent: ConfigurationSetDomainEvent = {
|
const configurationSetDomainEvent: ConfigurationSetDomainEvent = {
|
||||||
id: 'some-domain-event-id',
|
id: 'some-domain-event-id',
|
||||||
aggregateId: 'some-aggregate-id',
|
aggregateId: 'some-aggregate-id',
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
|
},
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
value: '3',
|
value: '3',
|
||||||
metadata: {
|
metadata: {
|
||||||
timestamp: new Date('2023-06-28T05:00:00Z').getTime(),
|
timestamp: new Date('2023-06-28T05:00:00Z').getTime(),
|
||||||
|
@ -51,7 +57,7 @@ describe('Publish message when configuration is set domain event handler', () =>
|
||||||
expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
|
expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
|
||||||
expect(mockMessagePublisher.publish).toHaveBeenCalledWith(
|
expect(mockMessagePublisher.publish).toHaveBeenCalledWith(
|
||||||
CONFIGURATION_SET_ROUTING_KEY,
|
CONFIGURATION_SET_ROUTING_KEY,
|
||||||
'{"id":"some-aggregate-id","metadata":{"correlationId":"some-correlation-id","timestamp":1687928400000},"domain":"AD","key":"seatsProposed","value":"3"}',
|
'{"id":"some-aggregate-id","metadata":{"correlationId":"some-correlation-id","timestamp":1687928400000},"domain":"CARPOOL","key":"seatsProposed","value":"3"}',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { AggregateID, NotFoundException } from '@mobicoop/ddd-library';
|
import { AggregateID, NotFoundException } from '@mobicoop/ddd-library';
|
||||||
import { SetConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/set-configuration.request.dto';
|
import { SetConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/set-configuration.request.dto';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { SetConfigurationService } from '@modules/configuration/core/application/commands/set-configuration/set-configuration.service';
|
import { SetConfigurationService } from '@modules/configuration/core/application/commands/set-configuration/set-configuration.service';
|
||||||
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
import { CONFIGURATION_REPOSITORY } from '@modules/configuration/configuration.di-tokens';
|
||||||
import { SetConfigurationCommand } from '@modules/configuration/core/application/commands/set-configuration/set-configuration.command';
|
import { SetConfigurationCommand } from '@modules/configuration/core/application/commands/set-configuration/set-configuration.command';
|
||||||
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
import { ConfigurationEntity } from '@modules/configuration/core/domain/configuration.entity';
|
||||||
|
|
||||||
const setConfigurationRequest: SetConfigurationRequestDto = {
|
const setConfigurationRequest: SetConfigurationRequestDto = {
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
value: '3',
|
value: '3',
|
||||||
};
|
};
|
||||||
|
@ -16,8 +19,11 @@ const setConfigurationRequest: SetConfigurationRequestDto = {
|
||||||
const existingConfigurationEntity = new ConfigurationEntity({
|
const existingConfigurationEntity = new ConfigurationEntity({
|
||||||
id: '047a6ecf-23d4-4d3e-877c-3225d560a8da',
|
id: '047a6ecf-23d4-4d3e-877c-3225d560a8da',
|
||||||
props: {
|
props: {
|
||||||
domain: Domain.AD,
|
identifier: {
|
||||||
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
|
},
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
value: '2',
|
value: '2',
|
||||||
},
|
},
|
||||||
createdAt: new Date('2023-10-23T07:00:00Z'),
|
createdAt: new Date('2023-10-23T07:00:00Z'),
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
} from '@mobicoop/ddd-library';
|
} from '@mobicoop/ddd-library';
|
||||||
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import { ConfigurationDomain } from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { DeleteConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/delete-configuration.grpc.controller';
|
import { DeleteConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/delete-configuration.grpc.controller';
|
||||||
import { DeleteConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/delete-configuration.request.dto';
|
import { DeleteConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/delete-configuration.request.dto';
|
||||||
import { CommandBus } from '@nestjs/cqrs';
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
@ -11,7 +11,7 @@ import { RpcException } from '@nestjs/microservices';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
const deleteConfigurationRequest: DeleteConfigurationRequestDto = {
|
const deleteConfigurationRequest: DeleteConfigurationRequestDto = {
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { NotFoundException } from '@mobicoop/ddd-library';
|
import { NotFoundException } from '@mobicoop/ddd-library';
|
||||||
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||||
import { ConfigurationMapper } from '@modules/configuration/configuration.mapper';
|
import { ConfigurationMapper } from '@modules/configuration/configuration.mapper';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import {
|
||||||
|
ConfigurationDomain,
|
||||||
|
ConfigurationType,
|
||||||
|
} from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { GetConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/get-configuration.grpc.controller';
|
import { GetConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/get-configuration.grpc.controller';
|
||||||
import { QueryBus } from '@nestjs/cqrs';
|
import { QueryBus } from '@nestjs/cqrs';
|
||||||
import { RpcException } from '@nestjs/microservices';
|
import { RpcException } from '@nestjs/microservices';
|
||||||
|
@ -21,9 +24,10 @@ const mockQueryBus = {
|
||||||
|
|
||||||
const mockConfigurationMapper = {
|
const mockConfigurationMapper = {
|
||||||
toResponse: jest.fn().mockImplementationOnce(() => ({
|
toResponse: jest.fn().mockImplementationOnce(() => ({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
value: '3',
|
value: '3',
|
||||||
|
type: ConfigurationType.NUMBER,
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,7 +66,7 @@ describe('Get Configuration Grpc Controller', () => {
|
||||||
jest.spyOn(mockQueryBus, 'execute');
|
jest.spyOn(mockQueryBus, 'execute');
|
||||||
jest.spyOn(mockConfigurationMapper, 'toResponse');
|
jest.spyOn(mockConfigurationMapper, 'toResponse');
|
||||||
const response = await getConfigurationGrpcController.get({
|
const response = await getConfigurationGrpcController.get({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
});
|
});
|
||||||
expect(response.value).toBe('3');
|
expect(response.value).toBe('3');
|
||||||
|
@ -76,7 +80,7 @@ describe('Get Configuration Grpc Controller', () => {
|
||||||
expect.assertions(4);
|
expect.assertions(4);
|
||||||
try {
|
try {
|
||||||
await getConfigurationGrpcController.get({
|
await getConfigurationGrpcController.get({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'price',
|
key: 'price',
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
@ -93,7 +97,7 @@ describe('Get Configuration Grpc Controller', () => {
|
||||||
expect.assertions(4);
|
expect.assertions(4);
|
||||||
try {
|
try {
|
||||||
await getConfigurationGrpcController.get({
|
await getConfigurationGrpcController.get({
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'someValue',
|
key: 'someValue',
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { IdResponse } from '@mobicoop/ddd-library';
|
import { IdResponse } from '@mobicoop/ddd-library';
|
||||||
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||||
import { Domain } from '@modules/configuration/core/domain/configuration.types';
|
import { ConfigurationDomain } from '@modules/configuration/core/domain/configuration.types';
|
||||||
import { SetConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/set-configuration.request.dto';
|
import { SetConfigurationRequestDto } from '@modules/configuration/interface/grpc-controllers/dtos/set-configuration.request.dto';
|
||||||
import { SetConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/set-configuration.grpc.controller';
|
import { SetConfigurationGrpcController } from '@modules/configuration/interface/grpc-controllers/set-configuration.grpc.controller';
|
||||||
import { CommandBus } from '@nestjs/cqrs';
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
@ -8,7 +8,7 @@ import { RpcException } from '@nestjs/microservices';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
const setConfigurationRequest: SetConfigurationRequestDto = {
|
const setConfigurationRequest: SetConfigurationRequestDto = {
|
||||||
domain: Domain.AD,
|
domain: ConfigurationDomain.CARPOOL,
|
||||||
key: 'seatsProposed',
|
key: 'seatsProposed',
|
||||||
value: '3',
|
value: '3',
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,12 +16,10 @@ const imports = [
|
||||||
useFactory: async (
|
useFactory: async (
|
||||||
configService: ConfigService,
|
configService: ConfigService,
|
||||||
): Promise<MessageBrokerModuleOptions> => ({
|
): Promise<MessageBrokerModuleOptions> => ({
|
||||||
uri: configService.get<string>('MESSAGE_BROKER_URI') as string,
|
uri: configService.get<string>('broker.uri') as string,
|
||||||
exchange: {
|
exchange: {
|
||||||
name: configService.get<string>('MESSAGE_BROKER_EXCHANGE') as string,
|
name: configService.get<string>('broker.exchange') as string,
|
||||||
durable: configService.get<boolean>(
|
durable: configService.get<boolean>('broker.durability') as boolean,
|
||||||
'MESSAGE_BROKER_EXCHANGE_DURABILITY',
|
|
||||||
) as boolean,
|
|
||||||
},
|
},
|
||||||
name: SERVICE_NAME,
|
name: SERVICE_NAME,
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in New Issue