Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/drizzle #6

Merged
merged 14 commits into from May 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
File renamed without changes.
3 changes: 2 additions & 1 deletion .envrc
@@ -1,3 +1,4 @@
layout node

# dotenv .env
dotenv .env
# dotenv .env.local
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still cant get .env to work like id expect/desire

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");