refactor: changed directory structure a bit

This commit is contained in:
user
2020-12-03 15:54:03 +01:00
parent ffdb060498
commit b14005e98c
35 changed files with 51 additions and 38 deletions

View File

@@ -205,7 +205,7 @@ Ports (for Driven Adapters) are interfaces that define contracts which must be i
- Ports should be created to fit the Domain needs, not simply mimic the tools APIs.
- Mock implementations can be passed to ports while testing. Mocking makes your tests faster and independent from the environment.
Example file: [event-emitter.port.ts](src/application/ports/event-emitter.port.ts)
Example file: [event-emitter.port.ts](src/core/ports/event-emitter.port.ts)
---
@@ -338,7 +338,7 @@ Lets distinguish two types of protection from illegal states: at **compile time*
Types give useful semantic information to a developer. Good code should be easy to use correctly, and hard to use incorrectly. Types system can be a good help for that. It can prevent some nasty errors at a compile time, so IDE will show type errors right away.
The simplest example may be using enums instead of constants, for example: [events.ts](src/application/events/events.ts). This file has enums of events that can occur in a program. Now, event emitter port [event-emitter.port.ts](src/application/ports/event-emitter.port.ts) uses that events type to prevent illegal types pass. If you try to pass anything that is not intended it will show type error.
The simplest example may be using enums instead of constants, for example: [events.ts](src/core/events/events.ts). This file has enums of events that can occur in a program. Now, event emitter port [event-emitter.port.ts](src/core/ports/event-emitter.port.ts) uses that events type to prevent illegal types pass. If you try to pass anything that is not intended it will show type error.
More importantly, this approach can be used to make business logic safer.
@@ -379,7 +379,7 @@ Validating will inform immediately when `Value Object` is created with corrupted
To avoid repeating same validation code between different domain objects consider using [guards](https://medium.com/better-programming/refactoring-guard-clauses-2ceeaa1a9da).
Example file: [guard.ts](src/domain/guard.ts)
Example file: [guard.ts](src/core/guard.ts)
**Keep in mind** that not all validations can be done in a single `Value Object`, it should validate only rules shared by all contexts. There are cases when validation may be different depending on a context, or one field may invole another field, or even a different entity. Handle those cases accordingly.
@@ -599,8 +599,8 @@ By default, Error objects seralize to JSON with output like this:
Consider serializing errors by creating a `toJSON()` method so it can be easily sent to other processes as a plain object.
- Exception abstract base class example: [exception.base.ts](/src/infrastructure/exceptions/exception.base.ts)
- Domain Validation Exception class example: [domain-validation.exception.ts](src/infrastructure/exceptions/domain-validation.exception.ts)
- Exception abstract base class example: [exception.base.ts](src/core/exceptions/exception.base.ts)
- Domain Validation Exception class example: [domain-validation.exception.ts](src/core/exceptions/domain-validation.exception.ts)
Read more: [Better error handling in JavaScript](https://iaincollins.medium.com/error-handling-in-javascript-a6172ccdf9af)

View File

@@ -0,0 +1,8 @@
export * from './exception.base';
export * from './argument-out-of-range.exception';
export * from './business-rule-validation.exception';
export * from './conflict.exception';
export * from './domain-validation.exception';
export * from './exception.types';
export * from './input-validation.exception';
export * from './not-found.exception';

View File

@@ -1,4 +1,4 @@
import { ID } from 'src/domain/value-objects/id.value-object';
import { ID } from 'src/core/value-objects/id.value-object';
/* Most of repos will probably need generic
save/find/delete operations, so it's easier

View File

@@ -1,4 +1,4 @@
import { DomainValidationException } from 'src/infrastructure/exceptions/domain-validation.exception';
import { DomainValidationException } from '@exceptions';
import { ValueObject } from '../base-classes/value-object.base';
export class DateVO extends ValueObject {

View File

@@ -1,4 +1,4 @@
import { ArgumentOutOfRangeException } from 'src/infrastructure/exceptions/argument-out-of-range.exception';
import { ArgumentOutOfRangeException } from '@exceptions';
import { ValueObject } from '../base-classes/value-object.base';
import { Guard } from '../guard';

View File

@@ -1,5 +1,5 @@
import { NestEventEmitter } from 'nest-event';
import { EventEmitterPort } from '../../application/ports/event-emitter.port';
import { EventEmitterPort } from 'src/core/ports/event-emitter.port';
export class EventEmitterAdapter extends NestEventEmitter
implements EventEmitterPort {}

View File

@@ -1,6 +1,6 @@
import { EntityProps } from 'src/domain/base-classes/entity.base';
import { DateVO } from 'src/domain/value-objects/date.value-object';
import { ID } from 'src/domain/value-objects/id.value-object';
import { EntityProps } from 'src/core/base-classes/entity.base';
import { DateVO } from 'src/core/value-objects/date.value-object';
import { ID } from 'src/core/value-objects/id.value-object';
import {
CreateDateColumn,
PrimaryGeneratedColumn,

View File

@@ -1,6 +1,6 @@
import { RepositoryPort } from 'src/application/ports/generic.ports';
import { ID } from 'src/domain/value-objects/id.value-object';
import { NotFoundException } from 'src/infrastructure/exceptions/not-found.exception';
import { RepositoryPort } from 'src/core/ports/generic.ports';
import { ID } from 'src/core/value-objects/id.value-object';
import { NotFoundException } from '@exceptions';
import { Repository } from 'typeorm';
import { OrmEntityBase } from './orm-entity.base';

View File

@@ -9,10 +9,12 @@ import {
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ConflictException } from '../exceptions/conflict.exception';
import { ExceptionBase } from '../exceptions/exception.base';
import { InputValidationException } from '../exceptions/input-validation.exception';
import { NotFoundException } from '../exceptions/not-found.exception';
import {
ExceptionBase,
ConflictException,
NotFoundException,
InputValidationException,
} from '@exceptions';
export class ExceptionInterceptor implements NestInterceptor {
intercept(

View File

@@ -1,4 +1,4 @@
import { EntityProps } from 'src/domain/base-classes/entity.base';
import { EntityProps } from 'src/core/base-classes/entity.base';
import { ApiProperty } from '@nestjs/swagger';
import { IdResponseDTO } from '../dtos/id.response.dto';

View File

@@ -1,4 +1,4 @@
import { RepositoryPort } from 'src/application/ports/generic.ports';
import { RepositoryPort } from 'src/core/ports/generic.ports';
import { UserEntity } from '../domain/entities/user.entity';
/* Repository port belongs to application's core, but since it usually

View File

@@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Injectable } from '@nestjs/common';
import { UserEntity } from 'src/modules/user/domain/entities/user.entity';
import { NotFoundException } from 'src/infrastructure/exceptions/not-found.exception';
import { NotFoundException } from '@exceptions';
import { OrmEntityBase } from 'src/infrastructure/database/base-classes/orm-entity.base';
import { UserOrmEntity } from './user.orm-entity';
import { UserRepositoryPort } from './user.repository.interface';

View File

@@ -1,4 +1,4 @@
import { Entity, EntityProps } from 'src/domain/base-classes/entity.base';
import { Entity, EntityProps } from 'src/core/base-classes/entity.base';
import { Address } from '../value-objects/address.value-object';
import { Email } from '../value-objects/email.value-object';

View File

@@ -1,7 +1,9 @@
import { ValueObject } from 'src/domain/base-classes/value-object.base';
import { Guard } from 'src/domain/guard';
import { ArgumentOutOfRangeException } from 'src/infrastructure/exceptions/argument-out-of-range.exception';
import { DomainValidationException } from 'src/infrastructure/exceptions/domain-validation.exception';
import { ValueObject } from 'src/core/base-classes/value-object.base';
import { Guard } from 'src/core/guard';
import {
ArgumentOutOfRangeException,
DomainValidationException,
} from '@exceptions';
export interface AddressProps {
country: string;

View File

@@ -1,5 +1,5 @@
import { ValueObject } from 'src/domain/base-classes/value-object.base';
import { DomainValidationException } from 'src/infrastructure/exceptions/domain-validation.exception';
import { ValueObject } from 'src/core/base-classes/value-object.base';
import { DomainValidationException } from '@exceptions';
export class Email extends ValueObject {
constructor(value: string) {

View File

@@ -1,5 +1,5 @@
import { On } from 'nest-event';
import { UserEvents } from 'src/application/events/events';
import { UserEvents } from 'src/core/events/events';
import { UserEntity } from '../../domain/entities/user.entity';
export class CreateUserEventHandler {

View File

@@ -1,8 +1,8 @@
import { ID } from 'src/domain/value-objects/id.value-object';
import { EventEmitterPort } from 'src/application/ports/event-emitter.port';
import { UserEvents } from 'src/application/events/events';
import { ID } from 'src/core/value-objects/id.value-object';
import { EventEmitterPort } from 'src/core/ports/event-emitter.port';
import { UserEvents } from 'src/core/events/events';
import { UserRepositoryPort } from '@modules/user/database/user.repository.interface';
import { ConflictException } from 'src/infrastructure/exceptions/conflict.exception';
import { ConflictException } from '@exceptions';
import { CreateUserCommand } from './create-user.command';
import { UserEntity } from '../../domain/entities/user.entity';

View File

@@ -1,5 +1,5 @@
import { EventEmitterPort } from 'src/application/ports/event-emitter.port';
import { UserEvents } from 'src/application/events/events';
import { EventEmitterPort } from 'src/core/ports/event-emitter.port';
import { UserEvents } from 'src/core/events/events';
import { UserRepositoryPort } from '@modules/user/database/user.repository.interface';
export class DeleteUserService {

View File

@@ -1,5 +1,5 @@
import { On } from 'nest-event';
import { UserEvents } from 'src/application/events/events';
import { UserEvents } from 'src/core/events/events';
import { UserEntity } from '../../domain/entities/user.entity';
export class UserDeletedEventHandler {

View File

@@ -14,7 +14,8 @@
"incremental": true,
"paths": {
"@modules/*": ["src/modules/*"],
"@config/*": ["src/infrastructure/configs/*"]
"@config/*": ["src/infrastructure/configs/*"],
"@exceptions": ["./src/core/exceptions"]
}
}
}