Skip to content

Commit

Permalink
feat: Drizzle, pnpm, schema overhaul
Browse files Browse the repository at this point in the history
Its a lot going on, but its cool.
  • Loading branch information
dcramer committed May 11, 2023
1 parent d64cef5 commit 021497b
Show file tree
Hide file tree
Showing 119 changed files with 13,645 additions and 33,172 deletions.
File renamed without changes.
3 changes: 2 additions & 1 deletion .envrc
@@ -1,3 +1,4 @@
layout node

# dotenv .env
dotenv .env
# dotenv .env.local
23 changes: 16 additions & 7 deletions .github/workflows/ci.yml
@@ -1,19 +1,28 @@
name: CI
inputs:
node-version:
required: false
description: Node version for setup-node
default: 18.x
on:
push:
branches:
- main
pull_request:

jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: nrwl/nx-set-shas@v3
- run: npm ci
- run: docker-compose up -d
- run: npx nx affected -t test --parallel=3 --configuration=ci
- run: npx nx affected -t build --parallel=3
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Set node version to ${{ inputs.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ inputs.node-version }}
- name: Run docker images
run: docker-compose up -d
- name: Run tests
run: npm run test:ci
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -4,6 +4,7 @@
node_modules/
.pnp/
.pnp.js
package-lock.json

# testing
coverage/
Expand Down
2 changes: 0 additions & 2 deletions .test.env

This file was deleted.

54 changes: 16 additions & 38 deletions Dockerfile
Expand Up @@ -3,21 +3,19 @@ FROM node:18-alpine as base
# set for base and all layer that inherit from it
ENV NODE_ENV production

FROM base as deps
RUN npm install -g pnpm

WORKDIR /app

ADD package.json package-lock.json .
ADD packages ./packages
ADD apps/web/package.json ./apps/web/package.json
ADD apps/api/package.json ./apps/api/package.json
RUN npm install --workspaces

# build web
FROM base as build-web
FROM base as build

WORKDIR /app

ADD . .
# ADD package.json pnpm-lock.yaml pnpm-workspace.yaml .
# ADD packages ./packages
# ADD apps/web/package.json ./apps/web/package.json
# ADD apps/api/package.json ./apps/api/package.json
RUN pnpm install

ARG VERSION
ENV VERSION $VERSION

Expand All @@ -36,34 +34,14 @@ ENV API_SERVER $API_SERVER
ARG GOOGLE_CLIENT_ID
ENV GOOGLE_CLIENT_ID $GOOGLE_CLIENT_ID

COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/packages/shared ./node_modules/@peated/shared

ADD apps/web/ .

RUN --mount=type=secret,id=SENTRY_AUTH_TOKEN \
SENTRY_AUTH_TOKEN="$(cat /run/secrets/SENTRY_AUTH_TOKEN)" \
npm run build

# build api
FROM base as build-api

WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/packages/shared ./node_modules/@peated/shared

ADD apps/api/prisma .
RUN npx prisma generate

ADD apps/api/ .

RUN npm run build
pnpm build

# web service
FROM nginx:alpine as web

COPY --from=build-web /app/dist /usr/share/nginx/html
COPY --from=build /app/dist /usr/share/nginx/html

RUN rm /etc/nginx/conf.d/default.conf

Expand All @@ -74,13 +52,11 @@ EXPOSE 8043
CMD ["nginx", "-g", "daemon off;"]

# api service
FROM build-api as api
FROM build as api

WORKDIR /app

COPY --from=build-api /app/node_modules ./node_modules

ADD apps/api/ .
COPY --from=build /app/ ./

ARG VERSION
ENV VERSION $VERSION
Expand All @@ -92,4 +68,6 @@ ENV PORT 4000

EXPOSE 4000

CMD ["npm", "start"]
WORKDIR /app/apps/api

CMD ["pnpm", "start"]
13 changes: 13 additions & 0 deletions Makefile
@@ -0,0 +1,13 @@
PG_CONTAINER=docker exec -t peated-postgres-1

reset-db:
$(MAKE) drop-db
$(MAKE) create-db

drop-db:
$(PG_CONTAINER) dropdb --if-exists -h 127.0.0.1 -p 5432 -U postgres peated
$(PG_CONTAINER) dropdb --if-exists -h 127.0.0.1 -p 5432 -U postgres test_peated

create-db:
$(PG_CONTAINER) createdb -E utf-8 -h 127.0.0.1 -p 5432 -U postgres peated || exit 0
$(PG_CONTAINER) createdb -E utf-8 -h 127.0.0.1 -p 5432 -U postgres test_peated || exit 0
2 changes: 2 additions & 0 deletions Procfile
@@ -0,0 +1,2 @@
web: npm run dev:web
api: npm run dev:api
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -23,13 +23,13 @@ Note: If you need to tweak default settings, `cp .env.example .env` and go to to
Create a local user to avoid setting up Google credentials:

```
npm run create-user -w apps/api
npm run user:create e -w apps/api
```

Run the dev server, which spins up both the `web` and the `api` services:

```
nf start
npm run dev
```

