mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 20:13:49 +00:00
Migrate database to Vercel postgres
This commit is contained in:
74
README.md
74
README.md
@@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
The Biergarten App is a web application designed for beer lovers to share their favorite brews and breweries with like-minded people online.
|
The Biergarten App is a web application designed for beer lovers to share their favorite brews and breweries with like-minded people online.
|
||||||
|
|
||||||
This application's stack consists of Next.js, Prisma and CockroachDB, and I'm motivated to learn more about these technologies while exploring my passion for beer.
|
This application's stack consists of Next.js, Prisma and Vercel Postgres. I'm motivated to learn more about these technologies while exploring my passion for beer.
|
||||||
|
|
||||||
I've also incorporated different APIs into the application, such as the Cloudinary API for image uploading and the SparkPost API for email services.
|
I've also incorporated different APIs into the application, such as the Cloudinary API for image uploading, the SparkPost API for email services as well as Mapbox for geolocation and map data.
|
||||||
|
|
||||||
To handle serverless functions (API routes), I use the next-connect package.
|
To handle serverless functions (API routes), I use the next-connect package.
|
||||||
|
|
||||||
@@ -26,6 +26,39 @@ In this app you will encounter various beer related terms. Here is a list of ter
|
|||||||
|
|
||||||
The [International Bitterness Units](https://en.wikipedia.org/wiki/Beer_measurement#Bitterness) scale, or IBU, is used to approximately quantify the bitterness of beer. This scale is not measured on the perceived bitterness of the beer, but rather the amount of a component of beer known as iso-alpha acids.
|
The [International Bitterness Units](https://en.wikipedia.org/wiki/Beer_measurement#Bitterness) scale, or IBU, is used to approximately quantify the bitterness of beer. This scale is not measured on the perceived bitterness of the beer, but rather the amount of a component of beer known as iso-alpha acids.
|
||||||
|
|
||||||
|
## Technologies
|
||||||
|
|
||||||
|
### General
|
||||||
|
|
||||||
|
- [Next.js](https://nextjs.org/)
|
||||||
|
- A React based framework for building web applications offering several features such as server side rendering, static site generation and API routes.
|
||||||
|
|
||||||
|
### Client
|
||||||
|
|
||||||
|
- [SWR](https://swr.vercel.app/)
|
||||||
|
- A React Hooks library for fetching data with support for caching, revalidation and error handling.
|
||||||
|
- [Tailwind CSS](https://tailwindcss.com/)
|
||||||
|
- A popular open-source utility-first CSS framework that provides pre-defined classes to style HTML elements.
|
||||||
|
- [Headless UI](https://headlessui.dev/)
|
||||||
|
- A set of completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.
|
||||||
|
- [Daisy UI](https://daisyui.com/)
|
||||||
|
- A component library for Tailwind CSS that provides ready-to-use components for building user interfaces.
|
||||||
|
|
||||||
|
### Server
|
||||||
|
|
||||||
|
- [Prisma](https://www.prisma.io/)
|
||||||
|
- An open-source ORM for Node.js and TypeScript applications.
|
||||||
|
- [Vercel Postgres](https://vercel.com/dashboard/stores)
|
||||||
|
- A managed PostgreSQL database service provided by Vercel.
|
||||||
|
- [Cloudinary](https://cloudinary.com/)
|
||||||
|
- A cloud-based image and video management service that provides developers with an easy way to upload, store, and manipulate media assets.
|
||||||
|
- [SparkPost](https://www.sparkpost.com/)
|
||||||
|
- A cloud-based email delivery service that provides developers with an easy way to send transactional and marketing emails.
|
||||||
|
- [Mapbox](https://www.mapbox.com/)
|
||||||
|
- A suite of open-source mapping tools that allows developers to add custom maps, search, and navigation into their applications.
|
||||||
|
- [next-connect](https://github.com/hoangvvo/next-connect#readme)
|
||||||
|
- A promise-based method routing and middleware layer for Next.js.
|
||||||
|
|
||||||
## How to run locally
|
## How to run locally
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
@@ -39,7 +72,8 @@ You will also need to create a free account with the following services:
|
|||||||
|
|
||||||
- [Cloudinary](https://cloudinary.com/users/register/free)
|
- [Cloudinary](https://cloudinary.com/users/register/free)
|
||||||
- [SparkPost](https://www.sparkpost.com/)
|
- [SparkPost](https://www.sparkpost.com/)
|
||||||
- [CockroachDB](https://www.cockroachlabs.com/)
|
- [Vercel Postgres](https://vercel.com/dashboard/stores)
|
||||||
|
- [Mapbox](https://account.mapbox.com/auth/signup/)
|
||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
@@ -60,23 +94,28 @@ npm install
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
echo "BASE_URL=
|
echo "BASE_URL=
|
||||||
|
|
||||||
CLOUDINARY_CLOUD_NAME=
|
CLOUDINARY_CLOUD_NAME=
|
||||||
CLOUDINARY_KEY=
|
CLOUDINARY_KEY=
|
||||||
CLOUDINARY_SECRET=
|
CLOUDINARY_SECRET=
|
||||||
|
|
||||||
CONFIRMATION_TOKEN_SECRET=
|
CONFIRMATION_TOKEN_SECRET=
|
||||||
SESSION_SECRET=
|
SESSION_SECRET=
|
||||||
|
SESSION_TOKEN_NAME=
|
||||||
DATABASE_URL=
|
SESSION_MAX_AGE=
|
||||||
NODE_ENV=
|
NODE_ENV=
|
||||||
|
POSTGRES_URL=
|
||||||
|
POSTGRES_PRISMA_URL=
|
||||||
|
POSTGRES_URL_NON_POOLING=
|
||||||
|
POSTGRES_USER=
|
||||||
|
POSTGRES_HOST=
|
||||||
|
POSTGRES_PASSWORD=
|
||||||
|
POSTGRES_DATABASE=
|
||||||
|
MAPBOX_ACCESS_TOKEN=
|
||||||
|
NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN=
|
||||||
SPARKPOST_API_KEY=
|
SPARKPOST_API_KEY=
|
||||||
SPARKPOST_SENDER_ADDRESS=" > .env
|
SPARKPOST_SENDER_ADDRESS=" > .env
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Explanation of environment variables
|
### Explanation of environment variables
|
||||||
|
|
||||||
- `BASE_URL` is the base URL of the application.
|
- `BASE_URL` is the base URL of the application.
|
||||||
- For example, if you are running the application locally, you can set this to `http://localhost:3000`.
|
- For example, if you are running the application locally, you can set this to `http://localhost:3000`.
|
||||||
@@ -86,8 +125,15 @@ SPARKPOST_SENDER_ADDRESS=" > .env
|
|||||||
- You can generate a random string using the`openssl rand -base64 127` command.
|
- You can generate a random string using the`openssl rand -base64 127` command.
|
||||||
- `SESSION_SECRET` is the secret used to sign the session cookie.
|
- `SESSION_SECRET` is the secret used to sign the session cookie.
|
||||||
- Use the same command as above to generate a random string.
|
- Use the same command as above to generate a random string.
|
||||||
- `DATABASE_URL` is the URL of your CockroachDB database.
|
- `SESSION_TOKEN_NAME` is the name of the session cookie.
|
||||||
- You can find this in the connection string in the CockroachDB Admin UI.
|
- You can set this to `biergarten`.
|
||||||
|
- `SESSION_MAX_AGE` is the maximum age of the session cookie in milliseconds.
|
||||||
|
- You can set this to `604800000` (1 week).
|
||||||
|
- `POSTGRES_URL`, `POSTGRES_PRISMA_URL`, `POSTGRES_URL_NON_POOLING`, `POSTGRES_USER`, `POSTGRES_HOST`, `POSTGRES_PASSWORD`, and `POSTGRES_DATABASE` are the credentials for your Vercel Postgres database.
|
||||||
|
- You can create a free account [here](https://vercel.com/dashboard/stores).
|
||||||
|
- `MAPBOX_ACCESS_TOKEN` and `NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN` are the access tokens for your Mapbox account.
|
||||||
|
- You can create a free account [here](https://account.mapbox.com/auth/signup/).
|
||||||
|
- You will need to create two access tokens, one for the server-side and one for the client-side.
|
||||||
- `NODE_ENV` is the environment in which the application is running.
|
- `NODE_ENV` is the environment in which the application is running.
|
||||||
- You can set this to `development` or `production`.
|
- You can set this to `development` or `production`.
|
||||||
- `SPARKPOST_API_KEY` is the API key for your SparkPost account.
|
- `SPARKPOST_API_KEY` is the API key for your SparkPost account.
|
||||||
@@ -113,7 +159,7 @@ npm run seed
|
|||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
# License
|
## License
|
||||||
|
|
||||||
The Biergarten App is licensed under the GNU General Public License v3.0. This means that anyone is free to use, modify, and distribute the code as long as they also distribute their modifications under the same license.
|
The Biergarten App is licensed under the GNU General Public License v3.0. This means that anyone is free to use, modify, and distribute the code as long as they also distribute their modifications under the same license.
|
||||||
|
|
||||||
@@ -123,4 +169,4 @@ By contributing to this repository, you agree to license your contributions unde
|
|||||||
|
|
||||||
If you have any questions or concerns about the license, please feel free to submit an issue to this repository.
|
If you have any questions or concerns about the license, please feel free to submit an issue to this repository.
|
||||||
|
|
||||||
I hope that this project will be useful to other developers and beer enthusiasts who are interested in learning about web development with Next.js, Prisma, CockroachDB, and other technologies.
|
I hope that this project will be useful to other developers and beer enthusiasts who are interested in learning about web development with Next.js, Prisma, Postgres, and other technologies.
|
||||||
|
|||||||
83
src/config/env/index.ts
vendored
83
src/config/env/index.ts
vendored
@@ -18,11 +18,19 @@ const envSchema = z.object({
|
|||||||
SESSION_SECRET: z.string(),
|
SESSION_SECRET: z.string(),
|
||||||
SESSION_TOKEN_NAME: z.string(),
|
SESSION_TOKEN_NAME: z.string(),
|
||||||
SESSION_MAX_AGE: z.coerce.number().positive(),
|
SESSION_MAX_AGE: z.coerce.number().positive(),
|
||||||
DATABASE_URL: z.string().url(),
|
|
||||||
|
POSTGRES_URL: z.string().url(),
|
||||||
|
POSTGRES_PRISMA_URL: z.string().url(),
|
||||||
|
POSTGRES_URL_NON_POOLING: z.string().url(),
|
||||||
|
POSTGRES_USER: z.string(),
|
||||||
|
POSTGRES_PASSWORD: z.string(),
|
||||||
|
POSTGRES_DATABASE: z.string(),
|
||||||
|
POSTGRES_HOST: z.string(),
|
||||||
|
|
||||||
NODE_ENV: z.enum(['development', 'production', 'test']),
|
NODE_ENV: z.enum(['development', 'production', 'test']),
|
||||||
SPARKPOST_API_KEY: z.string(),
|
SPARKPOST_API_KEY: z.string(),
|
||||||
SPARKPOST_SENDER_ADDRESS: z.string().email(),
|
SPARKPOST_SENDER_ADDRESS: z.string().email(),
|
||||||
MAPBOX_ACCESS_TOKEN: z.string()
|
MAPBOX_ACCESS_TOKEN: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const parsed = envSchema.safeParse(env);
|
const parsed = envSchema.safeParse(env);
|
||||||
@@ -110,12 +118,74 @@ export const SESSION_TOKEN_NAME = parsed.data.SESSION_TOKEN_NAME;
|
|||||||
export const SESSION_MAX_AGE = parsed.data.SESSION_MAX_AGE;
|
export const SESSION_MAX_AGE = parsed.data.SESSION_MAX_AGE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL of the CockroachDB database. CockroachDB uses the PostgreSQL wire protocol.
|
* PostgreSQL connection URL taken from Vercel.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* 'postgres://username:password@localhost/my-database';
|
* 'postgresql://user:password@host:5432/database';
|
||||||
|
*
|
||||||
|
* @see https://vercel.com/dashboard/stores
|
||||||
*/
|
*/
|
||||||
export const DATABASE_URL = parsed.data.DATABASE_URL;
|
export const POSTGRES_URL = parsed.data.POSTGRES_URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PostgreSQL connection URL for Prisma taken from Vercel.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* 'postgresql://user:password@host:5432/database';
|
||||||
|
*
|
||||||
|
* @see https://vercel.com/dashboard/stores
|
||||||
|
*/
|
||||||
|
export const POSTGRES_PRISMA_URL = parsed.data.POSTGRES_PRISMA_URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-pooling PostgreSQL connection URL taken from Vercel.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* 'postgresql://user:password@host:5432/database';
|
||||||
|
*
|
||||||
|
* @see https://vercel.com/dashboard/stores
|
||||||
|
*/
|
||||||
|
export const POSTGRES_URL_NON_POOLING = parsed.data.POSTGRES_URL_NON_POOLING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PostgreSQL user from Vercel.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* 'user';
|
||||||
|
*
|
||||||
|
* @see https://vercel.com/dashboard/stores
|
||||||
|
*/
|
||||||
|
export const POSTGRES_USER = parsed.data.POSTGRES_USER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PostgreSQL password from Vercel.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* 'password';
|
||||||
|
*
|
||||||
|
* @see https://vercel.com/dashboard/stores
|
||||||
|
*/
|
||||||
|
export const POSTGRES_PASSWORD = parsed.data.POSTGRES_PASSWORD;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PostgreSQL database from Vercel.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* 'database';
|
||||||
|
*
|
||||||
|
* @see https://vercel.com/dashboard/stores
|
||||||
|
*/
|
||||||
|
export const POSTGRES_DATABASE = parsed.data.POSTGRES_DATABASE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PostgreSQL host from Vercel.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* 'ep-sweet-pineapple.us-east-1.postgres.vercel-storage.com';
|
||||||
|
*
|
||||||
|
* @see https://vercel.com/dashboard/stores
|
||||||
|
*/
|
||||||
|
export const POSTGRES_HOST = parsed.data.POSTGRES_HOST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node environment.
|
* Node environment.
|
||||||
@@ -151,9 +221,8 @@ export const SPARKPOST_SENDER_ADDRESS = parsed.data.SPARKPOST_SENDER_ADDRESS;
|
|||||||
* Your Mapbox access token.
|
* Your Mapbox access token.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* 'pk.abcdefghijklmnopqrstuvwxyz123456';
|
* 'pk.abcdefghijklmnopqrstuvwxyz123456';
|
||||||
*
|
*
|
||||||
* @see https://docs.mapbox.com/help/how-mapbox-works/access-tokens/
|
* @see https://docs.mapbox.com/help/how-mapbox-works/access-tokens/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const MAPBOX_ACCESS_TOKEN = parsed.data.MAPBOX_ACCESS_TOKEN;
|
export const MAPBOX_ACCESS_TOKEN = parsed.data.MAPBOX_ACCESS_TOKEN;
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
-- CreateTable
|
|
||||||
CREATE TABLE "BreweryPostLike" (
|
|
||||||
"id" STRING NOT NULL,
|
|
||||||
"breweryPostId" STRING NOT NULL,
|
|
||||||
"likedById" STRING NOT NULL,
|
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
|
||||||
|
|
||||||
CONSTRAINT "BreweryPostLike_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_breweryPostId_fkey" FOREIGN KEY ("breweryPostId") REFERENCES "BreweryPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_likedById_fkey" FOREIGN KEY ("likedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
-- AlterTable
|
|
||||||
ALTER TABLE "BreweryPost" ADD COLUMN "dateEstablished" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to drop the column `location` on the `BreweryPost` table. All the data in the column will be lost.
|
|
||||||
- Added the required column `address` to the `BreweryPost` table without a default value. This is not possible if the table is not empty.
|
|
||||||
- Added the required column `city` to the `BreweryPost` table without a default value. This is not possible if the table is not empty.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "BreweryPost" DROP COLUMN "location";
|
|
||||||
ALTER TABLE "BreweryPost" ADD COLUMN "address" STRING NOT NULL;
|
|
||||||
ALTER TABLE "BreweryPost" ADD COLUMN "city" STRING NOT NULL;
|
|
||||||
ALTER TABLE "BreweryPost" ADD COLUMN "coordinates" FLOAT8[];
|
|
||||||
ALTER TABLE "BreweryPost" ADD COLUMN "country" STRING;
|
|
||||||
ALTER TABLE "BreweryPost" ADD COLUMN "stateOrProvince" STRING;
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to drop the column `address` on the `BreweryPost` table. All the data in the column will be lost.
|
|
||||||
- You are about to drop the column `city` on the `BreweryPost` table. All the data in the column will be lost.
|
|
||||||
- You are about to drop the column `coordinates` on the `BreweryPost` table. All the data in the column will be lost.
|
|
||||||
- You are about to drop the column `country` on the `BreweryPost` table. All the data in the column will be lost.
|
|
||||||
- You are about to drop the column `stateOrProvince` on the `BreweryPost` table. All the data in the column will be lost.
|
|
||||||
- A unique constraint covering the columns `[locationId]` on the table `BreweryPost` will be added. If there are existing duplicate values, this will fail.
|
|
||||||
- Added the required column `locationId` to the `BreweryPost` table without a default value. This is not possible if the table is not empty.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "BreweryPost" DROP COLUMN "address";
|
|
||||||
ALTER TABLE "BreweryPost" DROP COLUMN "city";
|
|
||||||
ALTER TABLE "BreweryPost" DROP COLUMN "coordinates";
|
|
||||||
ALTER TABLE "BreweryPost" DROP COLUMN "country";
|
|
||||||
ALTER TABLE "BreweryPost" DROP COLUMN "stateOrProvince";
|
|
||||||
ALTER TABLE "BreweryPost" ADD COLUMN "locationId" STRING NOT NULL;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE "Location" (
|
|
||||||
"id" STRING NOT NULL,
|
|
||||||
"city" STRING NOT NULL,
|
|
||||||
"stateOrProvince" STRING,
|
|
||||||
"country" STRING,
|
|
||||||
"coordinates" FLOAT8[],
|
|
||||||
"address" STRING NOT NULL,
|
|
||||||
"postedById" STRING NOT NULL,
|
|
||||||
|
|
||||||
CONSTRAINT "Location_pkey" PRIMARY KEY ("id")
|
|
||||||
);
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX "BreweryPost_locationId_key" ON "BreweryPost"("locationId");
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "Location" ADD CONSTRAINT "Location_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "Location"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "User" (
|
CREATE TABLE "User" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"username" STRING NOT NULL,
|
"username" TEXT NOT NULL,
|
||||||
"firstName" STRING NOT NULL,
|
"firstName" TEXT NOT NULL,
|
||||||
"lastName" STRING NOT NULL,
|
"lastName" TEXT NOT NULL,
|
||||||
"hash" STRING NOT NULL,
|
"hash" TEXT NOT NULL,
|
||||||
"email" STRING NOT NULL,
|
"email" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
"isAccountVerified" BOOL NOT NULL DEFAULT false,
|
"isAccountVerified" BOOLEAN NOT NULL DEFAULT false,
|
||||||
"dateOfBirth" TIMESTAMP(3) NOT NULL,
|
"dateOfBirth" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||||
@@ -16,14 +16,14 @@ CREATE TABLE "User" (
|
|||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BeerPost" (
|
CREATE TABLE "BeerPost" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"name" STRING NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
"ibu" FLOAT8 NOT NULL,
|
"ibu" DOUBLE PRECISION NOT NULL,
|
||||||
"abv" FLOAT8 NOT NULL,
|
"abv" DOUBLE PRECISION NOT NULL,
|
||||||
"description" STRING NOT NULL,
|
"description" TEXT NOT NULL,
|
||||||
"postedById" STRING NOT NULL,
|
"postedById" TEXT NOT NULL,
|
||||||
"breweryId" STRING NOT NULL,
|
"breweryId" TEXT NOT NULL,
|
||||||
"typeId" STRING NOT NULL,
|
"typeId" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
|
|
||||||
@@ -32,22 +32,33 @@ CREATE TABLE "BeerPost" (
|
|||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BeerPostLike" (
|
CREATE TABLE "BeerPostLike" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"beerPostId" STRING NOT NULL,
|
"beerPostId" TEXT NOT NULL,
|
||||||
"likedById" STRING NOT NULL,
|
"likedById" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
|
|
||||||
CONSTRAINT "BeerPostLike_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "BeerPostLike_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "BreweryPostLike" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"breweryPostId" TEXT NOT NULL,
|
||||||
|
"likedById" TEXT NOT NULL,
|
||||||
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
|
|
||||||
|
CONSTRAINT "BreweryPostLike_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BeerComment" (
|
CREATE TABLE "BeerComment" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"rating" INT4 NOT NULL,
|
"rating" INTEGER NOT NULL,
|
||||||
"beerPostId" STRING NOT NULL,
|
"beerPostId" TEXT NOT NULL,
|
||||||
"postedById" STRING NOT NULL,
|
"postedById" TEXT NOT NULL,
|
||||||
"content" STRING NOT NULL,
|
"content" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
|
|
||||||
@@ -56,35 +67,49 @@ CREATE TABLE "BeerComment" (
|
|||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BeerType" (
|
CREATE TABLE "BeerType" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"name" STRING NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
"postedById" STRING NOT NULL,
|
"postedById" TEXT NOT NULL,
|
||||||
|
|
||||||
CONSTRAINT "BeerType_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "BeerType_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Location" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"city" TEXT NOT NULL,
|
||||||
|
"stateOrProvince" TEXT,
|
||||||
|
"country" TEXT,
|
||||||
|
"coordinates" DOUBLE PRECISION[],
|
||||||
|
"address" TEXT NOT NULL,
|
||||||
|
"postedById" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Location_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BreweryPost" (
|
CREATE TABLE "BreweryPost" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"name" STRING NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
"location" STRING NOT NULL,
|
"locationId" TEXT NOT NULL,
|
||||||
"description" STRING NOT NULL,
|
"description" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
"postedById" STRING NOT NULL,
|
"postedById" TEXT NOT NULL,
|
||||||
|
"dateEstablished" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
CONSTRAINT "BreweryPost_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "BreweryPost_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BreweryComment" (
|
CREATE TABLE "BreweryComment" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"rating" INT4 NOT NULL,
|
"rating" INTEGER NOT NULL,
|
||||||
"breweryPostId" STRING NOT NULL,
|
"breweryPostId" TEXT NOT NULL,
|
||||||
"postedById" STRING NOT NULL,
|
"postedById" TEXT NOT NULL,
|
||||||
"content" STRING NOT NULL,
|
"content" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
|
|
||||||
@@ -93,28 +118,28 @@ CREATE TABLE "BreweryComment" (
|
|||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BeerImage" (
|
CREATE TABLE "BeerImage" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"beerPostId" STRING NOT NULL,
|
"beerPostId" TEXT NOT NULL,
|
||||||
"path" STRING NOT NULL,
|
"path" TEXT NOT NULL,
|
||||||
"alt" STRING NOT NULL,
|
"alt" TEXT NOT NULL,
|
||||||
"caption" STRING NOT NULL,
|
"caption" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
"postedById" STRING NOT NULL,
|
"postedById" TEXT NOT NULL,
|
||||||
|
|
||||||
CONSTRAINT "BeerImage_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "BeerImage_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
|
|
||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "BreweryImage" (
|
CREATE TABLE "BreweryImage" (
|
||||||
"id" STRING NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"breweryPostId" STRING NOT NULL,
|
"breweryPostId" TEXT NOT NULL,
|
||||||
"path" STRING NOT NULL,
|
"path" TEXT NOT NULL,
|
||||||
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updatedAt" TIMESTAMPTZ(3),
|
"updatedAt" TIMESTAMPTZ(3),
|
||||||
"caption" STRING NOT NULL,
|
"caption" TEXT NOT NULL,
|
||||||
"alt" STRING NOT NULL,
|
"alt" TEXT NOT NULL,
|
||||||
"postedById" STRING NOT NULL,
|
"postedById" TEXT NOT NULL,
|
||||||
|
|
||||||
CONSTRAINT "BreweryImage_pkey" PRIMARY KEY ("id")
|
CONSTRAINT "BreweryImage_pkey" PRIMARY KEY ("id")
|
||||||
);
|
);
|
||||||
@@ -125,6 +150,9 @@ CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
|
|||||||
-- CreateIndex
|
-- CreateIndex
|
||||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "BreweryPost_locationId_key" ON "BreweryPost"("locationId");
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "BeerPost" ADD CONSTRAINT "BeerPost_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "BeerPost" ADD CONSTRAINT "BeerPost_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
@@ -140,6 +168,12 @@ ALTER TABLE "BeerPostLike" ADD CONSTRAINT "BeerPostLike_beerPostId_fkey" FOREIGN
|
|||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "BeerPostLike" ADD CONSTRAINT "BeerPostLike_likedById_fkey" FOREIGN KEY ("likedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "BeerPostLike" ADD CONSTRAINT "BeerPostLike_likedById_fkey" FOREIGN KEY ("likedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_breweryPostId_fkey" FOREIGN KEY ("breweryPostId") REFERENCES "BreweryPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BreweryPostLike" ADD CONSTRAINT "BreweryPostLike_likedById_fkey" FOREIGN KEY ("likedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "BeerComment" ADD CONSTRAINT "BeerComment_beerPostId_fkey" FOREIGN KEY ("beerPostId") REFERENCES "BeerPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "BeerComment" ADD CONSTRAINT "BeerComment_beerPostId_fkey" FOREIGN KEY ("beerPostId") REFERENCES "BeerPost"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
@@ -149,6 +183,12 @@ ALTER TABLE "BeerComment" ADD CONSTRAINT "BeerComment_postedById_fkey" FOREIGN K
|
|||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "BeerType" ADD CONSTRAINT "BeerType_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "BeerType" ADD CONSTRAINT "BeerType_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Location" ADD CONSTRAINT "Location_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "Location"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "BreweryPost" ADD CONSTRAINT "BreweryPost_postedById_fkey" FOREIGN KEY ("postedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
# Please do not edit this file manually
|
# Please do not edit this file manually
|
||||||
# It should be added in your version-control system (i.e. Git)
|
# It should be added in your version-control system (i.e. Git)
|
||||||
provider = "cockroachdb"
|
provider = "postgresql"
|
||||||
@@ -6,8 +6,10 @@ generator client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
provider = "cockroachdb"
|
provider = "postgresql"
|
||||||
url = env("DATABASE_URL")
|
url = env("POSTGRES_PRISMA_URL") // uses connection pooling
|
||||||
|
directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
|
||||||
|
shadowDatabaseUrl = env("POSTGRES_URL_NON_POOLING") // used for migrations
|
||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import logger from '../../config/pino/logger';
|
|||||||
joinData: { beerPosts, users },
|
joinData: { beerPosts, users },
|
||||||
}),
|
}),
|
||||||
createNewBreweryPostComments({
|
createNewBreweryPostComments({
|
||||||
numberOfComments: 100000,
|
numberOfComments: 50000,
|
||||||
joinData: { breweryPosts, users },
|
joinData: { breweryPosts, users },
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
@@ -61,7 +61,7 @@ import logger from '../../config/pino/logger';
|
|||||||
|
|
||||||
const [beerPostLikes, breweryPostLikes] = await Promise.all([
|
const [beerPostLikes, breweryPostLikes] = await Promise.all([
|
||||||
createNewBeerPostLikes({
|
createNewBeerPostLikes({
|
||||||
numberOfLikes: 100000,
|
numberOfLikes: 500000,
|
||||||
joinData: { beerPosts, users },
|
joinData: { beerPosts, users },
|
||||||
}),
|
}),
|
||||||
createNewBreweryPostLikes({
|
createNewBreweryPostLikes({
|
||||||
@@ -77,7 +77,7 @@ import logger from '../../config/pino/logger';
|
|||||||
joinData: { beerPosts, users },
|
joinData: { beerPosts, users },
|
||||||
}),
|
}),
|
||||||
createNewBreweryImages({
|
createNewBreweryImages({
|
||||||
numberOfImages: 20000,
|
numberOfImages: 5000,
|
||||||
joinData: { breweryPosts, users },
|
joinData: { breweryPosts, users },
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user