Skip to content

Commit 23de85f

Browse files
authored
Major refactor of frontend (#107)
1 parent d3ca195 commit 23de85f

File tree

211 files changed

+13472
-21239
lines changed

Some content is hidden

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

211 files changed

+13472
-21239
lines changed

README.md

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ When a todo is completed, if this is the first completed todo, an email should b
7676
* **Authentication**
7777
* **Authorization** (Even at the repository level)
7878
* **Automatic JWT renewal**
79-
* **gRPC query caching**
80-
* **Automatic client code generation using gRPC**
79+
* **gRPC query caching** (deprecated)
80+
* **Automatic client code generation using OpenAPI**
8181

8282
## Technologies Used - Overview
8383
Here are listed some of the specific technologies used for the implementation of the project:
8484
* **Authentication**: [JSON Web Tokens - JWT](https://jwt.io/)
8585
* **Databases - Persistence**: [MongoDB](https://www.mongodb.com/), [PostgeSQL](https://www.postgresql.org/)
8686
* **Testing**: [JEST](https://jestjs.io/)
87-
* **External Communication Protocols**: [REST](https://en.wikipedia.org/wiki/Representational_state_transfer), [gRPC](https://grpc.io/)
87+
* **External Communication Protocols**: [REST](https://en.wikipedia.org/wiki/Representational_state_transfer), [gRPC](https://grpc.io/) (deprecated)
8888
* **Frameworks**: [ΝestJS](https://nestjs.com/)
8989
* **PubSub technology**: [NATS](https://nats.io/)
9090
* **Message Streaming Technology**: [JetStream](https://docs.nats.io/nats-concepts/jetstream) *by NATS*
@@ -120,14 +120,14 @@ docker compose -p bitloops-todo-app up -d
120120
```
121121
from the terminal inside the project **in order to download and run the necessary containers**.
122122

123-
Then the ReactJS front-end application will be visible at: `http://localhost:3000`.
123+
Then the ReactJS front-end application will be visible at: `http://localhost:4173`.
124124

125125
<p align="center" style="margin-bottom: 0px !important;">
126126
<img width="400" alt="image" src="https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda/assets/1571105/4570473b-4e67-4050-9935-967acfe0b7c6" alt="Frontend application" align="center">
127127
</p>
128128

129129
<p align="center">
130-
Frontend React JS application (new version using MVVM!)
130+
Frontend React JS application (new version using Vite and MVVM!)
131131
</p>
132132

133133
# IV. Design Process and Decisions
@@ -241,7 +241,7 @@ You may find tutorials on how to use **Postman** for REST and gRPC requests belo
241241
* REST ([link](https://hevodata.com/learn/postman-rest-client/))
242242
* gRPC ([link](https://learning.postman.com/docs/sending-requests/grpc/first-grpc-request/))
243243

244-
To just test the app is app and running you can just invoke `http://localhost:8082` URI with Post request as shown in the picture below:
244+
To just test the app is app and running you can just invoke `http://localhost:8080` URI with Post request as shown in the picture below:
245245

246246
<p align="center" style="margin-bottom: 0px !important;">
247247
<img width="900" src="https://storage.googleapis.com/bitloops-github-assets/app-testing-confirmation.png" alt="App Running Confirmation" align="center">
@@ -258,7 +258,7 @@ A faster way to test the app works is to use **[cURL](https://curl.se/)**. In mo
258258

259259
To just test the app is app and running you can just run the following command on terminal:
260260

261-
```curl http://localhost:8082/```
261+
```curl http://localhost:8080/```
262262

263263
The server should respond (in the terminal) with:
264264
```{"statusCode":404,"message":"Cannot GET /auth/register","error":"Not Found"}```
@@ -420,28 +420,76 @@ Below is a summary of all the software architecture and design patterns used in
420420

421421
## Table of Contents
422422

423-
- [Software Architecture](#software-architecture)
424-
- [Layered Architecture](#layered-architecture)
425-
- [Separation of concerns benefits example](#separation-of-concerns-benefits-example)
426-
- [Limitations of the classical layered architecture](#limitations-of-the-classical-layered-architecture)
427-
- [Modern Layered Architectures](#modern-layered-architectures)
428-
- [The Anti-pattern (beware)](#the-anti-pattern-beware)
429-
- [Hexagonal Architecture (or Clean / Onion Architecture)](#hexagonal-architecture-or-clean--onion-architecture)
430-
- [Ports And Adapters](#ports-and-adapters)
431-
- [Driven Adapters vs Driving Adapters](#driven-adapters-vs-driving-adapters)
432-
- [Inversion of Control](#inversion-of-control)
433-
- [Domain Driven Design (DDD)](#domain-driven-design-ddd)
434-
- [Key advantages of using DDD](#key-advantages-of-using-ddd)
435-
- [Strategic and Tactical DDD](#strategic-and-tactical-ddd)
423+
- [ddd-hexagonal-cqrs-es-eda](#ddd-hexagonal-cqrs-es-eda)
424+
- [Table of Contents](#table-of-contents)
425+
- [I. Introduction](#i-introduction)
426+
- [Overview](#overview)
427+
- [Todo application business requirements](#todo-application-business-requirements)
428+
- [II. Technologies and Technical Features](#ii-technologies-and-technical-features)
429+
- [Technical Features](#technical-features)
430+
- [Technologies Used - Overview](#technologies-used---overview)
431+
- [III. Quick start - running the ToDo App](#iii-quick-start---running-the-todo-app)
432+
- [Prerequisites](#prerequisites)
433+
- [Running the app](#running-the-app)
434+
- [IV. Design Process and Decisions](#iv-design-process-and-decisions)
435+
- [Design Process - Event Storming](#design-process---event-storming)
436+
- [Design Decisions](#design-decisions)
437+
- [V. Running in development mode](#v-running-in-development-mode)
438+
- [A. Project Setup](#a-project-setup)
439+
- [Prerequisites](#prerequisites-1)
440+
- [Running the app](#running-the-app-1)
441+
- [B. Application Validation](#b-application-validation)
442+
- [Test the application is running](#test-the-application-is-running)
443+
- [Postman](#postman)
444+
- [cURL (only for initial testing)](#curl-only-for-initial-testing)
445+
- [Running the application tests](#running-the-application-tests)
446+
- [C. Understanding the project structure](#c-understanding-the-project-structure)
447+
- [API Folder](#api-folder)
448+
- [Bounded-Contexts Folder](#bounded-contexts-folder)
449+
- [Config Folder](#config-folder)
450+
- [Lib Folder](#lib-folder)
451+
- [Module Structure](#module-structure)
452+
- [Application Folder](#application-folder)
453+
- [Commands folder](#commands-folder)
454+
- [Queries folder](#queries-folder)
455+
- [Domain folder](#domain-folder)
456+
- [Contracts folder](#contracts-folder)
457+
- [Ports folder](#ports-folder)
458+
- [Tests folder](#tests-folder)
459+
- [proto folder](#proto-folder)
460+
- [VI. Conclusion](#vi-conclusion)
461+
- [❓ Questions](#-questions)
462+
- [📚 Theoretical Review](#-theoretical-review)
463+
- [Table of Contents](#table-of-contents-1)
464+
- [Software Architecture](#software-architecture)
465+
- [Layered Architecture](#layered-architecture)
466+
- [Separation of concerns benefits example](#separation-of-concerns-benefits-example)
467+
- [Limitations of the classical layered architecture](#limitations-of-the-classical-layered-architecture)
468+
- [Modern Layered Architectures](#modern-layered-architectures)
469+
- [The Anti-pattern (beware)](#the-anti-pattern-beware)
470+
- [Hexagonal Architecture (or Clean / Onion Architecture)](#hexagonal-architecture-or-clean--onion-architecture)
471+
- [Ports And Adapters](#ports-and-adapters)
472+
- [Driven Adapters vs Driving Adapters](#driven-adapters-vs-driving-adapters)
473+
- [Inversion of Control](#inversion-of-control)
474+
- [Domain Driven Design (DDD)](#domain-driven-design-ddd)
475+
- [Key advantages of using DDD](#key-advantages-of-using-ddd)
476+
- [Strategic and Tactical DDD](#strategic-and-tactical-ddd)
477+
- [Strategic: Building a Domain Model](#strategic-building-a-domain-model)
478+
- [Tactically: Implementing DDD](#tactically-implementing-ddd)
436479
- [DDD \& Hexagonal Architecture are Complementary](#ddd--hexagonal-architecture-are-complementary)
437-
- [Behavior Driven Development (BDD)](#behavior-driven-development-bdd)
438-
- [Event-Driven Architecture](#event-driven-architecture)
439-
- [Command and Query Responsibility Segregation (CQRS)](#command-and-query-responsibility-segregation-cqrs)
440-
- [Event Sourcing (ES)](#event-sourcing-es)
441-
- [Eventual Consistency](#eventual-consistency)
442-
- [Event Storming](#event-storming)
443-
- [🚀 Bringing this all together!](#-bringing-this-all-together)
444-
- [🙌 Contributing](#-contributing)
480+
- [Behavior Driven Development (BDD)](#behavior-driven-development-bdd)
481+
- [Event-Driven Architecture](#event-driven-architecture)
482+
- [Command and Query Responsibility Segregation (CQRS)](#command-and-query-responsibility-segregation-cqrs)
483+
- [Event Sourcing (ES)](#event-sourcing-es)
484+
- [Eventual Consistency](#eventual-consistency)
485+
- [Event Storming](#event-storming)
486+
- [Big Picture Event Storming](#big-picture-event-storming)
487+
- [Process Level Event Storming](#process-level-event-storming)
488+
- [Design Level Event Storming](#design-level-event-storming)
489+
- [Event Storming Syntax](#event-storming-syntax)
490+
- [More on Event Storming](#more-on-event-storming)
491+
- [🚀 Bringing this all together!](#-bringing-this-all-together)
492+
- [🙌 Contributing](#-contributing)
445493
- [👨‍💻 Additional learning resources](#-additional-learning-resources)
446494
- [Articles](#articles)
447495
- [Blogs](#blogs)

backend/Dockerfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ ENV NATS_HOST bl-nats
2424
ENV GRAFANA_ADMIN_USER admin
2525
ENV GRAFANA_ADMIN_PASSWORD admin
2626
ENV NODE_ENV production
27-
ENV AUTH_URL "http://todo-backend:8082/auth/login"
28-
ENV PROXY_URL "http://todo-backend:8080"
29-
ENV REGISTRATION_URL "http://todo-backend:8082/auth/register"
27+
ENV AUTH_URL "http://todo-backend:8080/auth/login"
28+
ENV TODO_URL "http://todo-backend:8080"
29+
ENV REGISTRATION_URL "http://todo-backend:8080/auth/register"
3030
# Expose the port on which the app will be running (3000 is the default that `serve` uses)
31-
EXPOSE 8081 8082
31+
EXPOSE 8080
3232
# Start the app
3333
CMD [ "yarn", "start:prod" ]

backend/frontend-development.docker-compose.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ services:
55
build:
66
context: .
77
ports:
8-
- '8081:8081'
9-
- '8082:8082'
8+
- '8080:8080'
109
networks:
1110
- bitloops
1211

backend/package.json

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "todo",
3-
"version": "0.1.3",
3+
"version": "0.2.0",
44
"description": "Todo Backend using Domain Driven Design (DDD), Hexagonal Architecture, CQRS, Event Sourcing (ES), Event Driven Architecture (EDA), Behaviour Driven Development (BDD) using TypeScript and NestJS. Like what you see? Don't forget to star! ⭐",
55
"author": "Bitloops S.A.",
66
"private": false,
@@ -27,31 +27,41 @@
2727
},
2828
"dependencies": {
2929
"@bitloops/bl-boilerplate-core": "^0.3.6",
30-
"@bitloops/bl-boilerplate-infra-mongo": "^0.1.2",
31-
"@bitloops/bl-boilerplate-infra-nest-auth-passport": "^0.1.4",
32-
"@bitloops/bl-boilerplate-infra-nest-jetstream": "^0.0.8",
33-
"@bitloops/bl-boilerplate-infra-postgres": "^0.1.1",
34-
"@bitloops/bl-boilerplate-infra-telemetry": "^0.1.3",
30+
"@fastify/autoload": "^6.3.1",
31+
"@fastify/cors": "^11.0.1",
32+
"@fastify/helmet": "^13.0.1",
33+
"@fastify/swagger": "^9.5.1",
34+
"@fastify/swagger-ui": "^5.2.3",
3535
"@grpc/grpc-js": "^1.8.13",
36-
"@nestjs/common": "^9.4.0",
37-
"@nestjs/config": "^2.3.1",
38-
"@nestjs/core": "^9.0.0",
39-
"@nestjs/microservices": "^9.3.10",
40-
"@nestjs/platform-fastify": "^9.4.0",
36+
"@nestjs/cli": "^11.0.7",
37+
"@nestjs/common": "^11.1.3",
38+
"@nestjs/config": "^4.0.2",
39+
"@nestjs/core": "^11.1.3",
40+
"@nestjs/event-emitter": "^3.0.1",
41+
"@nestjs/jwt": "^11.0.0",
42+
"@nestjs/microservices": "^11.1.3",
43+
"@nestjs/passport": "^11.0.5",
44+
"@nestjs/platform-fastify": "^11.1.3",
45+
"@nestjs/schematics": "^11.0.5",
46+
"@nestjs/swagger": "^11.2.0",
47+
"@nestjs/testing": "^11.1.3",
48+
"async-mutex": "^0.5.0",
49+
"bcrypt": "^6.0.0",
4150
"class-transformer": "^0.5.1",
4251
"class-validator": "^0.14.0",
52+
"fastify": "^5.4.0",
4353
"google-protobuf": "^3.21.2",
4454
"jsonwebtoken": "^9.0.0",
4555
"mongodb": "^6.3.0",
4656
"nats": "^2.13.1",
57+
"passport-jwt": "^4.0.1",
58+
"passport-local": "^1.0.0",
59+
"pg": "^8.16.2",
4760
"reflect-metadata": "^0.1.13",
4861
"rxjs": "^7.8.0",
4962
"uuid": "^9.0.0"
5063
},
5164
"devDependencies": {
52-
"@nestjs/cli": "^9.0.0",
53-
"@nestjs/schematics": "^9.0.0",
54-
"@nestjs/testing": "^9.0.0",
5565
"@types/google-protobuf": "^3.15.6",
5666
"@types/jest": "29.5.12",
5767
"@types/jsonwebtoken": "^9.0.1",
@@ -62,8 +72,8 @@
6272
"eslint": "^8.0.1",
6373
"eslint-config-prettier": "^8.3.0",
6474
"eslint-plugin-prettier": "^4.0.0",
65-
"grpc-tools": "^1.12.4",
6675
"grpc_tools_node_protoc_ts": "^5.3.3",
76+
"grpc-tools": "^1.12.4",
6777
"jest": "29.7.0",
6878
"passport": "^0.6.0",
6979
"prettier": "^2.3.2",
@@ -74,7 +84,7 @@
7484
"ts-loader": "^9.2.3",
7585
"ts-node": "^10.0.0",
7686
"tsconfig-paths": "4.2.0",
77-
"typescript": "4.9.5"
87+
"typescript": "^5.8.3"
7888
},
7989
"jest": {
8090
"moduleFileExtensions": [

backend/src/api/api.module.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@ import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
22
import { ConfigModule, ConfigService } from '@nestjs/config';
33
import { AuthController } from './authentication.controller';
44
import { TodoController } from './todo.rest.controller';
5-
import { TodoGrpcController } from './todo.grpc.controller';
5+
import { TodoSSEController } from './todo.sse.controller';
66
import {
77
JetstreamModule,
88
NatsStreamingIntegrationEventBus,
99
NatsStreamingMessageBus,
10-
} from '@bitloops/bl-boilerplate-infra-nest-jetstream';
10+
} from '@lib/infra/nest-jetstream';
1111
import configuration from '@src/config/configuration';
1212
import authConfiguration, {
1313
AuthEnvironmentVariables,
1414
} from '@src/config/auth.configuration';
15-
import { AuthModule } from '@bitloops/bl-boilerplate-infra-nest-auth-passport';
15+
import { AuthModule } from '@lib/infra/nest-auth-passport';
1616
import {
1717
// CorrelationIdMiddleware,
1818
TracingModule,
19-
} from '@bitloops/bl-boilerplate-infra-telemetry';
19+
} from '@lib/infra/telemetry';
20+
import { SSEModule } from './sse.module';
2021

2122
@Module({
2223
imports: [
@@ -60,12 +61,12 @@ import {
6061
}`,
6162
],
6263
}),
63-
64+
SSEModule,
6465
TracingModule.register({
6566
messageBus: NatsStreamingMessageBus,
6667
}),
6768
],
68-
controllers: [AuthController, TodoController, TodoGrpcController],
69+
controllers: [AuthController, TodoController, TodoSSEController],
6970
})
7071
// implements NestModule
7172
export class ApiModule {

backend/src/api/authentication.controller.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import {
22
Body,
33
Controller,
4-
Get,
54
Post,
65
Request,
76
UseGuards,
87
Inject,
98
HttpStatus,
109
HttpException,
10+
Patch,
1111
} from '@nestjs/common';
1212
import { ChangeEmailCommand } from '@src/lib/bounded-contexts/iam/authentication/commands/change-email.command';
13-
import { UpdateEmailDTO } from './dto/update-email.dto';
14-
import { RegisterDTO } from './dto/register.dto';
15-
import { BUSES_TOKENS } from '@bitloops/bl-boilerplate-infra-nest-jetstream';
13+
import { UpdateEmailRequestDto } from './dto/update-email.dto';
14+
import { RegisterRequestDto } from './dto/register.dto';
15+
import { BUSES_TOKENS } from '@lib/infra/nest-jetstream';
1616
import {
1717
Application,
1818
Infra,
@@ -22,8 +22,8 @@ import {
2222
AuthService,
2323
JwtAuthGuard,
2424
LocalAuthGuard,
25-
} from '@bitloops/bl-boilerplate-infra-nest-auth-passport';
26-
import { Traceable } from '@bitloops/bl-boilerplate-infra-telemetry';
25+
} from '@lib/infra/nest-auth-passport';
26+
import { Traceable } from '@lib/infra/telemetry';
2727

2828
@Controller('auth')
2929
export class AuthController {
@@ -50,8 +50,8 @@ export class AuthController {
5050
}
5151

5252
@UseGuards(JwtAuthGuard)
53-
@Post('updateEmail')
54-
async updateEmail(@Request() req, @Body() dto: UpdateEmailDTO) {
53+
@Patch('updateEmail')
54+
async updateEmail(@Request() req, @Body() dto: UpdateEmailRequestDto) {
5555
console.log('req', req.user);
5656
const command = new ChangeEmailCommand({
5757
email: dto.email,
@@ -63,7 +63,7 @@ export class AuthController {
6363
}
6464

6565
@Post('register')
66-
async register(@Body() body: RegisterDTO) {
66+
async register(@Body() body: RegisterRequestDto) {
6767
const user = { email: body.email, password: body.password };
6868
const result = await this.authService.register(user);
6969
// const command = new RegisterCommand({

backend/src/api/dto/add-todo.dto.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { IsString, IsNotEmpty } from 'class-validator';
2+
import { ApiProperty } from '@nestjs/swagger';
23

3-
export class AddTodoDto {
4+
export class AddTodoRequestDto {
5+
@ApiProperty({ description: 'The title of the todo' })
46
@IsNotEmpty()
57
@IsString()
68
title: string;

backend/src/api/dto/complete-todo.dto.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)