NX is used to manage the monorepo, e.g.
Expand Down
4 changes: 4 additions & 0 deletions apps/api/.env.test
@@ -0,0 +1,4 @@
NODE_ENV=test
# DATABASE_URL=postgresql://postgres:postgres@localhost:5432/test_peated
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
JWT_SECRET=super-secret-test-secret
5 changes: 5 additions & 0 deletions apps/api/drizzle.config.json
@@ -0,0 +1,5 @@
{
"out": "./migrations",
"schema": "./src/db/schema.ts",
"breakpoints": false
}
176 changes: 176 additions & 0 deletions apps/api/migrations/0000_lying_purple_man.sql
@@ -0,0 +1,176 @@
DO $$ BEGIN
CREATE TYPE "category" AS ENUM('blend', 'bourbon', 'rye', 'single_grain', 'single_malt', 'spirit');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
CREATE TYPE "entity_type" AS ENUM('brand', 'distiller');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
CREATE TYPE "identity_provider" AS ENUM('google');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
CREATE TYPE "object_type" AS ENUM('bottle', 'edition', 'entity');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

CREATE TABLE IF NOT EXISTS "bottle" (
"id" bigserial PRIMARY KEY NOT NULL,
"name" varchar(255) NOT NULL,
"category" category,
"brand_id" bigint NOT NULL,
"stated_age" smallint,
"created_at" timestamp DEFAULT now() NOT NULL,
"created_by_id" bigint NOT NULL
);

CREATE TABLE IF NOT EXISTS "bottle_distiller" (
"bottle_id" bigint NOT NULL,
"distiller_id" bigint NOT NULL
);
--> statement-breakpoint
ALTER TABLE "bottle_distiller" ADD CONSTRAINT "bottle_distiller_bottle_id_distiller_id" PRIMARY KEY("bottle_id","distiller_id");

CREATE TABLE IF NOT EXISTS "change" (
"id" bigserial PRIMARY KEY NOT NULL,
"object_id" bigint NOT NULL,
"object_type" object_type NOT NULL,
"data" text NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"created_by_id" bigint NOT NULL
);

CREATE TABLE IF NOT EXISTS "edition" (
"id" bigserial PRIMARY KEY NOT NULL,
"name" varchar(255) NOT NULL,
"barrel" smallint,
"bottle_id" bigint NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"created_by_id" bigint NOT NULL
);

CREATE TABLE IF NOT EXISTS "entity" (
"id" bigserial PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"country" text,
"region" text,
"type" entity_type[] NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"created_by_id" bigint NOT NULL
);

CREATE TABLE IF NOT EXISTS "identity" (
"id" bigserial PRIMARY KEY NOT NULL,
"provider" identity_provider NOT NULL,
"external_id" text NOT NULL,
"user_id" bigint NOT NULL
);

CREATE TABLE IF NOT EXISTS "tasting" (
"id" bigserial PRIMARY KEY NOT NULL,
"bottle_id" bigint NOT NULL,
"edition_id" bigint,
"comments" text,
"tags" text[],
"rating" double precision NOT NULL,
"image_url" text,
"created_at" timestamp DEFAULT now() NOT NULL,
"created_by_id" bigint NOT NULL
);

CREATE TABLE IF NOT EXISTS "user" (
"id" bigserial PRIMARY KEY NOT NULL,
"email" text NOT NULL,
"password_hash" varchar(256),
"display_name" text,
"picture_url" text,
"active" boolean DEFAULT true NOT NULL,
"admin" boolean DEFAULT false NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL
);

DO $$ BEGIN
ALTER TABLE "bottle" ADD CONSTRAINT "bottle_brand_id_entity_id_fk" FOREIGN KEY ("brand_id") REFERENCES "entity"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "bottle" ADD CONSTRAINT "bottle_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "bottle_distiller" ADD CONSTRAINT "bottle_distiller_bottle_id_bottle_id_fk" FOREIGN KEY ("bottle_id") REFERENCES "bottle"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "bottle_distiller" ADD CONSTRAINT "bottle_distiller_distiller_id_entity_id_fk" FOREIGN KEY ("distiller_id") REFERENCES "entity"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "change" ADD CONSTRAINT "change_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "edition" ADD CONSTRAINT "edition_bottle_id_bottle_id_fk" FOREIGN KEY ("bottle_id") REFERENCES "bottle"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "edition" ADD CONSTRAINT "edition_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "entity" ADD CONSTRAINT "entity_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "identity" ADD CONSTRAINT "identity_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "tasting" ADD CONSTRAINT "tasting_bottle_id_bottle_id_fk" FOREIGN KEY ("bottle_id") REFERENCES "bottle"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "tasting" ADD CONSTRAINT "tasting_edition_id_bottle_id_fk" FOREIGN KEY ("edition_id") REFERENCES "bottle"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

DO $$ BEGIN
ALTER TABLE "tasting" ADD CONSTRAINT "tasting_created_by_id_user_id_fk" FOREIGN KEY ("created_by_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

CREATE UNIQUE INDEX IF NOT EXISTS "bottle_brand_unq" ON "bottle" ("name","brand_id");
CREATE UNIQUE INDEX IF NOT EXISTS "edition_unq" ON "edition" ("bottle_id","name","barrel");
CREATE UNIQUE INDEX IF NOT EXISTS "entity_name_unq" ON "entity" ("name");
CREATE UNIQUE INDEX IF NOT EXISTS "identity_unq" ON "identity" ("provider","external_id");
CREATE UNIQUE INDEX IF NOT EXISTS "user_email_unq" ON "user" ("email");

0 comments on commit 021497b

Please sign in to comment.