Skip to content

Commit

Permalink
Merge pull request #7 from blockydevs/switch-to-adapter-architecture
Browse files Browse the repository at this point in the history
switch to adapter architecture pattern
  • Loading branch information
stanislawkurzypBD authored Nov 18, 2024
2 parents 4d9e4b3 + 85a222f commit 857eb0c
Show file tree
Hide file tree
Showing 23 changed files with 137 additions and 200 deletions.
12 changes: 0 additions & 12 deletions src/app.controller.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { CustomerModule } from './customer/customer.module';
import { OrderModule } from './order/order.module';
import { ProductModule } from './product/product.module';
import { CartModule } from './cart/cart.module';
import { StoreManagerModule } from './store-manager/store-manager.module';

@Module({
imports: [
Expand Down Expand Up @@ -48,6 +49,7 @@ import { CartModule } from './cart/cart.module';
OrderModule,
CustomerModule,
HttpModule,
StoreManagerModule,
],
controllers: [],
providers: [],
Expand Down
8 changes: 0 additions & 8 deletions src/app.service.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/cart/cart.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { OrderModule } from '../order/order.module';
import { CustomerModule } from '../customer/customer.module';
import { ProductModule } from '../product/product.module';
import { CartService } from './cart.service';
import { StoreManagerModule } from '../store-manager/store-manager.module';

@Module({
imports: [
Expand All @@ -14,6 +15,7 @@ import { CartService } from './cart.service';
CustomerModule,
ProductModule,
CustomerModule,
StoreManagerModule,
],
controllers: [CartController],
providers: [CartService],
Expand Down
33 changes: 14 additions & 19 deletions src/cart/cart.service.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,49 @@
import {
BadRequestException,
ConflictException,
HttpException,
HttpStatus,
Inject,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { Cart } from './cart.interface';
import { ProductService } from '../product/product.service';
import { OrderService } from '../order/order.service';
import { CustomerService } from '../customer/customer.service';
import { CustomerEntity } from '../customer/entitites/customer.entity';
import { RedisCache } from 'cache-manager-redis-yet';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { StoreManagerPort } from '../store-manager/store-manager.port';

@Injectable()
export class CartService {
constructor(
private readonly httpService: HttpService,
private readonly productService: ProductService,
private readonly orderService: OrderService,
private readonly customerService: CustomerService,
@Inject(StoreManagerPort)
private readonly storeManagerPort: StoreManagerPort,
@Inject(CACHE_MANAGER) private cacheManager: RedisCache,
) {}

public async getCartData(cartId: string): Promise<Cart> {
console.log('STARTED INTEGRATION TEST! (BAD CLASS)');
const cachedData = await this.cacheManager.get<Cart>(cartId);

if (cachedData) {
console.log(`Reading cart data for cartId(CACHED): ${cartId}`);
return cachedData;
}

const { data } = await firstValueFrom(
this.httpService.get(`https://fakestoreapi.com/carts/${cartId}`),
);
const cartData = await this.storeManagerPort.getCartData(cartId);

if (!data) {
if (!cartData) {
throw new NotFoundException(
`Cart with id ${cartId} not found in the external API.`,
);
}

await this.cacheManager.set(cartId, data as Cart);
await this.cacheManager.set(cartId, cartData);

return data as Cart;
return cartData;
}

public async finalizeCart(cartId: string) {
Expand All @@ -61,20 +57,19 @@ export class CartService {
const cartData: Cart = await this.getCartData(cartId);
let cartValue: number = 0;

if (cartData.products.length === 0) {
throw new BadRequestException(
`Cannot complete transaction for empty cart: ${cartId}`,
);
}

for (const product of cartData.products) {
if (product.productId === 1000) {
throw new HttpException('Custom conflict message', HttpStatus.CONFLICT);
}
const p = await this.productService.getProductData(product.productId);
cartValue += p.price;
}

console.log(`Cart ${cartId} has total value of: ${cartValue}`);

if (cartValue === 0) {
throw new Error(`Cannot complete transaction for empty cart: ${cartId}`);
}

const customerEntity: CustomerEntity =
await this.customerService.getOrCreateCustomerById(
cartData.userId.toString(),
Expand Down
103 changes: 0 additions & 103 deletions src/cart/mocks/mock-cart.service.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/config/typeorm-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const config: DataSourceOptions = {
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'mantra_quest_tests',
database: 'postgres',
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: true,
};
Expand Down
6 changes: 3 additions & 3 deletions src/config/typeorm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ const config: DataSourceOptions = {
schema: process.env.DATABASE_SCHEMA || 'public',
host: process.env.DATABASE_HOST || 'localhost',
port: parseInt(process.env.DATABASE_PORT, 10) || 5432,
username: process.env.DATABASE_USERNAME || 'mantra',
password: process.env.DATABASE_PASSWORD || 'mantra',
database: process.env.DATABASE_NAME || 'mantra_quest_handler',
username: process.env.DATABASE_USERNAME || 'admin',
password: process.env.DATABASE_PASSWORD || 'admin',
database: process.env.DATABASE_NAME || 'admin_db',
entities: ['dist/**/*.entity{.ts,.js}'],
migrations: ['dist/migrations/*{.ts,.js}'],
logging: logging,
Expand Down
36 changes: 0 additions & 36 deletions src/product/mocks/mock-product.service.ts

This file was deleted.

3 changes: 2 additions & 1 deletion src/product/product.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Module } from '@nestjs/common';
import { ProductService } from './product.service';
import { HttpModule } from '@nestjs/axios';
import { StoreManagerModule } from '../store-manager/store-manager.module';

@Module({
imports: [HttpModule],
imports: [HttpModule, StoreManagerModule],
providers: [ProductService],
exports: [ProductService],
})
Expand Down
19 changes: 10 additions & 9 deletions src/product/product.service.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Inject, Injectable, NotFoundException } from '@nestjs/common';
import { Product } from './product.interface';
import { firstValueFrom } from 'rxjs';
import { StoreManagerPort } from '../store-manager/store-manager.port';

@Injectable()
export class ProductService {
constructor(private readonly httpService: HttpService) {}
constructor(
@Inject(StoreManagerPort)
private readonly storeManagerPort: StoreManagerPort,
) {}

public async getProductData(productId: number): Promise<Product> {
const { data } = await firstValueFrom(
this.httpService.get(`https://fakestoreapi.com/products/${productId}`),
const productData = await this.storeManagerPort.getProductData(
productId.toString(),
);

if (!data) {
if (!productData) {
console.log(`Product ${productId} not found`);
throw new NotFoundException(
`Product with id ${productId} not found in the external API.`,
);
}

return data;
return productData;
}
}
26 changes: 26 additions & 0 deletions src/store-manager/fake-api/fake-api-store-manager.adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { StoreManagerPort } from '../store-manager.port';
import { firstValueFrom } from 'rxjs';
import { Cart } from '../../cart/cart.interface';
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { Product } from '../../product/product.interface';

@Injectable()
export class FakeApiStoreManagerAdapter implements StoreManagerPort {
constructor(private readonly httpService: HttpService) {}

public async getCartData(cartId: string): Promise<Cart> {
const { data } = await firstValueFrom(
this.httpService.get(`https://fakestoreapi.com/carts/${cartId}`),
);

return data as Cart;
}

public async getProductData(productId: string): Promise<Product> {
const { data } = await firstValueFrom(
this.httpService.get(`https://fakestoreapi.com/products/${productId}`),
);
return data;
}
}
Loading

0 comments on commit 857eb0c

Please sign in to comment.