Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=
NEXT_PUBLIC_POSTHOG_HOST=

# ------------------------------------------------------------------
# Supabase (optional)
# These are OPTIONAL. When unset the app uses placeholder values and
# runs normally β€” waitlist submissions will simply not be persisted.
#
# For local development with a real database:
# 1. Install Docker Desktop and make sure it is running.
# 2. Run `npm run db:start` β€” it prints the credentials below.
# 3. Copy the printed values into a `.env.local` file.
# ------------------------------------------------------------------
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ yarn-error.log*

# env files (can opt-in for committing if needed)
.env
.env.local
.env*.local

# vercel
.vercel

# supabase
supabase/.temp/

# typescript
*.tsbuildinfo
next-env.d.ts
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ ACTA Web provides a sophisticated frontend experience for managing verifiable cr
- Node.js 18 or higher
- npm or yarn package manager
- Modern browser with WebAuthn support
- **Docker Desktop** (optional β€” required only for local Supabase database)
- **Supabase CLI** (optional β€” `npm i -g supabase` or use via `npx supabase`)

> **Note:** Docker and Supabase CLI are only needed if you want a local database for waitlist persistence. Without them, the app runs normally using placeholder credentials β€” waitlist submissions will simply not be stored.

### Installation

Expand Down Expand Up @@ -109,6 +113,65 @@ NEXT_PUBLIC_ENABLE_PASSKEY=true
NEXT_PUBLIC_ENABLE_PARTICLES=true
```

### Local Supabase (Docker) β€” Optional

The project includes a full local Supabase setup for waitlist persistence. **This is entirely optional.** When Supabase environment variables are missing or contain placeholder values, the app starts normally and the waitlist form submits without errors (requests simply won't be persisted).
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟑 Minor

Soften the β€œsubmits without errors” guarantee.

The current text over-promises behavior when Supabase is unconfigured. Prefer wording that guarantees app startup, but not guaranteed waitlist persistence/success response.

πŸ“ Suggested wording
-The project includes a full local Supabase setup for waitlist persistence. **This is entirely optional.** When Supabase environment variables are missing or contain placeholder values, the app starts normally and the waitlist form submits without errors (requests simply won't be persisted).
+The project includes a full local Supabase setup for waitlist persistence. **This is entirely optional.** When Supabase environment variables are missing or contain placeholder values, the app starts normally, but waitlist requests may fail or be non-persistent until Supabase is configured.
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The project includes a full local Supabase setup for waitlist persistence. **This is entirely optional.** When Supabase environment variables are missing or contain placeholder values, the app starts normally and the waitlist form submits without errors (requests simply won't be persisted).
The project includes a full local Supabase setup for waitlist persistence. **This is entirely optional.** When Supabase environment variables are missing or contain placeholder values, the app starts normally, but waitlist requests may fail or be non-persistent until Supabase is configured.
πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 118, The README currently over-promises that the waitlist
form "submits without errors" when Supabase env vars are missing; change the
sentence to guarantee only that the app will start and the waitlist form will be
available, but that persistence and successful responses are not guaranteed β€”
e.g., replace the clause "the waitlist form submits without errors (requests
simply won't be persisted)" with wording that the form may attempt submission
but requests may not be saved and may return errors or no-op when Supabase is
unconfigured.


#### Quick start

1. **Install & start Docker Desktop** β€” make sure the Docker engine is running.
2. **Start Supabase locally:**

```bash
npm run db:start
```

This pulls the Supabase Docker images (first run takes a few minutes) and prints the local credentials, including `API URL`, `anon key`, and `service_role key`.

3. **Copy the printed credentials into `.env.local`:**

```env
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=<anon key from db:start>
SUPABASE_SERVICE_ROLE_KEY=<service_role key from db:start>
```

4. **Run migrations and seed:**

```bash
npm run db:reset
```

This applies all migrations in `supabase/migrations/` and runs `supabase/seed.sql`, which inserts 8 sample waitlist rows.

5. **Start the dev server:**

```bash
npm run dev
```

#### Available database scripts

| Script | Command | Description |
| ----------------------------- | ------------------------ | ----------------------------------------- |
| `npm run db:start` | `supabase start` | Start local Supabase (Docker containers) |
| `npm run db:stop` | `supabase stop` | Stop local Supabase |
| `npm run db:reset` | `supabase db reset` | Drop & recreate DB, run migrations + seed |
| `npm run db:migration <name>` | `supabase migration new` | Create a new blank migration file |

#### Supabase Studio

When Supabase is running locally, you can access **Supabase Studio** at [http://127.0.0.1:54323](http://127.0.0.1:54323) to browse tables, run SQL, and inspect data.

#### Credential fallbacks

The Supabase client (`src/lib/supabase.ts`) is designed to be resilient:

- If `NEXT_PUBLIC_SUPABASE_URL` is missing or contains `"your_supabase"` / `"placeholder"`, a safe placeholder URL is used.
- If `NEXT_PUBLIC_SUPABASE_ANON_KEY` is missing, a placeholder JWT is used.
- If `SUPABASE_SERVICE_ROLE_KEY` is missing, the server falls back to the anon client and logs a warning.
- **The app never throws at startup** regardless of whether Supabase env vars are set.

### Development

```bash
Expand Down
128 changes: 126 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
"lint:check": "eslint . --ext .js,.jsx,.ts,.tsx",
"format": "prettier --write .",
"format:check": "prettier --check .",
"prepare": "husky"
"prepare": "husky",
"db:start": "npx supabase start",
"db:stop": "npx supabase stop",
"db:reset": "npx supabase db reset",
"db:migration": "npx supabase migration new"
},
"dependencies": {
"@radix-ui/react-accordion": "^1.2.12",
Expand Down Expand Up @@ -40,6 +44,7 @@
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@supabase/supabase-js": "^2.97.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
Expand Down
33 changes: 33 additions & 0 deletions src/lib/supabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { createClient, type SupabaseClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
Comment on lines +3 to +5
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | πŸ”΄ Critical

🧩 Analysis chain

🏁 Script executed:

cat -n src/lib/supabase.ts

Repository: ACTA-Team/website

Length of output: 1249


🏁 Script executed:

# Search for env var setup/validation
rg -i 'NEXT_PUBLIC_SUPABASE' --type js --type ts -B2 -A2 | head -50

# Check for any error handling around supabase
rg -i 'supabase.*try|catch.*supabase' --type js --type ts

# Look for .env setup or validation
fd -e '.env*' -o -e '*env*' -type f | grep -v node_modules

Repository: ACTA-Team/website

Length of output: 900


🏁 Script executed:

# Find env files more simply
find . -name ".env*" -type f 2>/dev/null | head -20

# Look for README or setup docs
find . -iname "readme*" -o -iname "setup*" -type f | head -10

# Check package.json for supabase version
rg '"@supabase' package.json

# Search for any guards around supabase initialization
rg -i 'optional.*supabase|supabase.*optional' --type md --type ts --type js -C2

Repository: ACTA-Team/website

Length of output: 1064


🏁 Script executed:

cat -n .env.example

# Also check if there's any existing placeholder handling in the codebase
rg -i 'placeholder' --type ts --type js

Repository: ACTA-Team/website

Length of output: 4243


createClient initialized with unchecked env vars breaks documented "optional Supabase" behavior.

The non-null assertions on lines 3–4 don't protect runtime values. According to .env.example and README.md, the app should run normally with placeholder values when Supabase env vars are missing, but the current code will fail at module import time if NEXT_PUBLIC_SUPABASE_URL or NEXT_PUBLIC_SUPABASE_ANON_KEY are undefined. Additionally, getServiceSupabase() (line 23) should log a warning when SUPABASE_SERVICE_ROLE_KEY is absent, matching the documented graceful fallback behavior.

Proposed fix
 import { createClient, type SupabaseClient } from "@supabase/supabase-js";
 
-const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
-const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
+const PLACEHOLDER_SUPABASE_URL = "https://placeholder.supabase.co";
+const PLACEHOLDER_ANON_KEY = "PLACEHOLDER_ANON_KEY_NOT_A_JWT";
+
+const rawSupabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL?.trim();
+const rawSupabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY?.trim();
 const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
+
+const supabaseUrl =
+  rawSupabaseUrl && !rawSupabaseUrl.includes("your_supabase") && !rawSupabaseUrl.includes("placeholder")
+    ? rawSupabaseUrl
+    : PLACEHOLDER_SUPABASE_URL;
+
+const supabaseAnonKey = rawSupabaseAnonKey || PLACEHOLDER_ANON_KEY;
 
 /**
  * Public (anon) Supabase client – safe to use in both client and server code.
  * Requires NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY in env.
@@
 export function getServiceSupabase(): SupabaseClient {
   if (!serviceRoleKey) {
+    console.warn(
+      "[supabase] SUPABASE_SERVICE_ROLE_KEY is missing; falling back to anon client."
+    );
     return supabase;
   }
πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/supabase.ts` around lines 3 - 5, Remove the non-null assertions on
NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY and ensure
createClient is not invoked with undefined at module import: read supabaseUrl
and supabaseAnonKey without "!" and either default them to empty strings or only
call createClient when both values are present so the module can load with
placeholders; also update getServiceSupabase to check serviceRoleKey and log a
warning via the existing logger when SUPABASE_SERVICE_ROLE_KEY is missing before
attempting to create the service client. Reference: supabaseUrl,
supabaseAnonKey, serviceRoleKey, createClient, and getServiceSupabase.


/**
* Public (anon) Supabase client – safe to use in both client and server code.
* Requires NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY in env.
*/
export const supabase: SupabaseClient = createClient(
supabaseUrl,
supabaseAnonKey
);

/**
* Server-only Supabase client with the service-role key.
* Uses anon client when SUPABASE_SERVICE_ROLE_KEY is not set.
*
* **Never import this in client components / bundles.**
*/
export function getServiceSupabase(): SupabaseClient {
if (!serviceRoleKey) {
return supabase;
}

return createClient(supabaseUrl, serviceRoleKey, {
auth: {
autoRefreshToken: false,
persistSession: false,
},
});
}
8 changes: 8 additions & 0 deletions supabase/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Supabase
.branches
.temp

# dotenvx
.env.keys
.env.local
.env.*.local
Loading