diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 833f40e3..c57d889a 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -21,12 +21,10 @@ env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} CERTIFICATE_ARN: ${{ secrets.CERTIFICATE_ARN }} - DATABASE_URL: ${{ secrets.DATABASE_URL }} + DATABASE_URL: ${{ secrets.PROD_DB_URL }} jobs: deploy: - if: (!contains(github.event.pull_request.labels.*.name, 'no deploy')) - runs-on: ubuntu-latest environment: @@ -44,4 +42,4 @@ jobs: run: pnpm install --frozen-lockfile - name: Deploy ZotMeet to production - run: pnpm sst deploy --stage prod + run: pnpm migrate && pnpm sst deploy --stage prod diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 4ba0c361..095fbdc9 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -23,7 +23,7 @@ env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} CERTIFICATE_ARN: ${{ secrets.CERTIFICATE_ARN }} - DATABASE_URL: ${{ secrets.DATABASE_URL }} + DATABASE_URL: ${{ secrets.DEV_DB_URL }} PR_NUM: ${{ github.event.pull_request.number }} jobs: @@ -47,4 +47,4 @@ jobs: run: pnpm install --frozen-lockfile - name: Deploy ZotMeet to staging - run: pnpm sst deploy --stage staging-$PR_NUM + run: pnpm migrate && pnpm sst deploy --stage staging-$PR_NUM diff --git a/.github/workflows/destroy-staging.yml b/.github/workflows/destroy-staging.yml index b164c51f..cc3070b9 100644 --- a/.github/workflows/destroy-staging.yml +++ b/.github/workflows/destroy-staging.yml @@ -22,7 +22,7 @@ env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} CERTIFICATE_ARN: ${{ secrets.CERTIFICATE_ARN }} - DATABASE_URL: ${{ secrets.DATABASE_URL }} + DATABASE_URL: ${{ secrets.DEV_DB_URL }} PR_NUM: ${{ github.event.pull_request.number }} jobs: diff --git a/package.json b/package.json index 530ca325..6a083f8f 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "generate": "drizzle-kit generate:pg --config=drizzle.config.ts", "postinstall": "husky install && pnpm generate && svelte-kit sync", "lint": "eslint --quiet --fix .", - "migrate": "pnpm dlx tsx src/lib/db/migrate.ts", + "migrate": "pnpm tsx src/lib/db/migrate.ts", + "migrate:dev": "pnpm dotenv -- pnpm tsx src/lib/db/migrate.ts", "preview": "vite preview", "sst:deploy": "sst deploy", "sst:dev": "sst dev", @@ -30,12 +31,15 @@ "@lucia-auth/adapter-drizzle": "^1.0.3", "arctic": "^1.2.1", "clsx": "^2.1.0", + "dotenv": "^16.4.5", + "dotenv-cli": "^7.4.1", "drizzle-orm": "0.29.4", "lucia": "^3.1.1", "pg": "^8.11.3", "postgres": "3.4.3", "svelty-picker": "^5.2.1", "tailwind-merge": "^2.2.1", + "tsx": "^4.7.2", "unplugin-icons": "^0.18.1" }, "devDependencies": { @@ -59,7 +63,6 @@ "cz-conventional-changelog": "3.3.0", "daisyui": "^4.6.2", "devmoji": "2.3.0", - "dotenv": "^16.4.5", "drizzle-kit": "0.20.14", "eslint": "8.54.0", "eslint-config-prettier": "9.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1e888a24..d07a7d11 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,12 @@ dependencies: clsx: specifier: ^2.1.0 version: 2.1.0 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + dotenv-cli: + specifier: ^7.4.1 + version: 7.4.1 drizzle-orm: specifier: 0.29.4 version: 0.29.4(@aws-sdk/client-rds-data@3.533.0)(@types/pg@8.11.2)(kysely@0.25.0)(pg@8.11.3)(postgres@3.4.3)(react@18.2.0) @@ -35,6 +41,9 @@ dependencies: tailwind-merge: specifier: ^2.2.1 version: 2.2.1 + tsx: + specifier: ^4.7.2 + version: 4.7.2 unplugin-icons: specifier: ^0.18.1 version: 0.18.5 @@ -100,9 +109,6 @@ devDependencies: devmoji: specifier: 2.3.0 version: 2.3.0 - dotenv: - specifier: ^16.4.5 - version: 16.4.5 drizzle-kit: specifier: 0.20.14 version: 0.20.14 @@ -1664,6 +1670,7 @@ packages: /@babel/highlight@7.23.4: resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} + requiresBuild: true dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 @@ -2036,7 +2043,6 @@ packages: cpu: [ppc64] os: [aix] requiresBuild: true - dev: true optional: true /@esbuild/android-arm64@0.18.13: @@ -2063,7 +2069,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm@0.18.13: @@ -2090,7 +2095,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-x64@0.18.13: @@ -2117,7 +2121,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/darwin-arm64@0.18.13: @@ -2144,7 +2147,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-x64@0.18.13: @@ -2171,7 +2173,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-arm64@0.18.13: @@ -2198,7 +2199,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-x64@0.18.13: @@ -2225,7 +2225,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm64@0.18.13: @@ -2252,7 +2251,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm@0.18.13: @@ -2279,7 +2277,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ia32@0.18.13: @@ -2306,7 +2303,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-loong64@0.18.13: @@ -2333,7 +2329,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-mips64el@0.18.13: @@ -2360,7 +2355,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ppc64@0.18.13: @@ -2387,7 +2381,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-riscv64@0.18.13: @@ -2414,7 +2407,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-s390x@0.18.13: @@ -2441,7 +2433,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-x64@0.18.13: @@ -2468,7 +2459,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/netbsd-x64@0.18.13: @@ -2495,7 +2485,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: true optional: true /@esbuild/openbsd-x64@0.18.13: @@ -2522,7 +2511,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: true optional: true /@esbuild/sunos-x64@0.18.13: @@ -2549,7 +2537,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: true optional: true /@esbuild/win32-arm64@0.18.13: @@ -2576,7 +2563,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-ia32@0.18.13: @@ -2603,7 +2589,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-x64@0.18.13: @@ -2630,7 +2615,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /@eslint-community/eslint-utils@4.4.0(eslint@8.54.0): @@ -5246,7 +5230,7 @@ packages: resolution: {integrity: sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==} dependencies: leven: 2.1.0 - minimist: 1.2.6 + minimist: 1.2.8 /commitizen@4.3.0(@types/node@20.10.0)(typescript@5.3.2): resolution: {integrity: sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==} @@ -5752,10 +5736,24 @@ packages: is-obj: 2.0.0 dev: true + /dotenv-cli@7.4.1: + resolution: {integrity: sha512-fE1aywjRrWGxV3miaiUr3d2zC/VAiuzEGghi+QzgIA9fEf/M5hLMaRSXb4IxbUAwGmaLi0IozdZddnVU96acag==} + hasBin: true + dependencies: + cross-spawn: 7.0.3 + dotenv: 16.4.5 + dotenv-expand: 10.0.0 + minimist: 1.2.8 + dev: false + + /dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + dev: false + /dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} - dev: true /dreamopt@0.8.0: resolution: {integrity: sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==} @@ -5934,6 +5932,7 @@ packages: /error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + requiresBuild: true dependencies: is-arrayish: 0.2.1 dev: true @@ -6165,7 +6164,6 @@ packages: '@esbuild/win32-arm64': 0.19.12 '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 - dev: true /escalade@3.1.2: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} @@ -6856,7 +6854,6 @@ packages: resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} dependencies: resolve-pkg-maps: 1.0.0 - dev: true /git-hooks-list@3.1.0: resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==} @@ -7342,6 +7339,7 @@ packages: /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + requiresBuild: true dev: true /is-bigint@1.0.4: @@ -7665,6 +7663,7 @@ packages: /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + requiresBuild: true dev: true /json-schema-traverse@0.4.1: @@ -7673,6 +7672,7 @@ packages: /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + requiresBuild: true dev: true /json-schema-typed@7.0.3: @@ -8215,6 +8215,7 @@ packages: /minimist@1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + dev: true /minimist@1.2.7: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} @@ -8269,7 +8270,7 @@ packages: duplexify: 4.1.3 help-me: 3.0.0 inherits: 2.0.4 - minimist: 1.2.6 + minimist: 1.2.8 mqtt-packet: 6.10.0 pump: 3.0.0 readable-stream: 3.6.2 @@ -9146,6 +9147,7 @@ packages: /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + requiresBuild: true dev: true /pvtsutils@1.3.5: @@ -9317,6 +9319,7 @@ packages: /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + requiresBuild: true dev: true /resolve-dir@1.0.1: @@ -9346,7 +9349,6 @@ packages: /resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: true /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} @@ -10373,6 +10375,17 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + /tsx@4.7.2: + resolution: {integrity: sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + esbuild: 0.19.12 + get-tsconfig: 4.7.3 + optionalDependencies: + fsevents: 2.3.3 + dev: false + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} diff --git a/src/lib/db/postgres.ts b/src/lib/db/postgres.ts index 8f0795cb..dbaedd3a 100644 --- a/src/lib/db/postgres.ts +++ b/src/lib/db/postgres.ts @@ -7,5 +7,7 @@ import { DATABASE_URL } from "$env/static/private"; * so you will have to use this instead of the Drizzle client. * * In all other cases, you should probably not use this unless you know what you are doing. + * + * TODO: Check if this is still necessary considering our Lucia version */ export const client = postgres(DATABASE_URL, { max: 1, ssl: "prefer" }); diff --git a/src/lib/db/schema.ts b/src/lib/db/schema.ts index 163e4016..23d919ff 100644 --- a/src/lib/db/schema.ts +++ b/src/lib/db/schema.ts @@ -2,7 +2,6 @@ import { relations } from "drizzle-orm"; import { text, uuid, - pgSchema, timestamp, index, smallint, @@ -11,21 +10,20 @@ import { pgEnum, boolean, json, + pgTable, } from "drizzle-orm/pg-core"; -export const zotMeet = pgSchema("zotmeet"); - export const attendanceEnum = pgEnum("attendance", ["accepted", "maybe", "declined"]); export const memberEnum = pgEnum("member_type", ["guest", "user"]); // Members encompasses anyone who uses ZotMeet, regardless of guest or user status. -export const members = zotMeet.table("members", { +export const members = pgTable("members", { id: text("id").primaryKey(), type: memberEnum("type").notNull().default("guest"), }); // Users encompasses Members who have created an account. -export const users = zotMeet.table("users", { +export const users = pgTable("users", { id: text("id") .primaryKey() .references(() => members.id, { onDelete: "cascade" }), @@ -37,7 +35,7 @@ export const users = zotMeet.table("users", { }); // Guests are Members who do not have an account and are bound to one specific meeting. -export const guests = zotMeet.table( +export const guests = pgTable( "guests", { id: text("id").unique().notNull(), @@ -49,7 +47,7 @@ export const guests = zotMeet.table( }), ); -export const meetings = zotMeet.table("meetings", { +export const meetings = pgTable("meetings", { id: uuid("id").defaultRandom().primaryKey(), title: text("title").notNull(), description: text("description"), @@ -61,7 +59,7 @@ export const meetings = zotMeet.table("meetings", { host_id: text("host_id").references(() => members.id), }); -export const meetingDates = zotMeet.table( +export const meetingDates = pgTable( "meeting_dates", { id: uuid("id").unique().defaultRandom(), @@ -73,7 +71,7 @@ export const meetingDates = zotMeet.table( }), ); -export const groups = zotMeet.table("groups", { +export const groups = pgTable("groups", { id: uuid("id").defaultRandom().primaryKey(), name: text("name").notNull(), description: text("description"), @@ -81,7 +79,7 @@ export const groups = zotMeet.table("groups", { created_by: text("user_id").references(() => users.id), }); -export const availabilities = zotMeet.table( +export const availabilities = pgTable( "availabilities", { day: date("day").notNull(), @@ -99,7 +97,7 @@ export const availabilities = zotMeet.table( }), ); // meeting_day -export const oauthAccountsTable = zotMeet.table( +export const oauthAccountsTable = pgTable( "oauth_accounts", { userId: text("user_id") @@ -116,7 +114,7 @@ export const oauthAccountsTable = zotMeet.table( }), ); -export const sessions = zotMeet.table( +export const sessions = pgTable( "sessions", { id: text("id").primaryKey(), @@ -134,7 +132,7 @@ export const sessions = zotMeet.table( }; }, ); -export const usersInGroup = zotMeet.table( +export const usersInGroup = pgTable( "users_in_group", { userId: text("user_id") @@ -149,7 +147,7 @@ export const usersInGroup = zotMeet.table( }), ); -export const membersInMeeting = zotMeet.table( +export const membersInMeeting = pgTable( "members_in_meeting", { memberId: text("member_id")