├── .github
└── workflows
│ ├── deploy-auth.yml
│ ├── deploy-client.yml
│ ├── deploy-expiration.yml
│ ├── deploy-manifests.yml
│ ├── deploy-orders.yml
│ ├── deploy-payments.yml
│ ├── deploy-tickets.yml
│ ├── tests-auth.yml
│ ├── tests-orders.yml
│ ├── tests-payments.yml
│ └── tests-tickets.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── 02_A_Mini_Microservices_App.md
├── 02_A_Mini_Microservices_App
└── app
│ ├── client
│ ├── .gitignore
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── manifest.json
│ │ └── robots.txt
│ └── src
│ │ ├── App.js
│ │ ├── CommentCreate.js
│ │ ├── CommentList.js
│ │ ├── PostCreate.js
│ │ ├── PostList.js
│ │ └── index.js
│ ├── comments
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
│ ├── event-bus
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
│ ├── moderation
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
│ ├── posts
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
│ └── query
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
├── 04_Orchestrating_Collections_of_Services_with_Kubernetes.md
├── 04_Orchestrating_Collections_of_Services_with_Kubernetes
├── app
│ ├── client
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ ├── index.html
│ │ │ ├── manifest.json
│ │ │ └── robots.txt
│ │ └── src
│ │ │ ├── App.js
│ │ │ ├── CommentCreate.js
│ │ │ ├── CommentList.js
│ │ │ ├── PostCreate.js
│ │ │ ├── PostList.js
│ │ │ └── index.js
│ ├── comments
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
│ ├── event-bus
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
│ ├── moderation
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
│ ├── posts
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
│ └── query
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
├── k8s
│ ├── client-depl.yaml
│ ├── client-srv-ClusterIP.yaml
│ ├── comments-depl.yaml
│ ├── comments-srv-ClusterIP.yaml
│ ├── event-bus-depl.yaml
│ ├── event-bus-srv-ClusterIP.yaml
│ ├── ingress-srv.yaml
│ ├── moderation-depl.yaml
│ ├── moderation-srv-ClusterIP.yaml
│ ├── posts-depl.yaml
│ ├── posts-srv-ClusterIP.yaml
│ ├── query-depl.yaml
│ └── query-srv-ClusterIP.yaml
└── skaffold
│ └── skaffold.yaml
├── 05_Architecture_of_Multi_Service_Apps.md
├── 05_Architecture_of_Multi_Service_Apps
├── app
│ └── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ └── index.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── 07_Response_Normalization_Strategies.md
├── 07_Response_Normalization_Strategies
├── app
│ └── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── errors
│ │ │ ├── custom-error.ts
│ │ │ ├── database-connectionerror.ts
│ │ │ ├── not-found-error.ts
│ │ │ └── request-validation-error.ts
│ │ ├── index.ts
│ │ ├── middlewares
│ │ │ └── error-handler.ts
│ │ └── routes
│ │ │ ├── current-user.ts
│ │ │ ├── signin.ts
│ │ │ ├── signout.ts
│ │ │ └── signup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── 08_Database Management_and_Modeling
├── app
│ └── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── errors
│ │ │ ├── bad-request-error.ts
│ │ │ ├── custom-error.ts
│ │ │ ├── database-connectionerror.ts
│ │ │ ├── not-found-error.ts
│ │ │ └── request-validation-error.ts
│ │ ├── index.ts
│ │ ├── middlewares
│ │ │ └── error-handler.ts
│ │ ├── models
│ │ │ └── User.ts
│ │ ├── routes
│ │ │ ├── current-user.ts
│ │ │ ├── signin.ts
│ │ │ ├── signout.ts
│ │ │ └── signup.ts
│ │ └── services
│ │ │ └── password.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── 08_Database_Management_and_Modeling.md
├── 09_Authentication_Strategies_and_Options.md
├── 09_Authentication_Strategies_and_Options
├── app
│ └── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── errors
│ │ │ ├── bad-request-error.ts
│ │ │ ├── custom-error.ts
│ │ │ ├── database-connectionerror.ts
│ │ │ ├── not-authorized-error.ts
│ │ │ ├── not-found-error.ts
│ │ │ └── request-validation-error.ts
│ │ ├── index.ts
│ │ ├── middlewares
│ │ │ ├── current-user.ts
│ │ │ ├── error-handler.ts
│ │ │ ├── require-auth.ts
│ │ │ └── validate-request.ts
│ │ ├── models
│ │ │ └── User.ts
│ │ ├── routes
│ │ │ ├── current-user.ts
│ │ │ ├── signin.ts
│ │ │ ├── signout.ts
│ │ │ └── signup.ts
│ │ └── services
│ │ │ └── password.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── 10_Testing_Isolated_Microservices.md
├── 10_Testing_Isolated_Microservices
├── app
│ └── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── app.ts
│ │ ├── errors
│ │ │ ├── bad-request-error.ts
│ │ │ ├── custom-error.ts
│ │ │ ├── database-connectionerror.ts
│ │ │ ├── not-authorized-error.ts
│ │ │ ├── not-found-error.ts
│ │ │ └── request-validation-error.ts
│ │ ├── index.ts
│ │ ├── middlewares
│ │ │ ├── current-user.ts
│ │ │ ├── error-handler.ts
│ │ │ ├── require-auth.ts
│ │ │ └── validate-request.ts
│ │ ├── models
│ │ │ └── User.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── current-user.test.ts
│ │ │ │ ├── signin.test.ts
│ │ │ │ ├── signout.test.ts
│ │ │ │ └── signup.test.ts
│ │ │ ├── current-user.ts
│ │ │ ├── signin.ts
│ │ │ ├── signout.ts
│ │ │ └── signup.ts
│ │ ├── services
│ │ │ └── password.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── 11_Integrating_a_Server_Side_Rendered_React_App.md
├── 11_Integrating_a_Server_Side_Rendered_React_App
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connectionerror.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── index.ts
│ │ │ ├── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ └── build-client.js
│ │ ├── components
│ │ └── Header.js
│ │ ├── hooks
│ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ ├── _app.js
│ │ ├── auth
│ │ ├── signin.js
│ │ ├── signout.js
│ │ └── signup.js
│ │ └── index.js
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── 12_Code_Sharing_and_Reuse_Between_Services.md
├── 12_Code_Sharing_and_Reuse_Between_Services
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ └── common
│ │ ├── .gitignore
│ │ ├── build
│ │ ├── index.d.ts
│ │ └── index.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── errors
│ │ │ ├── bad-request-error.ts
│ │ │ ├── custom-error.ts
│ │ │ ├── database-connection-error.ts
│ │ │ ├── not-authorized-error.ts
│ │ │ ├── not-found-error.ts
│ │ │ └── request-validation-error.ts
│ │ ├── index.ts
│ │ └── middlewares
│ │ │ ├── current-user.ts
│ │ │ ├── error-handler.ts
│ │ │ ├── require-auth.ts
│ │ │ └── validate-request.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── 13_Create_Read_Update_Destroy_Server_Setup.md
├── 13_Create_Read_Update_Destroy_Server_Setup
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── app.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ └── Ticket.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 14_NATS_Streaming_Server_An_Event_Bus_Implementation.md
├── 14_NATS_Streaming_Server_An_Event_Bus_Implementation
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── app.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ └── Ticket.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 15_Connecting_to_NATS_in_a_Node_JS_World.md
├── 15_Connecting_to_NATS_in_a_Node_JS_World
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ └── TicketUpdatedEventInterface.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── app.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ └── Ticket.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 16_Managing_a_NATS_Client.md
├── 16_Managing_a_NATS_Client
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ └── TicketUpdatedEventInterface.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ └── Ticket.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 17_Cross_Service_Data_Replication_In_Action.md
├── 17_Cross_Service_Data_Replication_In_Action
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ ├── TicketUpdatedEventInterface.ts
│ │ │ │ └── types
│ │ │ │ │ └── OrderStatus.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ ├── orders
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Ticket.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── delete.test.ts
│ │ │ │ │ ├── index.test.ts
│ │ │ │ │ ├── new.test.ts
│ │ │ │ │ └── show.test.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── new.ts
│ │ │ │ └── show.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ └── Ticket.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── orders-clusterIP.yaml
│ ├── orders-deployment.yaml
│ ├── orders-mongo-clusterIP.yaml
│ ├── orders-mongo-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 18_Understanding_Event_Flow.md
├── 18_Understanding_Event_Flow
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── OrderCancelledEventInterface.ts
│ │ │ │ ├── OrderCreatedEventInterface.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ ├── TicketUpdatedEventInterface.ts
│ │ │ │ └── types
│ │ │ │ │ └── OrderStatusEnum.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ ├── orders
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ └── publishers
│ │ │ │ │ ├── OrderCancelledPublisher.ts
│ │ │ │ │ └── OrderCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Ticket.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── delete.test.ts
│ │ │ │ │ ├── index.test.ts
│ │ │ │ │ ├── new.test.ts
│ │ │ │ │ └── show.test.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── new.ts
│ │ │ │ └── show.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ └── Ticket.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── orders-clusterIP.yaml
│ ├── orders-deployment.yaml
│ ├── orders-mongo-clusterIP.yaml
│ ├── orders-mongo-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 19_Listening_for_Events_and_Handling_Concurrency_Issues.md
├── 19_Listening_for_Events_and_Handling_Concurrency_Issues
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── OrderCancelledEventInterface.ts
│ │ │ │ ├── OrderCreatedEventInterface.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ ├── TicketUpdatedEventInterface.ts
│ │ │ │ └── types
│ │ │ │ │ └── OrderStatusEnum.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ ├── orders
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ │ ├── TicketUpdatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── TicketCreatedListener.test.ts
│ │ │ │ │ │ └── TicketUpdatedLister.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ ├── OrderCancelledPublisher.ts
│ │ │ │ │ └── OrderCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Ticket.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── delete.test.ts
│ │ │ │ │ ├── index.test.ts
│ │ │ │ │ ├── new.test.ts
│ │ │ │ │ └── show.test.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── new.ts
│ │ │ │ └── show.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ ├── listeners
│ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ ├── __test__
│ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ └── queueGroupName.ts
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ ├── Ticket.ts
│ │ │ └── __test__
│ │ │ │ └── Ticket.test.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── orders-clusterIP.yaml
│ ├── orders-deployment.yaml
│ ├── orders-mongo-clusterIP.yaml
│ ├── orders-mongo-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 20_Worker_Services.md
├── 20_Worker_Services
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ExpirationCompleteEventInterface.ts
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── OrderCancelledEventInterface.ts
│ │ │ │ ├── OrderCreatedEventInterface.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ ├── TicketUpdatedEventInterface.ts
│ │ │ │ └── types
│ │ │ │ │ └── OrderStatusEnum.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── expiration
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── events
│ │ │ │ ├── listeneres
│ │ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ └── ExpirationCompletePublisher.ts
│ │ │ ├── index.ts
│ │ │ └── queues
│ │ │ │ └── expiration-queue.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ ├── orders
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ │ ├── TicketUpdatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ │ ├── TicketCreatedListener.test.ts
│ │ │ │ │ │ └── TicketUpdatedLister.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ ├── OrderCancelledPublisher.ts
│ │ │ │ │ └── OrderCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Ticket.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── delete.test.ts
│ │ │ │ │ ├── index.test.ts
│ │ │ │ │ ├── new.test.ts
│ │ │ │ │ └── show.test.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── new.ts
│ │ │ │ └── show.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ ├── listeners
│ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ ├── __test__
│ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ └── queueGroupName.ts
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ ├── Ticket.ts
│ │ │ └── __test__
│ │ │ │ └── Ticket.test.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── expiration-deployment.yaml
│ ├── expiration-redis-clusterIP.yaml
│ ├── expiration-redis-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── orders-clusterIP.yaml
│ ├── orders-deployment.yaml
│ ├── orders-mongo-clusterIP.yaml
│ ├── orders-mongo-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 21_Handling_Payments.md
├── 21_Handling_Payments
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ └── index.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ExpirationCompleteEventInterface.ts
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── OrderCancelledEventInterface.ts
│ │ │ │ ├── OrderCreatedEventInterface.ts
│ │ │ │ ├── PaymentCreatedEventInteface.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ ├── TicketUpdatedEventInterface.ts
│ │ │ │ └── types
│ │ │ │ │ └── OrderStatusEnum.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── expiration
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── events
│ │ │ │ ├── listeneres
│ │ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ └── ExpirationCompletePublisher.ts
│ │ │ ├── index.ts
│ │ │ └── queues
│ │ │ │ └── expiration-queue.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ ├── orders
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ ├── PaymentCreatedListener.ts
│ │ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ │ ├── TicketUpdatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ │ ├── TicketCreatedListener.test.ts
│ │ │ │ │ │ └── TicketUpdatedLister.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ ├── OrderCancelledPublisher.ts
│ │ │ │ │ └── OrderCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Ticket.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── delete.test.ts
│ │ │ │ │ ├── index.test.ts
│ │ │ │ │ ├── new.test.ts
│ │ │ │ │ └── show.test.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── new.ts
│ │ │ │ └── show.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── payments
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ ├── NatsWrapper.ts
│ │ │ │ └── stripe.ts.disabled
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ └── PaymentCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Payment.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ └── new.test.ts
│ │ │ │ └── new.ts
│ │ │ ├── stripe.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ ├── listeners
│ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ ├── __test__
│ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ └── queueGroupName.ts
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ ├── Ticket.ts
│ │ │ └── __test__
│ │ │ │ └── Ticket.test.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── expiration-deployment.yaml
│ ├── expiration-redis-clusterIP.yaml
│ ├── expiration-redis-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── orders-clusterIP.yaml
│ ├── orders-deployment.yaml
│ ├── orders-mongo-clusterIP.yaml
│ ├── orders-mongo-deployment.yaml
│ ├── payments-clusterIP.yaml
│ ├── payments-deployment.yaml
│ ├── payments-mongo-clusterIP.yaml
│ ├── payments-mongo-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 22_Back_to_the_Client.md
├── 22_Back_to_the_Client
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ ├── index.js
│ │ │ ├── orders
│ │ │ ├── [orderId].js
│ │ │ └── index.js
│ │ │ └── tickets
│ │ │ ├── [ticketId].js
│ │ │ └── new.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ExpirationCompleteEventInterface.ts
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── OrderCancelledEventInterface.ts
│ │ │ │ ├── OrderCreatedEventInterface.ts
│ │ │ │ ├── PaymentCreatedEventInteface.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ ├── TicketUpdatedEventInterface.ts
│ │ │ │ └── types
│ │ │ │ │ └── OrderStatusEnum.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── expiration
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── events
│ │ │ │ ├── listeneres
│ │ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ └── ExpirationCompletePublisher.ts
│ │ │ ├── index.ts
│ │ │ └── queues
│ │ │ │ └── expiration-queue.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ ├── orders
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ ├── PaymentCreatedListener.ts
│ │ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ │ ├── TicketUpdatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ │ ├── TicketCreatedListener.test.ts
│ │ │ │ │ │ └── TicketUpdatedLister.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ ├── OrderCancelledPublisher.ts
│ │ │ │ │ └── OrderCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Ticket.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── delete.test.ts
│ │ │ │ │ ├── index.test.ts
│ │ │ │ │ ├── new.test.ts
│ │ │ │ │ └── show.test.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── new.ts
│ │ │ │ └── show.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── payments
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ ├── NatsWrapper.ts
│ │ │ │ └── stripe.ts.disabled
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ └── PaymentCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Payment.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ └── new.test.ts
│ │ │ │ └── new.ts
│ │ │ ├── stripe.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ ├── listeners
│ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ ├── __test__
│ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ └── queueGroupName.ts
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ ├── Ticket.ts
│ │ │ └── __test__
│ │ │ │ └── Ticket.test.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── auth-clusterIP.yaml
│ ├── auth-deployment.yaml
│ ├── auth-mongo-clusterIP.yaml
│ ├── auth-mongo-deployment.yaml
│ ├── client-clusterIP.yaml
│ ├── client-deployment.yaml
│ ├── expiration-deployment.yaml
│ ├── expiration-redis-clusterIP.yaml
│ ├── expiration-redis-deployment.yaml
│ ├── ingress-controller.yaml
│ ├── nats-clusterIP.yaml
│ ├── nats-deployment.yaml
│ ├── orders-clusterIP.yaml
│ ├── orders-deployment.yaml
│ ├── orders-mongo-clusterIP.yaml
│ ├── orders-mongo-deployment.yaml
│ ├── payments-clusterIP.yaml
│ ├── payments-deployment.yaml
│ ├── payments-mongo-clusterIP.yaml
│ ├── payments-mongo-deployment.yaml
│ ├── tickets-clusterIP.yaml
│ ├── tickets-deployment.yaml
│ ├── tickets-mongo-clusterIP.yaml
│ └── tickets-mongo-deployment.yaml
└── skaffold
│ └── skaffold.yaml
├── 23_CI_CD.md
├── 23_CI_CD
├── app
│ ├── auth
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── app.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ └── User.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── current-user.test.ts
│ │ │ │ │ ├── signin.test.ts
│ │ │ │ │ ├── signout.test.ts
│ │ │ │ │ └── signup.test.ts
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── signin.ts
│ │ │ │ ├── signout.ts
│ │ │ │ └── signup.ts
│ │ │ ├── services
│ │ │ │ └── password.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── client
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── api
│ │ │ └── build-client.js
│ │ ├── components
│ │ │ └── Header.js
│ │ ├── hooks
│ │ │ └── use-request.js
│ │ ├── next.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── pages
│ │ │ ├── _app.js
│ │ │ ├── auth
│ │ │ ├── signin.js
│ │ │ ├── signout.js
│ │ │ └── signup.js
│ │ │ ├── index.js
│ │ │ ├── orders
│ │ │ ├── [orderId].js
│ │ │ └── index.js
│ │ │ └── tickets
│ │ │ ├── [ticketId].js
│ │ │ └── new.js
│ ├── common
│ │ ├── .gitignore
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── errors
│ │ │ │ ├── bad-request-error.ts
│ │ │ │ ├── custom-error.ts
│ │ │ │ ├── database-connection-error.ts
│ │ │ │ ├── not-authorized-error.ts
│ │ │ │ ├── not-found-error.ts
│ │ │ │ └── request-validation-error.ts
│ │ │ ├── events
│ │ │ │ ├── ExpirationCompleteEventInterface.ts
│ │ │ │ ├── ListenerAbstract.ts
│ │ │ │ ├── OrderCancelledEventInterface.ts
│ │ │ │ ├── OrderCreatedEventInterface.ts
│ │ │ │ ├── PaymentCreatedEventInteface.ts
│ │ │ │ ├── PublisherAbstract.ts
│ │ │ │ ├── SubjectsEnum.ts
│ │ │ │ ├── TicketCreatedEventInterface.ts
│ │ │ │ ├── TicketUpdatedEventInterface.ts
│ │ │ │ └── types
│ │ │ │ │ └── OrderStatusEnum.ts
│ │ │ ├── index.ts
│ │ │ └── middlewares
│ │ │ │ ├── current-user.ts
│ │ │ │ ├── error-handler.ts
│ │ │ │ ├── require-auth.ts
│ │ │ │ └── validate-request.ts
│ │ └── tsconfig.json
│ ├── expiration
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── events
│ │ │ │ ├── listeneres
│ │ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ └── ExpirationCompletePublisher.ts
│ │ │ ├── index.ts
│ │ │ └── queues
│ │ │ │ └── expiration-queue.ts
│ │ └── tsconfig.json
│ ├── nats-test
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── events
│ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ └── TicketCreatedPublisher.ts
│ │ │ ├── listener.ts
│ │ │ └── publisher.ts
│ │ └── tsconfig.json
│ ├── orders
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ └── NatsWrapper.ts
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ ├── PaymentCreatedListener.ts
│ │ │ │ │ ├── TicketCreatedListener.ts
│ │ │ │ │ ├── TicketUpdatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── ExpirationCompleteListener.ts
│ │ │ │ │ │ ├── TicketCreatedListener.test.ts
│ │ │ │ │ │ └── TicketUpdatedLister.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ ├── OrderCancelledPublisher.ts
│ │ │ │ │ └── OrderCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Ticket.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ ├── delete.test.ts
│ │ │ │ │ ├── index.test.ts
│ │ │ │ │ ├── new.test.ts
│ │ │ │ │ └── show.test.ts
│ │ │ │ ├── delete.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── new.ts
│ │ │ │ └── show.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ ├── payments
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── NatsWrapper.ts
│ │ │ ├── __mocks__
│ │ │ │ ├── NatsWrapper.ts
│ │ │ │ └── stripe.ts.disabled
│ │ │ ├── app.ts
│ │ │ ├── events
│ │ │ │ ├── listeners
│ │ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ │ ├── __test__
│ │ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ │ └── queueGroupName.ts
│ │ │ │ └── publishers
│ │ │ │ │ └── PaymentCreatedPublisher.ts
│ │ │ ├── index.ts
│ │ │ ├── models
│ │ │ │ ├── Order.ts
│ │ │ │ └── Payment.ts
│ │ │ ├── routes
│ │ │ │ ├── __test__
│ │ │ │ │ └── new.test.ts
│ │ │ │ └── new.ts
│ │ │ ├── stripe.ts
│ │ │ └── test
│ │ │ │ └── setup.ts
│ │ └── tsconfig.json
│ └── tickets
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── NatsWrapper.ts
│ │ ├── __mocks__
│ │ │ └── NatsWrapper.ts
│ │ ├── app.ts
│ │ ├── events
│ │ │ ├── listeners
│ │ │ │ ├── OrderCancelledListener.ts
│ │ │ │ ├── OrderCreatedListener.ts
│ │ │ │ ├── __test__
│ │ │ │ │ ├── OrderCancelledListener.test.ts
│ │ │ │ │ └── OrderCreatedListener.test.ts
│ │ │ │ └── queueGroupName.ts
│ │ │ └── publishers
│ │ │ │ ├── TicketCreatedPublisher.ts
│ │ │ │ └── TicketUpdatedPublisher.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ ├── Ticket.ts
│ │ │ └── __test__
│ │ │ │ └── Ticket.test.ts
│ │ ├── routes
│ │ │ ├── __test__
│ │ │ │ ├── index.test.ts
│ │ │ │ ├── new.test.ts
│ │ │ │ ├── show.test.ts
│ │ │ │ └── update.test.ts
│ │ │ ├── index.ts
│ │ │ ├── new.ts
│ │ │ ├── show.ts
│ │ │ └── update.ts
│ │ └── test
│ │ │ └── setup.ts
│ │ └── tsconfig.json
├── k8s
│ ├── common
│ │ ├── auth-clusterIP.yaml
│ │ ├── auth-deployment.yaml
│ │ ├── auth-mongo-clusterIP.yaml
│ │ ├── auth-mongo-deployment.yaml
│ │ ├── client-clusterIP.yaml
│ │ ├── client-deployment.yaml
│ │ ├── expiration-deployment.yaml
│ │ ├── expiration-redis-clusterIP.yaml
│ │ ├── expiration-redis-deployment.yaml
│ │ ├── nats-clusterIP.yaml
│ │ ├── nats-deployment.yaml
│ │ ├── orders-clusterIP.yaml
│ │ ├── orders-deployment.yaml
│ │ ├── orders-mongo-clusterIP.yaml
│ │ ├── orders-mongo-deployment.yaml
│ │ ├── payments-clusterIP.yaml
│ │ ├── payments-deployment.yaml
│ │ ├── payments-mongo-clusterIP.yaml
│ │ ├── payments-mongo-deployment.yaml
│ │ ├── tickets-clusterIP.yaml
│ │ ├── tickets-deployment.yaml
│ │ ├── tickets-mongo-clusterIP.yaml
│ │ └── tickets-mongo-deployment.yaml
│ ├── dev
│ │ └── ingress-controller.yaml
│ └── prod
│ │ └── ingress-controller.yaml
└── skaffold
│ └── skaffold.yaml
├── Readme.md
└── img
├── pic-02-01.png
├── pic-02-02.png
├── pic-02-03.png
├── pic-02-04.png
├── pic-02-05.png
├── pic-02-06.png
├── pic-02-07.png
├── pic-02-08.png
├── pic-02-09.png
├── pic-02-10.png
├── pic-02-11.png
├── pic-02-12.png
├── pic-02-13.png
├── pic-02-14.png
├── pic-02-15.png
├── pic-02-16.png
├── pic-02-17.png
├── pic-02-18.png
├── pic-02-19.png
├── pic-02-20.png
├── pic-02-21.png
├── pic-02-22.png
├── pic-02-23.png
├── pic-04-01.png
├── pic-04-02.png
├── pic-04-03.png
├── pic-04-04.png
├── pic-04-05.png
├── pic-04-06.png
├── pic-04-07.png
├── pic-05-01.png
├── pic-05-02.png
├── pic-05-03.png
├── pic-05-04.png
├── pic-05-05.png
├── pic-08-01.png
├── pic-09-01.png
├── pic-09-02.png
├── pic-09-03.png
├── pic-09-04.png
├── pic-09-05.png
├── pic-09-06.png
├── pic-09-07.png
├── pic-09-08.png
├── pic-09-09.png
├── pic-09-10.png
├── pic-09-11.png
├── pic-09-12.png
├── pic-09-13.png
├── pic-09-14.png
├── pic-09-15.png
├── pic-09-16.png
├── pic-09-17.png
├── pic-09-18.png
├── pic-10-01.png
├── pic-10-02.png
├── pic-10-03.png
├── pic-10-04.png
├── pic-10-05.png
├── pic-11-01.png
├── pic-11-02.png
├── pic-11-03.png
├── pic-11-04.png
├── pic-11-05.png
├── pic-11-06.png
├── pic-11-07.png
├── pic-11-08.png
├── pic-11-09.png
├── pic-11-10.png
├── pic-11-11.png
├── pic-11-12.png
├── pic-11-13.png
├── pic-11-14.png
├── pic-11-15.png
├── pic-12-01.png
├── pic-12-02.png
├── pic-12-03.png
├── pic-12-04.png
├── pic-12-05.png
├── pic-13-01.png
├── pic-14-01.png
├── pic-14-02.png
├── pic-14-03.png
├── pic-14-04.png
├── pic-14-05.png
├── pic-14-06.png
├── pic-14-07.png
├── pic-14-08.png
├── pic-14-09.png
├── pic-14-10.png
├── pic-14-11.png
├── pic-14-12.png
├── pic-15-01.png
├── pic-15-02.png
├── pic-16-01.png
├── pic-16-02.png
├── pic-16-03.png
├── pic-16-04.png
├── pic-16-05.png
├── pic-16-06.png
├── pic-17-01.png
├── pic-17-02.png
├── pic-17-03.png
├── pic-17-04.png
├── pic-17-05.png
├── pic-17-06.png
├── pic-17-07.png
├── pic-18-01.png
├── pic-18-02.png
├── pic-18-03.png
├── pic-19-01.png
├── pic-19-02.png
├── pic-19-03.png
├── pic-19-04.png
├── pic-20-01.png
├── pic-20-02.png
├── pic-20-03.png
├── pic-20-04.png
├── pic-20-05.png
├── pic-21-01.png
├── pic-21-02.png
├── pic-21-03.png
├── pic-21-04.png
├── pic-21-05.png
├── pic-21-06.png
├── pic-21-07.png
├── pic-21-08.png
├── pic-21-09.png
├── pic-21-10.png
├── pic-21-11.png
├── pic-22-01.png
├── pic-22-02.png
├── pic-22-03.png
├── pic-22-04.png
├── pic-22-05.png
├── pic-23-01.png
├── pic-23-02.png
├── pic-23-03.png
├── pic-23-04.png
├── pic-23-05.png
└── pic-final-01.png
/.github/workflows/tests-auth.yml:
--------------------------------------------------------------------------------
1 | name: tests-auth
2 |
3 | on:
4 | push:
5 | paths:
6 | - '23_CI_CD/app/auth/**'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-18.04
11 | steps:
12 | - uses: actions/checkout@v2
13 | - run: cd 23_CI_CD/app/auth && npm install && npm run test:ci
14 |
--------------------------------------------------------------------------------
/.github/workflows/tests-orders.yml:
--------------------------------------------------------------------------------
1 | name: tests-orders
2 |
3 | on:
4 | push:
5 | paths:
6 | - '23_CI_CD/app/orders/**'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-18.04
11 | steps:
12 | - uses: actions/checkout@v2
13 | - run: cd 23_CI_CD/app/orders && npm install && npm run test:ci
14 |
--------------------------------------------------------------------------------
/.github/workflows/tests-payments.yml:
--------------------------------------------------------------------------------
1 | name: tests-payments
2 |
3 | on:
4 | push:
5 | paths:
6 | - '23_CI_CD/app/payments/**'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-18.04
11 | steps:
12 | - uses: actions/checkout@v2
13 | - run: cd 23_CI_CD/app/payments && npm install && npm run test:ci
14 |
--------------------------------------------------------------------------------
/.github/workflows/tests-tickets.yml:
--------------------------------------------------------------------------------
1 | name: tests-tickets
2 |
3 | on:
4 | push:
5 | paths:
6 | - '23_CI_CD/app/tickets/**'
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-18.04
11 | steps:
12 | - uses: actions/checkout@v2
13 | - run: cd 23_CI_CD/app/tickets && npm install && npm run test:ci
14 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | # *.test.js
3 | # *.spec.js
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "bracketSpacing": true
4 | }
5 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/02_A_Mini_Microservices_App/app/client/public/favicon.ico
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/client/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PostCreate from './PostCreate';
3 | import PostList from './PostList';
4 |
5 | export default () => {
6 | return (
7 |
8 |
Create Post
9 |
10 |
11 |
Posts
12 |
13 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render(, document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/comments/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "comments",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "nodemon index.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.19.2",
14 | "cors": "^2.8.5",
15 | "express": "^4.17.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/event-bus/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "event-bus",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "nodemon index.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.19.2",
14 | "express": "^4.17.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/moderation/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moderation",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "nodemon index.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.19.2",
14 | "express": "^4.17.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/posts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "posts",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "nodemon index.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.19.2",
14 | "cors": "^2.8.5",
15 | "express": "^4.17.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/02_A_Mini_Microservices_App/app/query/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "query",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "nodemon index.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.19.2",
14 | "cors": "^2.8.5",
15 | "express": "^4.17.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/client/public/favicon.ico
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render(, document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/comments/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/comments/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/event-bus/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/event-bus/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/moderation/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/moderation/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/posts/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/posts/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/query/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/app/query/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/k8s/client-srv-ClusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/k8s/comments-srv-ClusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: comments-svc
5 | spec:
6 | selector:
7 | app: comments
8 | ports:
9 | - name: comments
10 | protocol: TCP
11 | port: 4001
12 | targetPort: 4001
13 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/k8s/event-bus-srv-ClusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: event-bus-svc
5 | spec:
6 | selector:
7 | app: event-bus
8 | ports:
9 | - name: event-bus
10 | protocol: TCP
11 | port: 4005
12 | targetPort: 4005
13 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/k8s/moderation-srv-ClusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: moderation-svc
5 | spec:
6 | selector:
7 | app: moderation
8 | ports:
9 | - name: moderation
10 | protocol: TCP
11 | port: 4003
12 | targetPort: 4003
13 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/k8s/posts-srv-ClusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: posts-svc
5 | spec:
6 | selector:
7 | app: posts
8 | ports:
9 | - name: posts
10 | protocol: TCP
11 | port: 4000
12 | targetPort: 4000
13 |
--------------------------------------------------------------------------------
/04_Orchestrating_Collections_of_Services_with_Kubernetes/k8s/query-srv-ClusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: query-svc
5 | spec:
6 | selector:
7 | app: query
8 | ports:
9 | - name: query
10 | protocol: TCP
11 | port: 4002
12 | targetPort: 4002
13 |
--------------------------------------------------------------------------------
/05_Architecture_of_Multi_Service_Apps/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/05_Architecture_of_Multi_Service_Apps/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/05_Architecture_of_Multi_Service_Apps/app/auth/src/index.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { json } from 'body-parser';
3 |
4 | const app = express();
5 | app.use(json());
6 |
7 | app.get('/api/users/currentuser', (req, res) => {
8 | res.send('Hi there!');
9 | });
10 |
11 | app.listen(3000, () => {
12 | console.log('Listening on port 3000');
13 | });
14 |
--------------------------------------------------------------------------------
/05_Architecture_of_Multi_Service_Apps/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/07_Response_Normalization_Strategies/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/07_Response_Normalization_Strategies/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/07_Response_Normalization_Strategies/app/auth/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/07_Response_Normalization_Strategies/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.get('/api/users/currentuser', (req, res) => {
6 | res.send('Hi there!');
7 | });
8 |
9 | export { router as currentUserRouter };
10 |
--------------------------------------------------------------------------------
/07_Response_Normalization_Strategies/app/auth/src/routes/signin.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signin', (req, res) => {
6 | res.send('Hi there!');
7 | });
8 |
9 | export { router as signinRouter };
10 |
--------------------------------------------------------------------------------
/07_Response_Normalization_Strategies/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | res.send('Hi there!');
7 | });
8 |
9 | export { router as signoutRouter };
10 |
--------------------------------------------------------------------------------
/07_Response_Normalization_Strategies/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/app/auth/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.get('/api/users/currentuser', (req, res) => {
6 | res.send('Hi there!');
7 | });
8 |
9 | export { router as currentUserRouter };
10 |
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/app/auth/src/routes/signin.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signin', (req, res) => {
6 | res.send('Hi there!');
7 | });
8 |
9 | export { router as signinRouter };
10 |
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | res.send('Hi there!');
7 | });
8 |
9 | export { router as signoutRouter };
10 |
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/08_Database Management_and_Modeling/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/09_Authentication_Strategies_and_Options/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/09_Authentication_Strategies_and_Options/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/09_Authentication_Strategies_and_Options/app/auth/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/09_Authentication_Strategies_and_Options/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | import { currentUser } from '../middlewares/current-user';
4 |
5 | const router = express.Router();
6 |
7 | router.get('/api/users/currentuser', currentUser, (req, res) => {
8 | return res.send({ currentUser: req.currentUser });
9 | });
10 |
11 | export { router as currentUserRouter };
12 |
--------------------------------------------------------------------------------
/09_Authentication_Strategies_and_Options/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/09_Authentication_Strategies_and_Options/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/09_Authentication_Strategies_and_Options/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/10_Testing_Isolated_Microservices/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/10_Testing_Isolated_Microservices/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/10_Testing_Isolated_Microservices/app/auth/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/10_Testing_Isolated_Microservices/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | import { currentUser } from '../middlewares/current-user';
4 |
5 | const router = express.Router();
6 |
7 | router.get('/api/users/currentuser', currentUser, (req, res) => {
8 | return res.send({ currentUser: req.currentUser || null });
9 | });
10 |
11 | export { router as currentUserRouter };
12 |
--------------------------------------------------------------------------------
/10_Testing_Isolated_Microservices/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/10_Testing_Isolated_Microservices/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/10_Testing_Isolated_Microservices/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/app/auth/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/11_Integrating_a_Server_Side_Rendered_React_App/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/12_Code_Sharing_and_Reuse_Between_Services/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/13_Create_Read_Update_Destroy_Server_Setup/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/14_NATS_Streaming_Server_An_Event_Bus_Implementation/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 | }
5 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/15_Connecting_to_NATS_in_a_Node_JS_World/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/client/api/build-client.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export default ({ req }) => {
4 | if (typeof window === 'undefined') {
5 | return axios.create({
6 | baseURL: 'http://172-17-0-2.kubernetes.default.svc.cluster.local',
7 | headers: req.headers,
8 | });
9 | } else {
10 | return axios.create({
11 | baseUrl: '/',
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 | }
5 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/tickets/src/events/publishers/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketCreatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/tickets/src/events/publishers/TicketUpdatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketUpdatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketUpdatedPublisher extends PublisherAbstract<
8 | TicketUpdatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketUpdated = SubjectsEnum.TicketUpdated;
11 | }
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/app/tickets/src/routes/index.ts:
--------------------------------------------------------------------------------
1 | import express, { Request, Response } from 'express';
2 | import { Ticket } from '../models/Ticket';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/tickets', async (req: Request, res: Response) => {
7 | const tickets = await Ticket.find({});
8 | return res.send(tickets);
9 | });
10 |
11 | export { router as indexTicketRouter };
12 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/16_Managing_a_NATS_Client/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 | }
5 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/common/src/events/types/OrderStatus.ts:
--------------------------------------------------------------------------------
1 | export enum OrderStatusEnum {
2 | Created = 'created',
3 | Cancelled = 'cancelled',
4 | AwaitingPayment = 'awaiting:payment',
5 | Complete = 'complete',
6 | }
7 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/orders/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/orders/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/orders-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-svc
5 | spec:
6 | selector:
7 | app: orders
8 | ports:
9 | - name: orders
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/orders-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-mongo-svc
5 | spec:
6 | selector:
7 | app: orders-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/17_Cross_Service_Data_Replication_In_Action/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/client/api/build-client.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export default ({ req }) => {
4 | if (typeof window === 'undefined') {
5 | return axios.create({
6 | baseURL: 'http://172-17-0-2.kubernetes.default.svc.cluster.local',
7 | headers: req.headers,
8 | });
9 | } else {
10 | return axios.create({
11 | baseUrl: '/',
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/common/src/events/OrderCancelledEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface OrderCancelledEventInterface {
4 | subject: SubjectsEnum.OrderCancelled;
5 | data: {
6 | id: string;
7 | ticket: {
8 | id: string;
9 | };
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 |
5 | OrderCreated = 'order:created',
6 | OrderCancelled = 'order:cancelled',
7 | }
8 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | title: string;
8 | price: number;
9 | userId: string;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/common/src/events/types/OrderStatusEnum.ts:
--------------------------------------------------------------------------------
1 | export enum OrderStatusEnum {
2 | Created = 'created',
3 | Cancelled = 'cancelled',
4 | AwaitingPayment = 'awaiting:payment',
5 | Complete = 'complete',
6 | }
7 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/orders/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/orders/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/orders/src/events/publishers/OrderCancelledPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCancelledEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCancelledPublisher extends PublisherAbstract<
8 | OrderCancelledEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCancelled = SubjectsEnum.OrderCancelled;
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/orders/src/events/publishers/OrderCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCreatedPublisher extends PublisherAbstract<
8 | OrderCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCreated = SubjectsEnum.OrderCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/tickets/src/events/publishers/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketCreatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/tickets/src/events/publishers/TicketUpdatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketUpdatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketUpdatedPublisher extends PublisherAbstract<
8 | TicketUpdatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketUpdated = SubjectsEnum.TicketUpdated;
11 | }
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/app/tickets/src/routes/index.ts:
--------------------------------------------------------------------------------
1 | import express, { Request, Response } from 'express';
2 | import { Ticket } from '../models/Ticket';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/tickets', async (req: Request, res: Response) => {
7 | const tickets = await Ticket.find({});
8 | return res.send(tickets);
9 | });
10 |
11 | export { router as indexTicketRouter };
12 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/orders-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-svc
5 | spec:
6 | selector:
7 | app: orders
8 | ports:
9 | - name: orders
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/orders-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-mongo-svc
5 | spec:
6 | selector:
7 | app: orders-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/18_Understanding_Event_Flow/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/common/src/events/OrderCancelledEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface OrderCancelledEventInterface {
4 | subject: SubjectsEnum.OrderCancelled;
5 | data: {
6 | id: string;
7 | version: number;
8 | ticket: {
9 | id: string;
10 | };
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 |
5 | OrderCreated = 'order:created',
6 | OrderCancelled = 'order:cancelled',
7 | }
8 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/common/src/events/types/OrderStatusEnum.ts:
--------------------------------------------------------------------------------
1 | export enum OrderStatusEnum {
2 | Created = 'created',
3 | Cancelled = 'cancelled',
4 | AwaitingPayment = 'awaiting:payment',
5 | Complete = 'complete',
6 | }
7 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/orders/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/orders/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/orders/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'orders-service';
2 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/app/tickets/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'tickets-service';
2 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/orders-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-svc
5 | spec:
6 | selector:
7 | app: orders
8 | ports:
9 | - name: orders
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/orders-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-mongo-svc
5 | spec:
6 | selector:
7 | app: orders-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/19_Listening_for_Events_and_Handling_Concurrency_Issues/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/20_Worker_Services/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/20_Worker_Services/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/20_Worker_Services/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/20_Worker_Services/app/client/api/build-client.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export default ({ req }) => {
4 | if (typeof window === 'undefined') {
5 | return axios.create({
6 | baseURL: 'http://172-17-0-2.kubernetes.default.svc.cluster.local',
7 | headers: req.headers,
8 | });
9 | } else {
10 | return axios.create({
11 | baseUrl: '/',
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/src/events/ExpirationCompleteEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface ExpirationCompleteEventInterface {
4 | subject: SubjectsEnum.ExpirationComplete;
5 | data: {
6 | orderId: string;
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/src/events/OrderCancelledEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface OrderCancelledEventInterface {
4 | subject: SubjectsEnum.OrderCancelled;
5 | data: {
6 | id: string;
7 | version: number;
8 | ticket: {
9 | id: string;
10 | };
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 |
5 | OrderCreated = 'order:created',
6 | OrderCancelled = 'order:cancelled',
7 |
8 | ExpirationComplete = 'expiration:complete',
9 | }
10 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | orderId?: string;
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/common/src/events/types/OrderStatusEnum.ts:
--------------------------------------------------------------------------------
1 | export enum OrderStatusEnum {
2 | Created = 'created',
3 | Cancelled = 'cancelled',
4 | AwaitingPayment = 'awaiting:payment',
5 | Complete = 'complete',
6 | }
7 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/expiration/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/20_Worker_Services/app/expiration/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/20_Worker_Services/app/expiration/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/expiration/src/events/listeneres/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'expiration-service';
2 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/orders/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/20_Worker_Services/app/orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/20_Worker_Services/app/orders/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/orders/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'orders-service';
2 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/orders/src/events/publishers/OrderCancelledPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCancelledEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCancelledPublisher extends PublisherAbstract<
8 | OrderCancelledEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCancelled = SubjectsEnum.OrderCancelled;
11 | }
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/orders/src/events/publishers/OrderCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCreatedPublisher extends PublisherAbstract<
8 | OrderCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCreated = SubjectsEnum.OrderCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/20_Worker_Services/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/20_Worker_Services/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/tickets/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'tickets-service';
2 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/tickets/src/events/publishers/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketCreatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/tickets/src/events/publishers/TicketUpdatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketUpdatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketUpdatedPublisher extends PublisherAbstract<
8 | TicketUpdatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketUpdated = SubjectsEnum.TicketUpdated;
11 | }
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/app/tickets/src/routes/index.ts:
--------------------------------------------------------------------------------
1 | import express, { Request, Response } from 'express';
2 | import { Ticket } from '../models/Ticket';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/tickets', async (req: Request, res: Response) => {
7 | const tickets = await Ticket.find({});
8 | return res.send(tickets);
9 | });
10 |
11 | export { router as indexTicketRouter };
12 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/expiration-redis-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: expiration-redis-svc
5 | spec:
6 | selector:
7 | app: expiration-redis
8 | ports:
9 | - name: expiration-redis
10 | protocol: TCP
11 | port: 6379
12 | targetPort: 6379
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/orders-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-svc
5 | spec:
6 | selector:
7 | app: orders
8 | ports:
9 | - name: orders
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/orders-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-mongo-svc
5 | spec:
6 | selector:
7 | app: orders-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/20_Worker_Services/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/21_Handling_Payments/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/21_Handling_Payments/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/21_Handling_Payments/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/21_Handling_Payments/app/client/api/build-client.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export default ({ req }) => {
4 | if (typeof window === 'undefined') {
5 | return axios.create({
6 | baseURL: 'http://172-17-0-2.kubernetes.default.svc.cluster.local',
7 | headers: req.headers,
8 | });
9 | } else {
10 | return axios.create({
11 | baseUrl: '/',
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/events/ExpirationCompleteEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface ExpirationCompleteEventInterface {
4 | subject: SubjectsEnum.ExpirationComplete;
5 | data: {
6 | orderId: string;
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/events/OrderCancelledEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface OrderCancelledEventInterface {
4 | subject: SubjectsEnum.OrderCancelled;
5 | data: {
6 | id: string;
7 | version: number;
8 | ticket: {
9 | id: string;
10 | };
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/events/PaymentCreatedEventInteface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface PaymentCreatedEventInteface {
4 | subject: SubjectsEnum.PaymentCreated;
5 | data: {
6 | id: string;
7 | orderId: string;
8 | stripeId: string;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 |
5 | OrderCreated = 'order:created',
6 | OrderCancelled = 'order:cancelled',
7 |
8 | ExpirationComplete = 'expiration:complete',
9 |
10 | PaymentCreated = 'payment:created',
11 | }
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | orderId?: string;
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/common/src/events/types/OrderStatusEnum.ts:
--------------------------------------------------------------------------------
1 | export enum OrderStatusEnum {
2 | Created = 'created',
3 | Cancelled = 'cancelled',
4 | AwaitingPayment = 'awaiting:payment',
5 | Complete = 'complete',
6 | }
7 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/expiration/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/21_Handling_Payments/app/expiration/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/21_Handling_Payments/app/expiration/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/expiration/src/events/listeneres/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'expiration-service';
2 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/orders/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/21_Handling_Payments/app/orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/21_Handling_Payments/app/orders/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/orders/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'orders-service';
2 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/orders/src/events/publishers/OrderCancelledPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCancelledEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCancelledPublisher extends PublisherAbstract<
8 | OrderCancelledEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCancelled = SubjectsEnum.OrderCancelled;
11 | }
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/orders/src/events/publishers/OrderCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCreatedPublisher extends PublisherAbstract<
8 | OrderCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCreated = SubjectsEnum.OrderCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/payments/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/21_Handling_Payments/app/payments/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/21_Handling_Payments/app/payments/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/payments/src/__mocks__/stripe.ts.disabled:
--------------------------------------------------------------------------------
1 | export const stripe = {
2 | charges: {
3 | create: jest.fn().mockResolvedValue({}),
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/payments/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'payments-service';
2 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/payments/src/events/publishers/PaymentCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | SubjectsEnum,
3 | PublisherAbstract,
4 | PaymentCreatedEventInteface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class PaymentCreatedPublisher extends PublisherAbstract<
8 | PaymentCreatedEventInteface
9 | > {
10 | subject: SubjectsEnum.PaymentCreated = SubjectsEnum.PaymentCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/payments/src/stripe.ts:
--------------------------------------------------------------------------------
1 | import Stripe from 'stripe';
2 |
3 | export const stripe = new Stripe(process.env.STRIPE_KEY!, {
4 | apiVersion: '2020-03-02',
5 | });
6 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/21_Handling_Payments/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/21_Handling_Payments/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/tickets/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'tickets-service';
2 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/tickets/src/events/publishers/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketCreatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/tickets/src/events/publishers/TicketUpdatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketUpdatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketUpdatedPublisher extends PublisherAbstract<
8 | TicketUpdatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketUpdated = SubjectsEnum.TicketUpdated;
11 | }
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/app/tickets/src/routes/index.ts:
--------------------------------------------------------------------------------
1 | import express, { Request, Response } from 'express';
2 | import { Ticket } from '../models/Ticket';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/tickets', async (req: Request, res: Response) => {
7 | const tickets = await Ticket.find({});
8 | return res.send(tickets);
9 | });
10 |
11 | export { router as indexTicketRouter };
12 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/expiration-redis-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: expiration-redis-svc
5 | spec:
6 | selector:
7 | app: expiration-redis
8 | ports:
9 | - name: expiration-redis
10 | protocol: TCP
11 | port: 6379
12 | targetPort: 6379
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/orders-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-svc
5 | spec:
6 | selector:
7 | app: orders
8 | ports:
9 | - name: orders
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/orders-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-mongo-svc
5 | spec:
6 | selector:
7 | app: orders-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/payments-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: payments-svc
5 | spec:
6 | selector:
7 | app: payments
8 | ports:
9 | - name: payments
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/payments-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: payments-mongo-svc
5 | spec:
6 | selector:
7 | app: payments-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/21_Handling_Payments/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/client/api/build-client.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export default ({ req }) => {
4 | if (typeof window === 'undefined') {
5 | return axios.create({
6 | baseURL: 'http://172-17-0-2.kubernetes.default.svc.cluster.local',
7 | headers: req.headers,
8 | });
9 | } else {
10 | return axios.create({
11 | baseUrl: '/',
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/events/ExpirationCompleteEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface ExpirationCompleteEventInterface {
4 | subject: SubjectsEnum.ExpirationComplete;
5 | data: {
6 | orderId: string;
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/events/OrderCancelledEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface OrderCancelledEventInterface {
4 | subject: SubjectsEnum.OrderCancelled;
5 | data: {
6 | id: string;
7 | version: number;
8 | ticket: {
9 | id: string;
10 | };
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/events/PaymentCreatedEventInteface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface PaymentCreatedEventInteface {
4 | subject: SubjectsEnum.PaymentCreated;
5 | data: {
6 | id: string;
7 | orderId: string;
8 | stripeId: string;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 |
5 | OrderCreated = 'order:created',
6 | OrderCancelled = 'order:cancelled',
7 |
8 | ExpirationComplete = 'expiration:complete',
9 |
10 | PaymentCreated = 'payment:created',
11 | }
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | orderId?: string;
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/common/src/events/types/OrderStatusEnum.ts:
--------------------------------------------------------------------------------
1 | export enum OrderStatusEnum {
2 | Created = 'created',
3 | Cancelled = 'cancelled',
4 | AwaitingPayment = 'awaiting:payment',
5 | Complete = 'complete',
6 | }
7 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/expiration/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/expiration/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/expiration/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/expiration/src/events/listeneres/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'expiration-service';
2 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/orders/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/orders/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/orders/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'orders-service';
2 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/orders/src/events/publishers/OrderCancelledPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCancelledEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCancelledPublisher extends PublisherAbstract<
8 | OrderCancelledEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCancelled = SubjectsEnum.OrderCancelled;
11 | }
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/orders/src/events/publishers/OrderCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCreatedPublisher extends PublisherAbstract<
8 | OrderCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCreated = SubjectsEnum.OrderCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/payments/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/payments/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/payments/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/payments/src/__mocks__/stripe.ts.disabled:
--------------------------------------------------------------------------------
1 | export const stripe = {
2 | charges: {
3 | create: jest.fn().mockResolvedValue({}),
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/payments/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'payments-service';
2 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/payments/src/events/publishers/PaymentCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | SubjectsEnum,
3 | PublisherAbstract,
4 | PaymentCreatedEventInteface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class PaymentCreatedPublisher extends PublisherAbstract<
8 | PaymentCreatedEventInteface
9 | > {
10 | subject: SubjectsEnum.PaymentCreated = SubjectsEnum.PaymentCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/payments/src/stripe.ts:
--------------------------------------------------------------------------------
1 | import Stripe from 'stripe';
2 |
3 | export const stripe = new Stripe(process.env.STRIPE_KEY!, {
4 | apiVersion: '2020-03-02',
5 | });
6 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/tickets/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'tickets-service';
2 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/tickets/src/events/publishers/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketCreatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/app/tickets/src/events/publishers/TicketUpdatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketUpdatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketUpdatedPublisher extends PublisherAbstract<
8 | TicketUpdatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketUpdated = SubjectsEnum.TicketUpdated;
11 | }
12 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/expiration-redis-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: expiration-redis-svc
5 | spec:
6 | selector:
7 | app: expiration-redis
8 | ports:
9 | - name: expiration-redis
10 | protocol: TCP
11 | port: 6379
12 | targetPort: 6379
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/orders-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-svc
5 | spec:
6 | selector:
7 | app: orders
8 | ports:
9 | - name: orders
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/orders-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-mongo-svc
5 | spec:
6 | selector:
7 | app: orders-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/payments-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: payments-svc
5 | spec:
6 | selector:
7 | app: payments
8 | ports:
9 | - name: payments
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/payments-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: payments-mongo-svc
5 | spec:
6 | selector:
7 | app: payments-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/22_Back_to_the_Client/k8s/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/23_CI_CD/app/auth/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/23_CI_CD/app/auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/23_CI_CD/app/auth/src/routes/current-user.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { currentUser } from '@grider-ms-tickets/common';
3 |
4 | const router = express.Router();
5 |
6 | router.get('/api/users/currentuser', currentUser, (req, res) => {
7 | return res.send({ currentUser: req.currentUser || null });
8 | });
9 |
10 | export { router as currentUserRouter };
11 |
--------------------------------------------------------------------------------
/23_CI_CD/app/auth/src/routes/signout.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 |
3 | const router = express.Router();
4 |
5 | router.post('/api/users/signout', (req, res) => {
6 | req.session = null;
7 |
8 | return res.send({});
9 | });
10 |
11 | export { router as signoutRouter };
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/23_CI_CD/app/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "run", "dev"]
--------------------------------------------------------------------------------
/23_CI_CD/app/client/api/build-client.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export default ({ req }) => {
4 | if (typeof window === 'undefined') {
5 | return axios.create({
6 | baseURL: 'http://172-17-0-2.kubernetes.default.svc.cluster.local',
7 | headers: req.headers,
8 | });
9 | } else {
10 | return axios.create({
11 | baseUrl: '/',
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/23_CI_CD/app/client/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpackDevMiddleware: (config) => {
3 | config.watchOptions.poll = 300;
4 | return config;
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/errors/custom-error.ts:
--------------------------------------------------------------------------------
1 | export abstract class CustomError extends Error {
2 | abstract statusCode: number;
3 |
4 | constructor(message: string) {
5 | super(message);
6 | Object.setPrototypeOf(this, CustomError.prototype);
7 | }
8 |
9 | abstract serializeErrors(): { message: string; field?: string }[];
10 | }
11 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/errors/not-found-error.ts:
--------------------------------------------------------------------------------
1 | import { CustomError } from './custom-error';
2 |
3 | export class NotFoundError extends CustomError {
4 | statusCode = 404;
5 |
6 | constructor() {
7 | super('Route not found');
8 |
9 | Object.setPrototypeOf(this, NotFoundError.prototype);
10 | }
11 |
12 | serializeErrors() {
13 | return [{ message: 'Not Found' }];
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/events/ExpirationCompleteEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface ExpirationCompleteEventInterface {
4 | subject: SubjectsEnum.ExpirationComplete;
5 | data: {
6 | orderId: string;
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/events/OrderCancelledEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface OrderCancelledEventInterface {
4 | subject: SubjectsEnum.OrderCancelled;
5 | data: {
6 | id: string;
7 | version: number;
8 | ticket: {
9 | id: string;
10 | };
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/events/PaymentCreatedEventInteface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface PaymentCreatedEventInteface {
4 | subject: SubjectsEnum.PaymentCreated;
5 | data: {
6 | id: string;
7 | orderId: string;
8 | stripeId: string;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/events/SubjectsEnum.ts:
--------------------------------------------------------------------------------
1 | export enum SubjectsEnum {
2 | TicketCreated = 'ticket:created',
3 | TicketUpdated = 'ticket:updated',
4 |
5 | OrderCreated = 'order:created',
6 | OrderCancelled = 'order:cancelled',
7 |
8 | ExpirationComplete = 'expiration:complete',
9 |
10 | PaymentCreated = 'payment:created',
11 | }
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/events/TicketCreatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketCreatedEventInterface {
4 | subject: SubjectsEnum.TicketCreated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/events/TicketUpdatedEventInterface.ts:
--------------------------------------------------------------------------------
1 | import { SubjectsEnum } from './SubjectsEnum';
2 |
3 | export interface TicketUpdatedEventInterface {
4 | subject: SubjectsEnum.TicketUpdated;
5 | data: {
6 | id: string;
7 | version: number;
8 | title: string;
9 | price: number;
10 | userId: string;
11 | orderId?: string;
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/events/types/OrderStatusEnum.ts:
--------------------------------------------------------------------------------
1 | export enum OrderStatusEnum {
2 | Created = 'created',
3 | Cancelled = 'cancelled',
4 | AwaitingPayment = 'awaiting:payment',
5 | Complete = 'complete',
6 | }
7 |
--------------------------------------------------------------------------------
/23_CI_CD/app/common/src/middlewares/require-auth.ts:
--------------------------------------------------------------------------------
1 | import { Request, Response, NextFunction } from 'express';
2 | import { NotAuthorizedError } from '../errors/not-authorized-error';
3 |
4 | export const requireAuth = (
5 | req: Request,
6 | res: Response,
7 | next: NextFunction
8 | ) => {
9 | if (!req.currentUser) {
10 | throw new NotAuthorizedError();
11 | }
12 |
13 | next();
14 | };
15 |
--------------------------------------------------------------------------------
/23_CI_CD/app/expiration/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/23_CI_CD/app/expiration/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/23_CI_CD/app/expiration/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/expiration/src/events/listeneres/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'expiration-service';
2 |
--------------------------------------------------------------------------------
/23_CI_CD/app/nats-test/src/events/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | TicketCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/orders/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/23_CI_CD/app/orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/23_CI_CD/app/orders/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/orders/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'orders-service';
2 |
--------------------------------------------------------------------------------
/23_CI_CD/app/orders/src/events/publishers/OrderCancelledPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCancelledEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCancelledPublisher extends PublisherAbstract<
8 | OrderCancelledEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCancelled = SubjectsEnum.OrderCancelled;
11 | }
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/orders/src/events/publishers/OrderCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | OrderCreatedEventInterface,
4 | SubjectsEnum,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class OrderCreatedPublisher extends PublisherAbstract<
8 | OrderCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.OrderCreated = SubjectsEnum.OrderCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/payments/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/23_CI_CD/app/payments/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/23_CI_CD/app/payments/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/payments/src/__mocks__/stripe.ts.disabled:
--------------------------------------------------------------------------------
1 | export const stripe = {
2 | charges: {
3 | create: jest.fn().mockResolvedValue({}),
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/23_CI_CD/app/payments/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'payments-service';
2 |
--------------------------------------------------------------------------------
/23_CI_CD/app/payments/src/events/publishers/PaymentCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | SubjectsEnum,
3 | PublisherAbstract,
4 | PaymentCreatedEventInteface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class PaymentCreatedPublisher extends PublisherAbstract<
8 | PaymentCreatedEventInteface
9 | > {
10 | subject: SubjectsEnum.PaymentCreated = SubjectsEnum.PaymentCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/payments/src/stripe.ts:
--------------------------------------------------------------------------------
1 | import Stripe from 'stripe';
2 |
3 | export const stripe = new Stripe(process.env.STRIPE_KEY!, {
4 | apiVersion: '2020-03-02',
5 | });
6 |
--------------------------------------------------------------------------------
/23_CI_CD/app/tickets/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/23_CI_CD/app/tickets/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:12.16.3-alpine3.9
2 |
3 | WORKDIR /app
4 | COPY package.json ./
5 | RUN npm install --only=prod
6 | COPY ./ ./
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/23_CI_CD/app/tickets/src/__mocks__/NatsWrapper.ts:
--------------------------------------------------------------------------------
1 | export const natsWrapper = {
2 | client: {
3 | publish: jest
4 | .fn()
5 | .mockImplementationOnce(
6 | (subject: string, data: string, callback: () => void) => {
7 | callback();
8 | }
9 | ),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/tickets/src/events/listeners/queueGroupName.ts:
--------------------------------------------------------------------------------
1 | export const queueGroupName = 'tickets-service';
2 |
--------------------------------------------------------------------------------
/23_CI_CD/app/tickets/src/events/publishers/TicketCreatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketCreatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketCreatedPublisher extends PublisherAbstract<
8 | TicketCreatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketCreated = SubjectsEnum.TicketCreated;
11 | }
12 |
--------------------------------------------------------------------------------
/23_CI_CD/app/tickets/src/events/publishers/TicketUpdatedPublisher.ts:
--------------------------------------------------------------------------------
1 | import {
2 | PublisherAbstract,
3 | SubjectsEnum,
4 | TicketUpdatedEventInterface,
5 | } from '@grider-ms-tickets/common';
6 |
7 | export class TicketUpdatedPublisher extends PublisherAbstract<
8 | TicketUpdatedEventInterface
9 | > {
10 | subject: SubjectsEnum.TicketUpdated = SubjectsEnum.TicketUpdated;
11 | }
12 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/auth-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-svc
5 | spec:
6 | selector:
7 | app: auth
8 | ports:
9 | - name: auth
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/auth-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: auth-mongo-svc
5 | spec:
6 | selector:
7 | app: auth-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/client-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client-svc
5 | spec:
6 | selector:
7 | app: client
8 | ports:
9 | - name: client
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/expiration-redis-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: expiration-redis-svc
5 | spec:
6 | selector:
7 | app: expiration-redis
8 | ports:
9 | - name: expiration-redis
10 | protocol: TCP
11 | port: 6379
12 | targetPort: 6379
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/nats-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nats-svc
5 | spec:
6 | selector:
7 | app: nats
8 | ports:
9 | - name: nats-client
10 | protocol: TCP
11 | port: 4222
12 | targetPort: 4222
13 | - name: nats-monitoring
14 | protocol: TCP
15 | port: 8222
16 | targetPort: 8222
17 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/orders-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-svc
5 | spec:
6 | selector:
7 | app: orders
8 | ports:
9 | - name: orders
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/orders-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: orders-mongo-svc
5 | spec:
6 | selector:
7 | app: orders-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/payments-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: payments-svc
5 | spec:
6 | selector:
7 | app: payments
8 | ports:
9 | - name: payments
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/payments-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: payments-mongo-svc
5 | spec:
6 | selector:
7 | app: payments-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/tickets-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-svc
5 | spec:
6 | selector:
7 | app: tickets
8 | ports:
9 | - name: tickets
10 | protocol: TCP
11 | port: 3000
12 | targetPort: 3000
13 |
--------------------------------------------------------------------------------
/23_CI_CD/k8s/common/tickets-mongo-clusterIP.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: tickets-mongo-svc
5 | spec:
6 | selector:
7 | app: tickets-mongo
8 | ports:
9 | - name: db
10 | protocol: TCP
11 | port: 27017
12 | targetPort: 27017
13 |
--------------------------------------------------------------------------------
/img/pic-02-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-01.png
--------------------------------------------------------------------------------
/img/pic-02-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-02.png
--------------------------------------------------------------------------------
/img/pic-02-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-03.png
--------------------------------------------------------------------------------
/img/pic-02-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-04.png
--------------------------------------------------------------------------------
/img/pic-02-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-05.png
--------------------------------------------------------------------------------
/img/pic-02-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-06.png
--------------------------------------------------------------------------------
/img/pic-02-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-07.png
--------------------------------------------------------------------------------
/img/pic-02-08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-08.png
--------------------------------------------------------------------------------
/img/pic-02-09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-09.png
--------------------------------------------------------------------------------
/img/pic-02-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-10.png
--------------------------------------------------------------------------------
/img/pic-02-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-11.png
--------------------------------------------------------------------------------
/img/pic-02-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-12.png
--------------------------------------------------------------------------------
/img/pic-02-13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-13.png
--------------------------------------------------------------------------------
/img/pic-02-14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-14.png
--------------------------------------------------------------------------------
/img/pic-02-15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-15.png
--------------------------------------------------------------------------------
/img/pic-02-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-16.png
--------------------------------------------------------------------------------
/img/pic-02-17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-17.png
--------------------------------------------------------------------------------
/img/pic-02-18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-18.png
--------------------------------------------------------------------------------
/img/pic-02-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-19.png
--------------------------------------------------------------------------------
/img/pic-02-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-20.png
--------------------------------------------------------------------------------
/img/pic-02-21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-21.png
--------------------------------------------------------------------------------
/img/pic-02-22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-22.png
--------------------------------------------------------------------------------
/img/pic-02-23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-02-23.png
--------------------------------------------------------------------------------
/img/pic-04-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-04-01.png
--------------------------------------------------------------------------------
/img/pic-04-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-04-02.png
--------------------------------------------------------------------------------
/img/pic-04-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-04-03.png
--------------------------------------------------------------------------------
/img/pic-04-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-04-04.png
--------------------------------------------------------------------------------
/img/pic-04-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-04-05.png
--------------------------------------------------------------------------------
/img/pic-04-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-04-06.png
--------------------------------------------------------------------------------
/img/pic-04-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-04-07.png
--------------------------------------------------------------------------------
/img/pic-05-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-05-01.png
--------------------------------------------------------------------------------
/img/pic-05-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-05-02.png
--------------------------------------------------------------------------------
/img/pic-05-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-05-03.png
--------------------------------------------------------------------------------
/img/pic-05-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-05-04.png
--------------------------------------------------------------------------------
/img/pic-05-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-05-05.png
--------------------------------------------------------------------------------
/img/pic-08-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-08-01.png
--------------------------------------------------------------------------------
/img/pic-09-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-01.png
--------------------------------------------------------------------------------
/img/pic-09-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-02.png
--------------------------------------------------------------------------------
/img/pic-09-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-03.png
--------------------------------------------------------------------------------
/img/pic-09-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-04.png
--------------------------------------------------------------------------------
/img/pic-09-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-05.png
--------------------------------------------------------------------------------
/img/pic-09-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-06.png
--------------------------------------------------------------------------------
/img/pic-09-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-07.png
--------------------------------------------------------------------------------
/img/pic-09-08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-08.png
--------------------------------------------------------------------------------
/img/pic-09-09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-09.png
--------------------------------------------------------------------------------
/img/pic-09-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-10.png
--------------------------------------------------------------------------------
/img/pic-09-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-11.png
--------------------------------------------------------------------------------
/img/pic-09-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-12.png
--------------------------------------------------------------------------------
/img/pic-09-13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-13.png
--------------------------------------------------------------------------------
/img/pic-09-14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-14.png
--------------------------------------------------------------------------------
/img/pic-09-15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-15.png
--------------------------------------------------------------------------------
/img/pic-09-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-16.png
--------------------------------------------------------------------------------
/img/pic-09-17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-17.png
--------------------------------------------------------------------------------
/img/pic-09-18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-09-18.png
--------------------------------------------------------------------------------
/img/pic-10-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-10-01.png
--------------------------------------------------------------------------------
/img/pic-10-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-10-02.png
--------------------------------------------------------------------------------
/img/pic-10-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-10-03.png
--------------------------------------------------------------------------------
/img/pic-10-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-10-04.png
--------------------------------------------------------------------------------
/img/pic-10-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-10-05.png
--------------------------------------------------------------------------------
/img/pic-11-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-01.png
--------------------------------------------------------------------------------
/img/pic-11-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-02.png
--------------------------------------------------------------------------------
/img/pic-11-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-03.png
--------------------------------------------------------------------------------
/img/pic-11-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-04.png
--------------------------------------------------------------------------------
/img/pic-11-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-05.png
--------------------------------------------------------------------------------
/img/pic-11-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-06.png
--------------------------------------------------------------------------------
/img/pic-11-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-07.png
--------------------------------------------------------------------------------
/img/pic-11-08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-08.png
--------------------------------------------------------------------------------
/img/pic-11-09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-09.png
--------------------------------------------------------------------------------
/img/pic-11-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-10.png
--------------------------------------------------------------------------------
/img/pic-11-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-11.png
--------------------------------------------------------------------------------
/img/pic-11-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-12.png
--------------------------------------------------------------------------------
/img/pic-11-13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-13.png
--------------------------------------------------------------------------------
/img/pic-11-14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-14.png
--------------------------------------------------------------------------------
/img/pic-11-15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-11-15.png
--------------------------------------------------------------------------------
/img/pic-12-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-12-01.png
--------------------------------------------------------------------------------
/img/pic-12-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-12-02.png
--------------------------------------------------------------------------------
/img/pic-12-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-12-03.png
--------------------------------------------------------------------------------
/img/pic-12-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-12-04.png
--------------------------------------------------------------------------------
/img/pic-12-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-12-05.png
--------------------------------------------------------------------------------
/img/pic-13-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-13-01.png
--------------------------------------------------------------------------------
/img/pic-14-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-01.png
--------------------------------------------------------------------------------
/img/pic-14-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-02.png
--------------------------------------------------------------------------------
/img/pic-14-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-03.png
--------------------------------------------------------------------------------
/img/pic-14-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-04.png
--------------------------------------------------------------------------------
/img/pic-14-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-05.png
--------------------------------------------------------------------------------
/img/pic-14-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-06.png
--------------------------------------------------------------------------------
/img/pic-14-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-07.png
--------------------------------------------------------------------------------
/img/pic-14-08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-08.png
--------------------------------------------------------------------------------
/img/pic-14-09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-09.png
--------------------------------------------------------------------------------
/img/pic-14-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-10.png
--------------------------------------------------------------------------------
/img/pic-14-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-11.png
--------------------------------------------------------------------------------
/img/pic-14-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-14-12.png
--------------------------------------------------------------------------------
/img/pic-15-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-15-01.png
--------------------------------------------------------------------------------
/img/pic-15-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-15-02.png
--------------------------------------------------------------------------------
/img/pic-16-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-16-01.png
--------------------------------------------------------------------------------
/img/pic-16-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-16-02.png
--------------------------------------------------------------------------------
/img/pic-16-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-16-03.png
--------------------------------------------------------------------------------
/img/pic-16-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-16-04.png
--------------------------------------------------------------------------------
/img/pic-16-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-16-05.png
--------------------------------------------------------------------------------
/img/pic-16-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-16-06.png
--------------------------------------------------------------------------------
/img/pic-17-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-17-01.png
--------------------------------------------------------------------------------
/img/pic-17-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-17-02.png
--------------------------------------------------------------------------------
/img/pic-17-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-17-03.png
--------------------------------------------------------------------------------
/img/pic-17-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-17-04.png
--------------------------------------------------------------------------------
/img/pic-17-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-17-05.png
--------------------------------------------------------------------------------
/img/pic-17-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-17-06.png
--------------------------------------------------------------------------------
/img/pic-17-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-17-07.png
--------------------------------------------------------------------------------
/img/pic-18-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-18-01.png
--------------------------------------------------------------------------------
/img/pic-18-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-18-02.png
--------------------------------------------------------------------------------
/img/pic-18-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-18-03.png
--------------------------------------------------------------------------------
/img/pic-19-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-19-01.png
--------------------------------------------------------------------------------
/img/pic-19-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-19-02.png
--------------------------------------------------------------------------------
/img/pic-19-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-19-03.png
--------------------------------------------------------------------------------
/img/pic-19-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-19-04.png
--------------------------------------------------------------------------------
/img/pic-20-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-20-01.png
--------------------------------------------------------------------------------
/img/pic-20-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-20-02.png
--------------------------------------------------------------------------------
/img/pic-20-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-20-03.png
--------------------------------------------------------------------------------
/img/pic-20-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-20-04.png
--------------------------------------------------------------------------------
/img/pic-20-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-20-05.png
--------------------------------------------------------------------------------
/img/pic-21-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-01.png
--------------------------------------------------------------------------------
/img/pic-21-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-02.png
--------------------------------------------------------------------------------
/img/pic-21-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-03.png
--------------------------------------------------------------------------------
/img/pic-21-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-04.png
--------------------------------------------------------------------------------
/img/pic-21-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-05.png
--------------------------------------------------------------------------------
/img/pic-21-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-06.png
--------------------------------------------------------------------------------
/img/pic-21-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-07.png
--------------------------------------------------------------------------------
/img/pic-21-08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-08.png
--------------------------------------------------------------------------------
/img/pic-21-09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-09.png
--------------------------------------------------------------------------------
/img/pic-21-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-10.png
--------------------------------------------------------------------------------
/img/pic-21-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-21-11.png
--------------------------------------------------------------------------------
/img/pic-22-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-22-01.png
--------------------------------------------------------------------------------
/img/pic-22-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-22-02.png
--------------------------------------------------------------------------------
/img/pic-22-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-22-03.png
--------------------------------------------------------------------------------
/img/pic-22-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-22-04.png
--------------------------------------------------------------------------------
/img/pic-22-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-22-05.png
--------------------------------------------------------------------------------
/img/pic-23-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-23-01.png
--------------------------------------------------------------------------------
/img/pic-23-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-23-02.png
--------------------------------------------------------------------------------
/img/pic-23-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-23-03.png
--------------------------------------------------------------------------------
/img/pic-23-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-23-04.png
--------------------------------------------------------------------------------
/img/pic-23-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-23-05.png
--------------------------------------------------------------------------------
/img/pic-final-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webmakaka/Microservices-with-Node-JS-and-React/4f3a385676b6612e2afec9d5e7fbd9887162150b/img/pic-final-01.png
--------------------------------------------------------------------------------