Skip to content

Commit 34e4562

Browse files
committed
feat(example): add encrypted user aggregate example
1 parent 78337e9 commit 34e4562

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+789
-126
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
dist
2+
example/dist
13
example/src/nestjs-eventstore
24

35
# Common

.npmignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# source
2+
example
3+
node_modules
24
src
35
index.ts
46
package-lock.json
@@ -8,4 +10,5 @@ tsconfig.build.json
810
.eslintignore
911
.eslintrc.js
1012
.prettierrc
13+
.prettierignore
1114
.release-it.json

docker-compose.override.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: '3.6'
2+
3+
services:
4+
app:
5+
volumes:
6+
- type: bind
7+
source: ./example
8+
target: /app
9+
- type: bind
10+
source: ./src
11+
target: /app/src/nestjs-eventstore

docker-compose.recreate.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
version: '3.6'
2+
3+
services:
4+
app:
5+
command: ['npm', 'run', 'console:dev', 'eventstore:readmodel:restore']

docker-compose.yaml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,10 @@ services:
4848
ports:
4949
- 3000:3000
5050
environment:
51-
- MONGO_URI=mongodb://mongo:27017/projections
51+
- MONGO_URI=mongodb://mongo:27017/example
5252
- EVENTSTORE_URI=esdb://eventstore.db:2113?tls=false
53+
- KEYSTORE_URI=mongodb://mongo:27017/keystore
5354
- PORT=3000
54-
volumes:
55-
- type: bind
56-
source: ./example/
57-
target: /app
58-
- type: bind
59-
source: ./src/
60-
target: /app/src/nestjs-eventstore/
6155

6256
volumes:
6357
eventstore-volume-data:

example/nest-cli.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
{
22
"collection": "@nestjs/schematics",
33
"sourceRoot": "src",
4-
"compilerOptions": {
5-
"plugins": ["@nestjs/swagger"]
6-
}
4+
"compilerOptions": {}
75
}

example/package-lock.json

Lines changed: 0 additions & 112 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/src/app.module.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
EventStoreModule,
1010
EVENTSTORE_KEYSTORE_CONNECTION,
1111
} from './nestjs-eventstore';
12+
import { UserModule } from './user';
1213

1314
@Module({
1415
imports: [
@@ -27,11 +28,19 @@ import {
2728
category: 'example',
2829
connection: process.env.EVENTSTORE_URI,
2930
}),
30-
MongooseModule.forRoot(process.env.MONGO_URI),
31+
MongooseModule.forRoot(process.env.MONGO_URI, {
32+
useCreateIndex: true,
33+
useFindAndModify: false,
34+
useNewUrlParser: true,
35+
}),
3136
MongooseModule.forRoot(process.env.KEYSTORE_URI, {
3237
connectionName: EVENTSTORE_KEYSTORE_CONNECTION,
38+
useCreateIndex: true,
39+
useFindAndModify: false,
40+
useNewUrlParser: true,
3341
}),
3442
AccountModule,
43+
UserModule,
3544
],
3645
})
3746
export class AppModule {}

example/src/console.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { AppModule } from './app.module';
55
const bootstrap = new BootstrapConsole({
66
module: AppModule,
77
useDecorators: true,
8+
contextOptions: {
9+
logger: ['debug', 'error', 'log', 'verbose', 'warn'],
10+
},
811
});
912
bootstrap.init().then(async (app) => {
1013
try {

example/src/main.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { Logger, ValidationPipe } from '@nestjs/common';
2-
import { NestFactory } from '@nestjs/core';
1+
import {
2+
ClassSerializerInterceptor,
3+
Logger,
4+
ValidationPipe,
5+
} from '@nestjs/common';
6+
import { NestFactory, Reflector } from '@nestjs/core';
37
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
48
import { AppModule } from './app.module';
59

@@ -16,6 +20,7 @@ async function bootstrap() {
1620

1721
const port = process.env.PORT || 3000;
1822
app.useGlobalPipes(new ValidationPipe());
23+
app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));
1924
await app.listen(port, () => {
2025
Logger.log(`Listening at http://localhost:${port}/api`);
2126
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
2+
import {
3+
AggregateRepository,
4+
IdAlreadyRegisteredError,
5+
InjectAggregateRepository,
6+
} from '../../../nestjs-eventstore';
7+
import { Password, User, UserId, Username } from '../../domain';
8+
import { CreateUserCommand } from './create-user.query';
9+
10+
@CommandHandler(CreateUserCommand)
11+
export class CreateUserHandler implements ICommandHandler<CreateUserCommand> {
12+
constructor(
13+
@InjectAggregateRepository(User)
14+
private readonly users: AggregateRepository<User, UserId>,
15+
) {}
16+
17+
async execute(command: CreateUserCommand) {
18+
const userId = UserId.with(command.id);
19+
const username = Username.with(command.username);
20+
const password = Password.with(command.password);
21+
22+
if ((await this.users.find(userId)) instanceof User) {
23+
throw IdAlreadyRegisteredError.withId(userId);
24+
}
25+
26+
const user = User.add(userId, username, password);
27+
28+
this.users.save(user);
29+
}
30+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ICommand } from '@nestjs/cqrs';
2+
3+
export class CreateUserCommand implements ICommand {
4+
constructor(
5+
public readonly id: string,
6+
public readonly username: string,
7+
public readonly password: string,
8+
) {}
9+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
2+
import {
3+
AggregateRepository,
4+
IdNotFoundError,
5+
InjectAggregateRepository,
6+
} from '../../../nestjs-eventstore';
7+
import { User, UserId } from '../../domain';
8+
import { DeleteUserCommand } from './delete-user.query';
9+
10+
@CommandHandler(DeleteUserCommand)
11+
export class DeleteUserHandler implements ICommandHandler<DeleteUserCommand> {
12+
constructor(
13+
@InjectAggregateRepository(User)
14+
private readonly users: AggregateRepository<User, UserId>,
15+
) {}
16+
17+
async execute(command: DeleteUserCommand): Promise<void> {
18+
const userId = UserId.with(command.id);
19+
20+
const user = await this.users.find(userId);
21+
22+
if (!user || user.deleted) {
23+
throw IdNotFoundError.withId(userId);
24+
}
25+
26+
user.delete();
27+
28+
this.users.delete(user);
29+
}
30+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { ICommand } from '@nestjs/cqrs';
2+
3+
export class DeleteUserCommand implements ICommand {
4+
constructor(public readonly id: string) {}
5+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { CreateUserHandler } from './create-user.handler';
2+
import { DeleteUserHandler } from './delete-user.handler';
3+
import { UpdateUserHandler } from './update-user.handler';
4+
5+
export const commandHandlers = [
6+
CreateUserHandler,
7+
UpdateUserHandler,
8+
DeleteUserHandler,
9+
];
10+
11+
export * from './create-user.query';
12+
export * from './update-user.query';
13+
export * from './delete-user.query';

0 commit comments

Comments
 (0)