Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,14 @@ SPONSORSHIP_PICTURE_BUCKET=exampleKey
WEBHOOK_SECRET=exampleKey
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=exampleKey
NEXT_PUBLIC_SUPABASE_ANON_KEY=exampleKey
NEXT_PUBLIC_SUPABASE_URL="https://bug-free-orbit-rq5vxrpqgv6357w9.github.dev/"
NEXT_PUBLIC_SUPABASE_URL="https://bug-free-orbit-rq5vxrpqgv6357w9.github.dev/"
NEXT_PUBLIC_TELEMETRY_SITE_URL=telemetrySiteUrl
NEXT_PUBLIC_GRAFANA_URL=grafanaSiteUrl
Comment thread
promatty marked this conversation as resolved.
DIRECT_URL="postgresql://postgres:password@localhost:5432/solar-car-website-next"

# If you run Postgres locally via `docker-compose up -d`, the example DATABASE_URL
# and DIRECT_URL above will work as-is. To create a local runtime env file from
# this example run:
#
# copy .env.example .env (PowerShell)
# cp .env.example .env (bash/WSL/git-bash)
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ yarn-error.log*
*.tsbuildinfo

# idea files
.idea
.idea

# clerk configuration (can include secrets)
/.clerk/
96 changes: 88 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ The Calgary Solar Car website leverages modern technologies to ensure a scalable

_For access to Clerk and Supabase, please contact the telemetry lead._ 🙋‍♂️

## ⚙️ Getting Started
## ⚙️ Local Development

Follow these steps to set up your local development environment:
Follow these steps to set up the app, database, and Clerk auth locally.

1. **Clone the Repository:**

Expand All @@ -58,28 +58,59 @@ Follow these steps to set up your local development environment:
corepack enable yarn
```

3. **Install Dependencies:**
3. **Start the Local Database:**

The repo includes a `docker-compose.yml` with a local Postgres instance for Prisma.

```bash
yarn install
docker-compose up -d
```

4. **Create Your Local Environment File:**

Copy `.env.example` to `.env` and fill in any secrets you need for Clerk, Supabase, and webhooks.

PowerShell:

```powershell
copy .env.example .env
```

bash / WSL / git-bash:

```bash
cp .env.example .env
```

4. **Obtain the Environment Configuration:**
5. **Install Dependencies:**

Copy the env variables from [Confluence](https://uofcsolarcar.atlassian.net/wiki/spaces/ST/pages/345931787/Solar+Car+Next+Website+Environment+Variables) or request the `.env` file from the telemetry lead.
```bash
yarn install
```

5. **Generate the Database Client:**
6. **Generate and Apply Prisma Migrations:**

```bash
yarn db:generate
yarn db:migrate-dev
```

7. **Seed the Database:**

The repo includes a Faker-powered seed script for local development data.

```bash
yarn db:seed
```

6. **Start the Development Server:**
8. **Start the Development Server:**

```bash
yarn dev
```

If `yarn dev` fails with a Clerk middleware error, check the auth middleware entrypoint in `src/proxy.ts` and make sure you are using the current Clerk packages.

## 🌐 Using Webhooks Locally

To ensure that Clerk syncs with our Supabase database, follow these steps for the first time while signing up on /portal locally.
Expand All @@ -92,6 +123,8 @@ To ensure that Clerk syncs with our Supabase database, follow these steps for th
yarn dev
```

If this is the first time you're signing up locally, the app needs Clerk middleware to be active in the auth middleware entrypoint (`src/proxy.ts`).

2. **Expose Your Localhost to the Internet:**

Open a new terminal window and create a tunnel using SSH:
Expand Down Expand Up @@ -141,3 +174,50 @@ To ensure that Clerk syncs with our Supabase database, follow these steps for th
We enforce strict code quality standards using **ESLint** and **Prettier**. Always run your linter and address any issues before merging your work.

Rebase your branch from main before opening a merge request, and make sure your branch is up to date before merging changes into main.

## 🗄️ Local Database (Docker Compose)

