Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…ration-workspace into feature/shared-infrastructure
  • Loading branch information
zhumeisongsong committed Nov 18, 2024
2 parents bed8f77 + 1f18384 commit 9b3bad9
Show file tree
Hide file tree
Showing 63 changed files with 265 additions and 66 deletions.
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
"cSpell.words": [
"nestjs",
"supergraph",
"usecase"
]
}
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ You can use `npx nx list` to get a list of installed plugins. Then, run `npx nx

## Architecture

| Layer | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| usecase | Define business use cases and encapsulate business logic. |
| entity(domain) | Define core business entities and business rules.<br/> Maintain entity independence from database and framework. |
| repository(domain) | Interfaces (or abstract classes), which define methods for manipulating data without concern for specific database implementations. <br/>By defining this interface, we can decouple database access: the specific details of data access will be done by implementation classes, such as specific implementations using tools like Mongoose, TypeORM, Prisma, and so on. |
| Layer | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| dto(presentation) | Define DTOs for GraphQL schema. |
| resolver(presentation) | Define GraphQL schema and resolver. |
| use-case(application) | Define business use cases and encapsulate business logic. |
| entity(domain) | Define core business entities and business rules.<br/> Maintain entity independence from database and framework. |
| repository(domain) | Interfaces (or abstract classes), which define methods for manipulating data without concern for specific database implementations. <br/>By defining this interface, we can decouple database access: the specific details of data access will be done by implementation classes, such as specific implementations using tools like Mongoose, TypeORM, Prisma, and so on. |

## Useful links

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default {
displayName: 'users-application-e2e',
displayName: 'users-e2e',
preset: '../../jest.preset.js',
globalSetup: '<rootDir>/src/support/global-setup.ts',
globalTeardown: '<rootDir>/src/support/global-teardown.ts',
Expand All @@ -14,5 +14,5 @@ export default {
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/users-application-e2e',
coverageDirectory: '../../coverage/users-e2e',
};
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"name": "users-application-e2e",
"name": "users-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"implicitDependencies": ["users-application"],
"implicitDependencies": ["users"],
"targets": {
"e2e": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"],
"options": {
"jestConfig": "apps/users-application-e2e/jest.config.ts",
"jestConfig": "apps/users-e2e/jest.config.ts",
"passWithNoTests": true
},
"dependsOn": ["users-application:build"]
"dependsOn": ["users:build"]
}
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export default {
displayName: 'users-application',
displayName: 'users',
preset: '../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/apps/users-application',
coverageDirectory: '../../coverage/apps/users',
};
10 changes: 5 additions & 5 deletions apps/users-application/project.json → apps/users/project.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "users-application",
"name": "users",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/users-application/src",
"sourceRoot": "apps/users/src",
"projectType": "application",
"tags": [],
"targets": {
Expand All @@ -10,15 +10,15 @@
"defaultConfiguration": "development",
"dependsOn": ["build"],
"options": {
"buildTarget": "users-application:build",
"buildTarget": "users:build",
"runBuildTargetDependencies": false
},
"configurations": {
"development": {
"buildTarget": "users-application:build:development"
"buildTarget": "users:build:development"
},
"production": {
"buildTarget": "users-application:build:production"
"buildTarget": "users:build:production"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ describe('AppController', () => {
describe('getData', () => {
it('should return "Hello User Service"', () => {
const appController = app.get<AppController>(AppController);
expect(appController.getData()).toEqual({ message: 'Hello User Service' });
expect(appController.getData()).toEqual({
message: 'Hello User Service',
});
});
});
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service';
import { UsersResolver } from '@users/presentation-resolver';
import { UsersService } from '@users/application';
import { ApolloServerPluginInlineTrace } from '@apollo/server/plugin/inlineTrace';
import { DatabaseModule } from '@shared/infrastructure-mongoose';

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { join } = require('path');

module.exports = {
output: {
path: join(__dirname, '../../dist/apps/users-application'),
path: join(__dirname, '../../dist/apps/users'),
},
plugins: [
new NxAppWebpackPlugin({
Expand Down
7 changes: 0 additions & 7 deletions libs/user/usecase/README.md

This file was deleted.

9 changes: 0 additions & 9 deletions libs/user/usecase/project.json

This file was deleted.

1 change: 0 additions & 1 deletion libs/user/usecase/src/index.ts

This file was deleted.

7 changes: 7 additions & 0 deletions libs/users/application/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# users-application

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test users-application` to execute the unit tests via [Jest](https://jestjs.io).
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export default {
displayName: 'user-usecase',
displayName: 'users-application',
preset: '../../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../../coverage/libs/user/usecase',
coverageDirectory: '../../../coverage/libs/users/application',
};
9 changes: 9 additions & 0 deletions libs/users/application/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "users-application",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/users/application/src",
"projectType": "library",
"tags": [],
"// targets": "to see all targets run: nx show project users-application --web",
"targets": {}
}
4 changes: 4 additions & 0 deletions libs/users/application/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './lib/use-case/get-user.use-case';

