Skip to content

Commit

Permalink
[MS 780] feat: App improvements (#22)
Browse files Browse the repository at this point in the history
* [MS-780] feat: Fix commands. Add send-notification tests

* [MS-780] feat: Bump to fastify v5

* [MS-780] feat: Add sentry

* [MS-780] feat: Bump libs

* [MS-780] chore: Update readme

* [MS-780] feat: Add webhooks tests

* [MS-780] feat: More tests. Coverage setup

* [MS-780] ci: Improve CI

* [MS-780] feat: More tests
  • Loading branch information
piotrgrundas committed Oct 24, 2024
1 parent 7488340 commit 2da3b2e
Show file tree
Hide file tree
Showing 38 changed files with 3,845 additions and 2,831 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/code_quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Code quality

on:
pull_request:
branches: ["*"]

jobs:
code_quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9.10.0
run_install: false

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"

- name: Install dependencies
run: pnpm --version && pnpm install --frozen-lockfile

- name: Check prettier
run: pnpm lint:prettier

- name: Check eslint
run: pnpm lint:eslint

- name: Check types
run: pnpm lint:tsc

- name: Check coverage
run: |
RESULT="$(pnpm --silent test:coverage:avg)"
echo "Average coverage: ${RESULT}"
13 changes: 2 additions & 11 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Linters and tests
name: Tests

on:
pull_request:
branches: ["*"]

jobs:
tests-and-linters:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -25,14 +25,5 @@ jobs:
- name: Install dependencies
run: pnpm --version && pnpm install --frozen-lockfile

- name: Check prettier
run: pnpm lint:prettier

- name: Check eslint
run: pnpm lint:eslint

- name: Check types
run: pnpm lint:tsc

- name: Run tests
run: pnpm test
6 changes: 2 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then pnpm install --frozen-lockfile
RUN pnpm build


FROM node:20-alpine as runner
FROM node:20-alpine AS runner

WORKDIR /app

Expand All @@ -32,9 +32,7 @@ COPY --from=builder /app/etc /app/etc
COPY --from=builder /app/build /app/build
COPY --from=builder /app/node_modules /app/node_modules

# ENTRYPOINT ["/bin/bash", "./etc/commands/docker-entrypoint.sh"]

EXPOSE 3000
EXPOSE 3001
EXPOSE 3002

CMD [ "pnpm", "dev" ]
50 changes: 47 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ Alternatively, you can use docker to run the app.

## Localstack

Localstack is used for local development to replace need of usage AWS services. Everything needed is automatically configured on container startup.

### Install [awscli-local](https://github.com/localstack/awscli-local)

```
Expand Down Expand Up @@ -110,11 +112,37 @@ Verifying domain identity:
$ awslocal ses verify-domain-identity --region ap-southeast-1 --domain mirumee.com --endpoint-url=http://localhost:4566
```

### Envs, Prerequisite etc info
## Using AWS

You can use AWS services directly, without using localstack.

You will need:

- set your AWS envs:
- `AWS_ACCESS_KEY_ID`
- `AWS_SECRET_ACCESS_KEY`
- `AWS_REGION`
- create a [SQS queue](https://aws.amazon.com/sqs/) and set the `SQS_QUEUE_URL` env.
- create a [secret manager](https://aws.amazon.com/secrets-manager/) entry and set the `SECRET_MANAGER_APP_CONFIG_PATH` env. The initial secret should be pre populated with empty object `{}`.

## Email providers

To change the email provider, change the `getEmailProvider` function in [src/providers/email.ts](src/providers/email.ts) to return the provider of your choice.

### [Amazon Simple Email Service](https://aws.amazon.com/ses/)

```
import { awsSESEmailProvider } from "@/lib/emails/providers/awsSESEmailProvider";
export const getEmailProvider = awsSESEmailProvider;
```

In AWS you will have to:

TBD
- verify [domain identity](https://docs.aws.amazon.com/ses/latest/dg/creating-identities.html#just-verify-domain-proc) from `FROM_EMAIL` env.
- verify [email identity](https://docs.aws.amazon.com/ses/latest/dg/creating-identities.html#just-verify-email-proc) from `FROM_DOMAIN` env.

### Local email develpment
### Local email development

App is using [React Email](https://react.email/) for email templating.

Expand All @@ -131,3 +159,19 @@ $ docker compose up emails
```

Now you can see emails preview in the browser - [http://localhost:3002/](http://localhost:3002/)

### Tests

App is using [vitest](https://vitest.dev/) for testing.

To run tests:

```
$ pnpm test
```

or

```
$ pnpm test:watch
```
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ services:
- "3002:3002"

localstack:
container_name: "${LOCALSTACK_DOCKER_NAME:-localstack}"
image: localstack/localstack:latest
container_name: aws
image: localstack/localstack:3.8.1
environment:
# LocalStack configuration: https://docs.localstack.cloud/references/configuration/
- AWS_DEFAULT_REGION=${AWS_REGION?:AWS_REGION env is required}
Expand Down
File renamed without changes.
File renamed without changes.
14 changes: 13 additions & 1 deletion etc/scripts/common.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { sentryEsbuildPlugin } from "@sentry/esbuild-plugin";
import copy from "esbuild-plugin-copy";

const isSentryEnabled =
process.env.SENTRY_ORG &&
process.env.SENTRY_PROJECT &&
process.env.SENTRY_AUTH_TOKEN;

export const esbuildConfig = {
entryPoints: ["src/emails-sender.ts", "src/events-receiver.ts"],
entryPoints: ["src/events-receiver.ts", "src/emails-sender.ts"],
outdir: "build",
bundle: true,
allowOverwrite: true,
Expand All @@ -19,6 +25,12 @@ export const esbuildConfig = {
"process.env.NODE_ENV": `"${process.env.NODE_ENV ?? "production"}"`,
},
plugins: [
sentryEsbuildPlugin({
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
disable: !isSentryEnabled,
}),
copy({
watch: true,
resolveFrom: "cwd",
Expand Down
87 changes: 46 additions & 41 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"node": "20"
},
"scripts": {
"dev": "concurrently -k -p \"[{name}]\" -n \"TSC,BUILD,EVENTS-RECEIVER,EMAILS-SENDER\" -c \"blue.bold,red.bold,cyan.bold,green.bold\" \"pnpm tsc:watch\" \"pnpm dev:build\" \"pnpm dev:run:events-receiver\" \"pnpm dev:run:emails-sender-proxy\"",
"dev": "concurrently -k -p \"[{name}]\" -n \"TSC,BUILD,RECEIVER,SENDER\" -c \"blue.bold,red.bold,cyan.bold,green.bold\" \"pnpm tsc:watch\" \"pnpm dev:build\" \"pnpm dev:run:events-receiver\" \"pnpm dev:run:emails-sender-proxy\"",
"dev:build": "dotenv -v NODE_ENV=development -- node ./etc/scripts/dev.mjs",
"dev:emails": "dotenv -- email dev -d ./src/emails -p 3002",
"dev:run:events-receiver": "dotenv -v NODE_ENV=development -- nodemon --inspect=0.0.0.0:9229 --watch build/events-receiver.js build/events-receiver.js",
Expand All @@ -29,6 +29,7 @@
"test": "npx vitest --run",
"test:watch": "npx vitest",
"test:coverage": "npx vitest --coverage --run",
"test:coverage:avg": "pnpm test:coverage | grep -E \"All files\" -A 0 | awk '{print ($4 + $6 + $8+ $10) / 4}'",
"tsc:watch": "tsc --watch --noEmit",
"codegen": "graphql-codegen --require dotenv/config --config ./codegen.ts",
"prepare": "husky"
Expand All @@ -37,86 +38,90 @@
"*.{js,mjs,cjs,ts,tsx}": "pnpm lint:fix"
},
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.637.0",
"@aws-sdk/client-ses": "^3.658.1",
"@aws-sdk/client-sqs": "^3.658.1",
"@fastify/aws-lambda": "^4.1.0",
"@aws-sdk/client-secrets-manager": "^3.670.0",
"@aws-sdk/client-ses": "^3.670.0",
"@aws-sdk/client-sqs": "^3.670.0",
"@fastify/aws-lambda": "^5.0.0",
"@fastify/error": "^4.0.0",
"@react-email/components": "^0.0.25",
"@types/react": "18",
"@types/react-dom": "18",
"@sentry/aws-serverless": "^8.34.0",
"@sentry/node": "^8.34.0",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"dataloader": "^2.2.2",
"dotenv-cli": "^7.4.2",
"drizzle-kit": "^0.23.2",
"drizzle-orm": "^0.32.2",
"esbuild": "^0.23.1",
"esbuild-plugin-copy": "^2.1.1",
"eslint-define-config": "^2.1.0",
"fastify": "^4.28.1",
"fastify-plugin": "^4.5.1",
"fastify-raw-body": "^4.3.0",
"fastify-type-provider-zod": "^2.0.0",
"fastify": "^5.0.0",
"fastify-plugin": "^5.0.1",
"fastify-raw-body": "^5.0.0",
"fastify-type-provider-zod": "^4.0.2",
"graphql": "^16.9.0",
"husky": "^9.1.4",
"jose": "^5.6.3",
"husky": "^9.1.6",
"jose": "^5.9.4",
"jsonwebtoken": "^9.0.2",
"path-to-regexp": "^7.0.0",
"pg": "^8.12.0",
"path-to-regexp": "^8.2.0",
"pg": "^8.13.0",
"pino-pretty": "^11.2.2",
"postcss": "^8.4.40",
"react": "18",
"react-dom": "18",
"postcss": "^8.4.47",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-email": "^3.0.1",
"tailwind-merge": "^2.5.3",
"tailwindcss": "^3.4.13",
"tailwind-merge": "^2.5.4",
"tailwindcss": "^3.4.14",
"ts-invariant": "^0.10.3",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.5.2",
"vite": "^5.3.5",
"typescript": "^5.6.3",
"vite": "^5.4.9",
"vite-tsconfig-paths": "^4.3.2",
"winston": "^3.14.2",
"winston": "^3.15.0",
"winston-console-format": "^1.0.8",
"zod": "^3.23.8"
},
"devDependencies": {
"@digitalroute/cz-conventional-changelog-for-jira": "^8.0.1",
"@graphql-codegen/cli": "^5.0.2",
"@graphql-codegen/cli": "^5.0.3",
"@graphql-codegen/near-operation-file-preset": "^3.0.0",
"@graphql-codegen/typed-document-node": "^5.0.9",
"@graphql-codegen/typescript": "^4.0.9",
"@graphql-codegen/typescript-operations": "^4.2.3",
"@graphql-codegen/typed-document-node": "^5.0.10",
"@graphql-codegen/typescript": "^4.1.0",
"@graphql-codegen/typescript-operations": "^4.3.0",
"@graphql-typed-document-node/core": "^3.2.0",
"@sentry/esbuild-plugin": "^2.22.5",
"@types/aws-lambda": "^8.10.145",
"@types/graphql": "^14.5.0",
"@types/jsonwebtoken": "^9.0.6",
"@types/node": "^20.14.9",
"@types/pg": "^8.11.6",
"@typescript-eslint/parser": "^7.14.1",
"@vitest/coverage-v8": "^2.0.4",
"commitizen": "^4.3.0",
"@types/jsonwebtoken": "^9.0.7",
"@types/node": "^20.16.11",
"@types/pg": "^8.11.10",
"@typescript-eslint/parser": "^7.18.0",
"@vitest/coverage-v8": "^2.1.3",
"commitizen": "^4.3.1",
"concurrently": "^8.2.2",
"dotenv": "^16.4.5",
"eslint": ">=8",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-drizzle": "^0.2.3",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-n": "^17.10.1",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-n": "^17.11.1",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-promise": "^7.0.0",
"eslint-plugin-promise": "^7.1.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-sort-keys-fix": "^1.1.2",
"eslint-plugin-typescript-sort-keys": "^3.2.0",
"graphql-config": "^5.0.3",
"eslint-plugin-typescript-sort-keys": "^3.3.0",
"graphql-config": "^5.1.3",
"lint-staged": "^15.2.10",
"nodemon": "^3.1.7",
"prettier": "^3.3.2",
"prettier": "^3.3.3",
"sqs-consumer": "^11.1.0",
"ts-essentials": "^10.0.2",
"typescript-eslint": "^7.18.0",
"vitest": "^2.0.3"
"vitest": "^2.1.3"
},
"optionalDependencies": {
"@rollup/rollup-linux-arm64-gnu": "^4.19.0"
"@rollup/rollup-linux-arm64-gnu": "^4.24.0"
},
"config": {
"commitizen": {
Expand Down
Loading

0 comments on commit 2da3b2e

Please sign in to comment.