Skip to content

Commit 145d35f

Browse files
committed
implement endpoint for loading products
1 parent 9c4a7d4 commit 145d35f

Some content is hidden

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

42 files changed

+546
-107
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
## Notable Links 🤓
1414

1515
- [Get started with Temporal and TypeScript](https://github.com/temporalio/sdk-typescript)
16+
- [Workflow Messages - TypeScript SDK](https://docs.temporal.io/develop/typescript/message-passing)
1617

1718
### Public Courses
1819

@@ -209,6 +210,17 @@ docker-compose up -d
209210
docker-compose down --volumes
210211
```
211212

213+
## Payment Providers
214+
215+
- Stripe:
216+
- [Webhooks](https://docs.stripe.com/webhooks?lang=node)
217+
- [Stripe Webhook integration](https://docs.stripe.com/api/webhook_endpoints)
218+
- [Stripe Checkout](https://docs.stripe.com/payments/checkout)
219+
- [Webhooks Dashboard](https://dashboard.stripe.com/test/workbench/webhooks)
220+
- [Automatic fulfillment Orders](https://docs.stripe.com/checkout/fulfillment)
221+
- [Interactive webhook endpoint builder](https://docs.stripe.com/webhooks/quickstart)
222+
- [Trigger webhook events with the Stripe CLI](https://docs.stripe.com/stripe-cli/triggers)
223+
212224
## Supporting 🍻
213225
I believe in Unicorns 🦄
214226
Support [me](http://www.paypal.me/jdnichollsc/2), if you do too.

apps/order/src/app/app.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export class AppService {
162162
// Signal the workflow
163163
await handle.signal(paymentWebHookEventSignal, webhookEvent);
164164

165+
// Return true to indicate the webhook was received
165166
return { received: true };
166167
} catch (err) {
167168
this.logger.error('Webhook Error:', err.message);

apps/product/project.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@
55
"projectType": "application",
66
"tags": [],
77
"targets": {
8+
"build": {
9+
"executor": "@nx/webpack:webpack",
10+
"outputs": ["{options.outputPath}"],
11+
"defaultConfiguration": "production",
12+
"options": {
13+
"target": "node",
14+
"compiler": "tsc",
15+
"outputPath": "dist/apps/product",
16+
"main": "apps/product/src/main.ts",
17+
"tsConfig": "apps/product/tsconfig.app.json",
18+
"assets": [
19+
"apps/product/src/assets"
20+
],
21+
"isolatedConfig": true,
22+
"webpackConfig": "apps/product/webpack.config.js"
23+
},
24+
"configurations": {
25+
"development": {
26+
"mode": "development"
27+
},
28+
"production": {
29+
"mode": "production"
30+
}
31+
}
32+
},
833
"serve": {
934
"executor": "@nx/js:node",
1035
"defaultConfiguration": "development",
Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,19 @@
11
import { Injectable, Logger } from '@nestjs/common';
2-
import { ProductDto, ProductStatus } from '@projectx/models';
2+
import { ProductRepositoryService } from '@projectx/db';
3+
import { ProductDto } from '@projectx/models';
34

45
@Injectable()
56
export class AppService {
67
readonly logger = new Logger(AppService.name);
78

9+
constructor(private readonly productRepository: ProductRepositoryService) {}
10+
811
/**
912
* Retrieves all available products.
1013
* @returns Array of ProductDto containing the product information.
1114
*/
12-
getProducts(): ProductDto[] {
15+
async getProducts(): Promise<ProductDto[]> {
1316
this.logger.log('getProducts() - retrieving all products');
14-
// TODO: Replace with actual database query
15-
return [
16-
new ProductDto({
17-
id: 1,
18-
name: 'Sample Product 1',
19-
description: 'This is a sample product',
20-
estimatedPrice: 99.99,
21-
status: ProductStatus.Active,
22-
createdAt: new Date(),
23-
updatedAt: new Date(),
24-
}),
25-
new ProductDto({
26-
id: 2,
27-
name: 'Sample Product 2',
28-
description: 'This is another sample product',
29-
estimatedPrice: 149.99,
30-
status: ProductStatus.Active,
31-
createdAt: new Date(),
32-
updatedAt: new Date(),
33-
}),
34-
];
17+
return await this.productRepository.findProducts();
3518
}
3619
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Environment } from '@projectx/models';
1+
import type { Environment } from '@projectx/models';
22

33
import { getRequiredServerEnvVar } from './utils.server';
44

@@ -7,5 +7,6 @@ export const sessionSecret = getRequiredServerEnvVar(
77
'SESSION_SECRET',
88
'MY_SECRET_KEY'
99
);
10-
export const authAPIUrl = getRequiredServerEnvVar('AUTH_API_URL');
11-
export const orderAPIUrl = getRequiredServerEnvVar('ORDER_API_URL');
10+
export const authAPIUrl = getRequiredServerEnvVar('AUTH_API_URL', 'http://localhost:8081');
11+
export const orderAPIUrl = getRequiredServerEnvVar('ORDER_API_URL', 'http://localhost:8082');
12+
export const productAPIUrl = getRequiredServerEnvVar('PRODUCT_API_URL', 'http://localhost:8083');

apps/web/app/config/env.server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { authAPIUrl, environment, orderAPIUrl } from './app.config.server';
1+
import { authAPIUrl, environment, orderAPIUrl, productAPIUrl } from './app.config.server';
22

33
export function getEnv() {
4-
console.log(authAPIUrl);
54
return {
65
NODE_ENV: environment,
76
AUTH_API_URL: authAPIUrl,
87
ORDER_API_URL: orderAPIUrl,
8+
PRODUCT_API_URL: productAPIUrl,
99
};
1010
}
1111

apps/web/app/config/security.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const imgSrc = replaceNewLinesWithSpaces(`
3434
https://*.unsplash.com
3535
https://placehold.co
3636
https://gravatar.com
37+
https://*.githubusercontent.com
3738
`);
3839

3940
export const contentSecurityPolicy = replaceNewLinesWithSpaces(`

apps/web/app/constants/api.server.ts

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

apps/web/app/constants/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
export * from './api.server';
21
export * from './links';
32
export * from './navigation';
43
export * from './theme';

apps/web/app/hooks/useProducts.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { ProductDto } from '@projectx/models';
2+
import { useInfiniteQuery } from '@tanstack/react-query';
3+
import axios from 'axios';
4+
5+
const PRODUCTS_QUERY_KEY = 'products';
6+
const MAX_RETRY_ATTEMPTS = 3;
7+
8+
export const useProducts = ({
9+
initialData = [] as ProductDto[],
10+
size = 10,
11+
}) => {
12+
return useInfiniteQuery<ProductDto[]>({
13+
queryKey: [PRODUCTS_QUERY_KEY],
14+
queryFn: async ({ pageParam = 1 }) => {
15+
// TODO: Use limit and offset to load more products from the endpoint
16+
const response = await axios.get<ProductDto[]>(`${window.ENV.PRODUCT_API_URL}/product`);
17+
return response.data;
18+
},
19+
enabled: true,
20+
refetchOnWindowFocus: true,
21+
retry: (failureCount) => failureCount <= MAX_RETRY_ATTEMPTS,
22+
getNextPageParam: (lastPage: ProductDto[], pages: ProductDto[][]) => {
23+
if (lastPage.length === size) {
24+
return pages.length + 1;
25+
}
26+
return undefined;
27+
},
28+
initialPageParam: 1,
29+
...(!!initialData?.length && {
30+
initialData: {
31+
pages: [initialData],
32+
pageParams: [null],
33+
},
34+
}),
35+
});
36+
};

0 commit comments

Comments
 (0)