This repo includes a `docker-compose.yml` to run a local Postgres instance used by Prisma.

- Start Postgres in the background:

```bash
docker-compose up -d
```

- Create a local `.env` from the example (then edit secrets if needed):

PowerShell:
```powershell
copy .env.example .env
```

bash / WSL / git-bash:
```bash
cp .env.example .env
```

- Generate Prisma client and run migrations:

```bash
yarn install
yarn db:generate
yarn db:migrate-dev
```

- Open the Prisma Studio UI:

```bash
yarn db:studio
```

- Stop and remove containers when finished:

```bash
docker-compose down
```

Notes:

- The `.env.example` now includes `DIRECT_URL` which Prisma uses for `directUrl` (shadow/direct connections).
- If `env` validation blocks `yarn dev`, run with `SKIP_ENV_VALIDATION=1 yarn dev`.
16 changes: 16 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: "3.8"
services:
db:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: solar-car-website-next
ports:
- "5432:5432"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
volumes:
- db-data:/var/lib/postgresql/data

volumes:
db-data:
5 changes: 5 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ const config = {
hostname: "vxpityfkkkoyujulayck.supabase.co",
protocol: "https",
},
{
hostname: "picsum.photos",
protocol: "https",
},
],
},
reactCompiler: true,
reactStrictMode: true,
transpilePackages: ["geist"],
};
Expand Down
27 changes: 18 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@
"build": "next build",
"db:generate": "prisma generate",
"db:migrate:reset": "prisma migrate reset",
"db:migrate-dev": "prisma migrate dev",
"db:migrate-prod": "prisma migrate deploy",
"db:migrate:dev": "prisma migrate dev",
"db:migrate:prod": "prisma migrate deploy",
"db:pull": "prisma db pull",
"db:push": "prisma db push",
"db:seed": "prisma db seed",
"db:studio": "prisma studio",
"dev": "next dev --turbo",
"postinstall": "prisma generate",
"lint": "next lint",
"start": "next start"
},
"dependencies": {
"@clerk/nextjs": "^6.12.5",
"@clerk/nextjs": "^7.3.5",
"@flags-sdk/vercel": "1.3.0",
"@prisma/client": "^6.4.1",
"@supabase/supabase-js": "^2.45.4",
"@t3-oss/env-nextjs": "^0.10.1",
Expand All @@ -31,12 +33,13 @@
"axios": "^1.7.9",
"browser-image-compression": "^2.0.2",
"classnames": "^2.5.1",
"flags": "4.0.6",
"framer-motion": "^12.23.22",
"geist": "^1.3.0",
"next": "15.5.9",
"npm": "^10.9.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"next": "^16.1.6",
Comment thread
promatty marked this conversation as resolved.
"npm": "10.9.0",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-hot-toast": "^2.5.2",
"react-select": "^5.8.1",
"react-spinners": "^0.15.0",
Expand All @@ -47,13 +50,15 @@
"zod": "^3.23.3"
},
"devDependencies": {
"@faker-js/faker": "^8.0.2",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/eslint": "^8.56.10",
"@types/node": "^20.14.10",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react": "19.2.10",
"@types/react-dom": "19.2.3",
"@typescript-eslint/eslint-plugin": "^8.1.0",
"@typescript-eslint/parser": "^8.1.0",
"babel-plugin-react-compiler": "1.0.0",
"eslint": "^8.57.0",
"eslint-config-next": "15.5.9",
"eslint-config-prettier": "^9.1.0",
Expand All @@ -64,8 +69,12 @@
"prettier": "^3.3.3",
"prisma": "^6.4.1",
"sass": "^1.79.4",
"tsx": "^4.22.0",
"typescript": "^5.5.3"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"ct3aMetadata": {
"initVersion": "7.37.0"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
-- AlterEnum: replace legacy communications roles with Communications Co-Manager / Communications Associate
BEGIN;

ALTER TABLE "User" ALTER COLUMN "teamRole" TYPE TEXT USING ("teamRole"::text);

UPDATE "User"
SET "teamRole" = 'Communications Associate'
WHERE "teamRole" IN (
'Event Associate',
'Marketing Associate',
'Videographer',
'Marketing \& Events Associate'
);
Comment thread
promatty marked this conversation as resolved.

DROP TYPE "AllTeamRoles";

CREATE TYPE "AllTeamRoles" AS ENUM (
'Team Captain',
'Engineering Team Manager',
'Business Team Manager',
'Software Team Manager',
'Software Technical Manager',
'Embedded Team Lead',
'Telemetry Team Lead',
'Viscomm Team Lead',
'Embedded Team',
'Telemetry Team',
'Viscomm Team',
'Accounting Co-Manager',
'Assistant Accounting Manager',
'Accounting Analyst',
'Accounting Associate',
'Communications Manager',
'Communications Co-Manager',
'Communications Associate',
'Sponsorship Manager',
'Sponsorship Assistant Manager',
'Monetary Lead',
'In-Kind Lead',
'Sponsorship Associate',
'Electrical Manager',
'Electrical Co-Manager',
'Electrical Technical Manager',
'Arrays Lead',
'Energy Storage Lead',
'High Voltage Lead',
'Low Voltage Lead',
'Arrays Team',
'Energy Storage Team',
'High Voltage Team',
'Low Voltage Team',
'Electrical Team',
'Mechanical Manager',
'Mechanical Technical Manager',
'Suspension \& Steering Lead',
'Structures Lead',
'Electrical Integration Lead',
'Body \& Chassis Lead',
'Suspension \& Steering Team',
'Structures Team',
'Electrical Integration Team',
'Body \& Chassis Team',
'Multi Team'
);

ALTER TABLE "User" ALTER COLUMN "teamRole" TYPE "AllTeamRoles" USING ("teamRole"::"AllTeamRoles");

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "company" TEXT,
ADD COLUMN "companyTitle" TEXT,
ADD COLUMN "yearRetired" TEXT,
ALTER COLUMN "clerkUserId" DROP NOT NULL;
25 changes: 25 additions & 0 deletions prisma/migrations/20260517100001_migrate_alumni_data/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- Copy Alumni data into User
INSERT INTO "User" (
"firstName",
"lastName",
"profilePictureUrl",
"linkedIn",
"company",
"companyTitle",
"yearJoined" ,
"yearRetired",
"clerkUserId"
) SELECT
"firstName",
"lastName",
"profilePictureUrl",
"linkedIn",
"company",
"position",
"yearJoinedSolarCar",
"yearLeftSolarCar",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
NULL
FROM "Alumni";

-- DropTable
DROP TABLE "Alumni";
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-- Convert yearJoined and yearRetired from String to Date
-- Create new columns with Date type
ALTER TABLE "User" ADD COLUMN "yearJoined_new" DATE;
ALTER TABLE "User" ADD COLUMN "yearRetired_new" DATE;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

-- Migrate data: convert YYYY strings to Jan 1st of that year
UPDATE "User"
SET "yearJoined_new" = CASE
WHEN "yearJoined" IS NOT NULL AND "yearJoined" ~ '^\d{4}$'
THEN TO_DATE("yearJoined" || '-01-01', 'YYYY-MM-DD')
ELSE NULL
END;

UPDATE "User"
SET "yearRetired_new" = CASE
WHEN "yearRetired" IS NOT NULL AND "yearRetired" ~ '^\d{4}$'
THEN TO_DATE("yearRetired" || '-01-01', 'YYYY-MM-DD')
ELSE NULL
END;

-- Drop old columns
ALTER TABLE "User" DROP COLUMN "yearJoined";
ALTER TABLE "User" DROP COLUMN "yearRetired";

-- Rename new columns to original names
ALTER TABLE "User" RENAME COLUMN "yearJoined_new" TO "yearJoined";
ALTER TABLE "User" RENAME COLUMN "yearRetired_new" TO "yearRetired";
Loading