// service
export * from './lib/users.service';
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { GetUserUsecase } from './get-user.usecase';
import { GetUserUseCase } from './get-user.use-case';
import { UserRepository } from '@user/domain';

describe('GetUserUsecase', () => {
let getUserUsecase: GetUserUsecase;
describe('GetUserUseCase', () => {
let getUserUseCase: GetUserUseCase;
let userRepository: jest.Mocked<UserRepository>;

beforeEach(() => {
userRepository = {
findById: jest.fn(),
} as unknown as jest.Mocked<UserRepository>;

getUserUsecase = new GetUserUsecase(userRepository);
getUserUseCase = new GetUserUseCase(userRepository);
});

describe('execute', () => {
it('should return a user when found', async () => {
const user = { id: '1', name: 'John Doe' };
userRepository.findById.mockResolvedValue(user);

const result = await getUserUsecase.execute('1');
const result = await getUserUseCase.execute('1');

expect(result).toEqual(user);
expect(userRepository.findById).toHaveBeenCalledWith('1');
Expand All @@ -27,7 +27,7 @@ describe('GetUserUsecase', () => {
it('should return null when user is not found', async () => {
userRepository.findById.mockResolvedValue(null);

const result = await getUserUsecase.execute('1');
const result = await getUserUseCase.execute('1');

expect(result).toBeNull();
expect(userRepository.findById).toHaveBeenCalledWith('1');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { User, UserRepository } from '@user/domain';

export class GetUserUsecase {
export class GetUserUseCase {
constructor(private readonly userRepository: UserRepository) {}

async execute(id: string): Promise<User | null> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ describe('UsersService', () => {
});

it('should return a user by id', () => {
const user: User = service.findById('1');
const user: User | undefined = service.findById('1');
expect(user).toEqual({ id: '1', name: 'John Doe' });
});

it('should return undefined if user is not found', () => {
const user: User = service.findById('3');
const user: User | undefined = service.findById('3');
expect(user).toBeUndefined();
});
});
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions libs/users/presentation/dto/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# users-presentation-dto

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test users-presentation-dto` to execute the unit tests via [Jest](https://jestjs.io).
3 changes: 3 additions & 0 deletions libs/users/presentation/dto/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const baseConfig = require('../../../../eslint.config.js');

module.exports = [...baseConfig];
10 changes: 10 additions & 0 deletions libs/users/presentation/dto/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
displayName: 'users-presentation-dto',
preset: '../../../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../../../coverage/libs/users/presentation/dto',
};
9 changes: 9 additions & 0 deletions libs/users/presentation/dto/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "users-presentation-dto",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/users/presentation/dto/src",
"projectType": "library",
"tags": [],
"// targets": "to see all targets run: nx show project users-presentation-dto --web",
"targets": {}
}
1 change: 1 addition & 0 deletions libs/users/presentation/dto/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/user.dto';
13 changes: 13 additions & 0 deletions libs/users/presentation/dto/src/lib/user.dto.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { UserDto } from './user.dto';

describe('UserDto', () => {
it('should create a new UserDto instance', () => {
const id = '123';
const name = 'Test User';
const userDto = new UserDto(id, name);

expect(userDto).toBeDefined();
expect(userDto.id).toBe(id);
expect(userDto.name).toBe(name);
});
});
16 changes: 16 additions & 0 deletions libs/users/presentation/dto/src/lib/user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class UserDto {
@Field(() => ID)
id: string;

@Field()
name: string;

constructor(id: string, name: string) {
this.id = id;
this.name = name;
}
}
22 changes: 22 additions & 0 deletions libs/users/presentation/dto/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"extends": "../../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noPropertyAccessFromIndexSignature": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
11 changes: 11 additions & 0 deletions libs/users/presentation/dto/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}
14 changes: 14 additions & 0 deletions libs/users/presentation/dto/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
7 changes: 7 additions & 0 deletions libs/users/presentation/resolver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# users-presentation-resolver

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test users-presentation-resolver` to execute the unit tests via [Jest](https://jestjs.io).
3 changes: 3 additions & 0 deletions libs/users/presentation/resolver/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const baseConfig = require('../../../../eslint.config.js');

module.exports = [...baseConfig];
10 changes: 10 additions & 0 deletions libs/users/presentation/resolver/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
displayName: 'users-presentation-resolver',
preset: '../../../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../../../coverage/libs/users/presentation/resolver',
};
Loading

0 comments on commit 9b3bad9

Please sign in to comment.