diff --git a/.dockerignore b/.dockerignore
index 2a7a8de5..94f572d0 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -5,8 +5,17 @@ node_modules
/cdk
/docs
/tests
+/scripts
.vscode
+# ignore git
+.git*
+.github
+.git-hooks
+
+# no dotfiles in general
+.*
+
# no builds
**/build
@@ -20,4 +29,8 @@ node_modules
**/*.db
# ignore env files
-.env*
\ No newline at end of file
+.env*
+
+# take .turbo and .svelte-kit for build cache
+!.turbo
+!.svelte-kit
\ No newline at end of file
diff --git a/.env.sample b/.env.sample
index 8fc398b9..de342621 100644
--- a/.env.sample
+++ b/.env.sample
@@ -10,8 +10,8 @@ VITE_DISCORD_GUILD_ID=$DISCORD_GUILD_ID
DISCORD_AUTH_CLIENT_ID=$DISCORD_APP_ID
DISCORD_AUTH_CLIENT_SECRET=oauthclientsecret
-# Database URL for prisma (relative to prisma directory)
-DATABASE_URL="file:data/local.db"
+# Database URL for prisma (relative to prisma directory if using a file)
+DATABASE_URL="mysql://root:super-top-secret@localhost:3306/hey-amplify"
# GitHub->Discord release webhook
DISCORD_WEBHOOK_URL_RELEASES=discordwebhookurl
diff --git a/.gitignore b/.gitignore
index 4318309b..d2ce3030 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,16 +1,18 @@
+# general ignores
.DS_Store
node_modules
*.log
+# ignore all env files except the sample
.env
.env.*
!.env.sample
-cypress.env.json
+# notes
notes.md
-/prisma/data
-/.svelte-kit
-/build
+# ignore all build directories
+build
-packages/**/build
\ No newline at end of file
+# ignore all turbo dot-directories
+.turbo
\ No newline at end of file
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 00000000..e18e3b5a
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,4 @@
+node-version=18.14.1
+engine-strict=true
+
+init-license=Apache-2.0
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
index bc7eb587..e048c8ca 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v18.10.0
\ No newline at end of file
+v18.15.0
diff --git a/Dockerfile b/Dockerfile
index e7c76a0a..30d2bcb9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,49 +1,44 @@
#syntax=docker/dockerfile:1.4
-FROM --platform=linux/amd64 alpine as builder
-# Download the static build of Litestream directly into the path & make it executable.
-# This is done in the builder and copied as the chmod doubles the size.
-ADD https://github.com/benbjohnson/litestream/releases/download/v0.3.8/litestream-v0.3.8-linux-amd64-static.tar.gz /tmp/litestream.tar.gz
-RUN tar -C /usr/local/bin -xzf /tmp/litestream.tar.gz
-
-FROM --platform=linux/amd64 node:18-alpine
-WORKDIR /usr/src
-
-# @todo - remove this after upgrading prisma to ~4.8.0
-# https://github.com/prisma/prisma/issues/16553#issuecomment-1353302617
-RUN apk add --update --no-cache openssl1.1-compat
-
-# Copy executable & Litestream from builder.
-COPY --from=builder /usr/local/bin/litestream /usr/local/bin/litestream
-# Copy litestream config
-COPY scripts/litestream.yml /etc/litestream.yml
-
-# add bash
-RUN apk add bash
-
-# Create data directory (although this will likely be mounted too)
-RUN mkdir -p /data
-
+# ARG PLATFORM="linux/amd64"
+ARG NODE_VERSION="18.14.2"
+ARG ALPINE_VERSION="3.17"
+FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} as pnpm-builder
+ARG PNPM_VERSION="7.30.0"
+# for turbo - https://turbo.build/repo/docs/handbook/deploying-with-docker#example
+RUN apk add --no-cache libc6-compat
+RUN apk update
+WORKDIR /workspace
# Install pnpm
-ARG PNPM_VERSION=7.9.5
-RUN npm install --global pnpm@${PNPM_VERSION}
+RUN corepack enable && \
+ corepack prepare pnpm@${PNPM_VERSION} --activate
# pnpm fetch only requires lockfile, but we'll need to build workspaces
COPY pnpm*.yaml ./
-# RUN pnpm fetch
+COPY patches ./patches
+# mount pnpm store as cache & fetch dependencies
+RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm-store \
+ pnpm fetch
+
+# build workspace
+FROM pnpm-builder AS workspace
+WORKDIR /workspace
+ENV CI=true
# add project source to build
-ADD . .
-# install dependencies
-RUN pnpm install --frozen-lockfile
+COPY . ./
+# mount .env file
+RUN --mount=type=secret,id=env,required=true,target=/workspace/.env \
+ pnpm install --frozen-lockfile --offline --silent
+
+# @todo remove in favor of mounting .env?
# expose arguments for VITE environment variables
ARG VITE_HOST=http://localhost:3000
ARG VITE_NEXTAUTH_URL=http://localhost:3000
ARG VITE_DISCORD_GUILD_ID=976838371383083068
-ARG DATABASE_URL="file:/data/sqlite.db"
-# expose necessary env vars
-ENV PORT=3000
-# run build
-RUN pnpm run build:lib && pnpm run build
-# install production dependencies
-RUN pnpm install --frozen-lockfile --prod --ignore-scripts
-EXPOSE 3000
-CMD ["./scripts/start.sh"]
+# run build
+RUN --mount=type=secret,id=env,required=true,target=/workspace/.env \
+ pnpm run build
+# RUN pnpm run build
+# deploy app
+RUN pnpm --filter ./apps/bot.amplify.aws deploy ./build/bot.amplify.aws
+# deploy bot
+RUN pnpm --filter ./apps/discord-bot deploy ./build/discord-bot
\ No newline at end of file
diff --git a/README.md b/README.md
index eba97ac4..54ac2721 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,8 @@ This repository contains the source code for the [AWS Amplify Discord Server](ht
4. Run the application with `pnpm dev`
5. As the server owner navigate to `http://localhost:3000/`, log in, and visit `/admin` to configure the instance
+Once you are finished working with the Discord Bot you will want to stop the database container with `pnpm stop-db`
+
### Setting up a Discord Bot
diff --git a/apps/bot.amplify.aws/.gitignore b/apps/bot.amplify.aws/.gitignore
new file mode 100644
index 00000000..955fed86
--- /dev/null
+++ b/apps/bot.amplify.aws/.gitignore
@@ -0,0 +1 @@
+/.svelte-kit
\ No newline at end of file
diff --git a/apps/bot.amplify.aws/Dockerfile b/apps/bot.amplify.aws/Dockerfile
new file mode 100644
index 00000000..97e0ded1
--- /dev/null
+++ b/apps/bot.amplify.aws/Dockerfile
@@ -0,0 +1,9 @@
+# "workspace" is built from the project root, see "pnpm docker-build-workspace" in root package.json
+FROM workspace
+WORKDIR /app
+# copy built files
+COPY --from=workspace /workspace/build/bot.amplify.aws ./build
+# expose port
+EXPOSE 3000
+# start the app
+CMD ["pnpm", "run", "start"]
\ No newline at end of file
diff --git a/apps/bot.amplify.aws/package.json b/apps/bot.amplify.aws/package.json
new file mode 100644
index 00000000..1558bf1f
--- /dev/null
+++ b/apps/bot.amplify.aws/package.json
@@ -0,0 +1,60 @@
+{
+ "name": "@aws-amplify/discord-bot-frontend",
+ "type": "module",
+ "version": "2.0.0-next.0",
+ "license": "Apache-2.0",
+ "private": true,
+ "scripts": {
+ "start": "node ./build/index.js",
+ "dev": "vite",
+ "build": "vite build",
+ "test": "vitest",
+ "coverage": "vitest run --coverage",
+ "prepare": "svelte-kit sync"
+ },
+ "dependencies": {
+ "@auth/core": "^0.5.1",
+ "@auth/sveltekit": "^0.3.0",
+ "@aws-crypto/sha256-js": "^4.0.0",
+ "@carbon/styles": "^1.26.0",
+ "@discordjs/rest": "^1.7.0",
+ "@hey-amplify/discord": "workspace:*",
+ "@hey-amplify/prisma-client": "workspace:*",
+ "@next-auth/prisma-adapter": "^1.0.5",
+ "@octokit/auth-app": "^4.0.9",
+ "@octokit/graphql": "^5.0.5",
+ "@octokit/rest": "^19.0.7",
+ "cookie": "^0.5.0",
+ "discord-api-types": "^0.37.37",
+ "discord.js": "^14.9.0",
+ "fast-glob": "^3.2.12",
+ "fuzzy": "^0.1.3",
+ "svelte": "3.58.0",
+ "uuid": "^9.0.0",
+ "zod": "^3.21.4"
+ },
+ "devDependencies": {
+ "@carbon/charts": "^1.6.14",
+ "@carbon/charts-svelte": "^1.6.14",
+ "@hey-amplify/constants": "workspace:*",
+ "@hey-amplify/features": "workspace:*",
+ "@hey-amplify/github": "workspace:*",
+ "@hey-amplify/support": "workspace:*",
+ "@sveltejs/adapter-node": "1.2.3",
+ "@sveltejs/kit": "1.15.2",
+ "@types/cookie": "^0.5.1",
+ "@vitest/ui": "^0.29.8",
+ "carbon-components-svelte": "^0.73.5",
+ "carbon-icons-svelte": "^11.4.0",
+ "carbon-preprocess-svelte": "^0.9.1",
+ "d3": "^7.8.4",
+ "jsdom": "^21.1.1",
+ "svelte-check": "^3.2.0",
+ "svelte-preprocess": "^5.0.3",
+ "tslib": "^2.5.0",
+ "typescript": "^5.0.4",
+ "vite": "^4.2.1",
+ "vite-node": "^0.29.8",
+ "vitest": "^0.29.8"
+ }
+}
diff --git a/public/Discord-Logo-White.svg b/apps/bot.amplify.aws/public/Discord-Logo-White.svg
similarity index 100%
rename from public/Discord-Logo-White.svg
rename to apps/bot.amplify.aws/public/Discord-Logo-White.svg
diff --git a/public/favicon.png b/apps/bot.amplify.aws/public/favicon.png
similarity index 100%
rename from public/favicon.png
rename to apps/bot.amplify.aws/public/favicon.png
diff --git a/public/logo.svg b/apps/bot.amplify.aws/public/logo.svg
similarity index 100%
rename from public/logo.svg
rename to apps/bot.amplify.aws/public/logo.svg
diff --git a/src/app.css b/apps/bot.amplify.aws/src/app.css
similarity index 100%
rename from src/app.css
rename to apps/bot.amplify.aws/src/app.css
diff --git a/src/app.d.ts b/apps/bot.amplify.aws/src/app.d.ts
similarity index 62%
rename from src/app.d.ts
rename to apps/bot.amplify.aws/src/app.d.ts
index 6b3a4d62..b0f86ef0 100644
--- a/src/app.d.ts
+++ b/apps/bot.amplify.aws/src/app.d.ts
@@ -1,17 +1,17 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
///