db/ fix DB env var name

This commit is contained in:
Leon van Zyl
2025-08-13 15:28:44 +02:00
parent 15a2efbd17
commit 955a14dfe5
8 changed files with 42 additions and 48 deletions

View File

@@ -51,7 +51,7 @@ Fill in your environment variables in the `.env` file:
```env ```env
# Database # Database
DATABASE_URL="postgresql://username:password@localhost:5432/your_database_name" POSTGRES_URL="postgresql://username:password@localhost:5432/your_database_name"
# Authentication - Better Auth # Authentication - Better Auth
BETTER_AUTH_SECRET="your-random-32-character-secret-key-here" BETTER_AUTH_SECRET="your-random-32-character-secret-key-here"
@@ -92,7 +92,7 @@ Your application will be available at [http://localhost:3000](http://localhost:3
2. Navigate to the **Storage** tab 2. Navigate to the **Storage** tab
3. Click **Create****Postgres** 3. Click **Create****Postgres**
4. Choose your database name and region 4. Choose your database name and region
5. Copy the `DATABASE_URL` from the `.env.local` tab 5. Copy the `POSTGRES_URL` from the `.env.local` tab
6. Add it to your `.env` file 6. Add it to your `.env` file
### Google OAuth Credentials ### Google OAuth Credentials
@@ -171,7 +171,7 @@ npm run db:reset # Reset database (drop all tables)
Ensure these are set in your production environment: Ensure these are set in your production environment:
- `DATABASE_URL` - Production PostgreSQL connection string - `POSTGRES_URL` - Production PostgreSQL connection string
- `BETTER_AUTH_SECRET` - Secure random 32+ character string - `BETTER_AUTH_SECRET` - Secure random 32+ character string
- `GOOGLE_CLIENT_ID` - Google OAuth Client ID - `GOOGLE_CLIENT_ID` - Google OAuth Client ID
- `GOOGLE_CLIENT_SECRET` - Google OAuth Client Secret - `GOOGLE_CLIENT_SECRET` - Google OAuth Client Secret

View File

@@ -1,10 +1,10 @@
import type { Config } from "drizzle-kit" import type { Config } from "drizzle-kit";
export default { export default {
dialect: "postgresql", dialect: "postgresql",
schema: "./src/lib/schema.ts", schema: "./src/lib/schema.ts",
out: "./drizzle", out: "./drizzle",
dbCredentials: { dbCredentials: {
url: process.env.DATABASE_URL!, url: process.env.POSTGRES_URL!,
}, },
} satisfies Config } satisfies Config;

View File

@@ -1,8 +1,9 @@
# Database # Database
DATABASE_URL= POSTGRES_URL=
# Authentication - Better Auth # Authentication - Better Auth
BETTER_AUTH_SECRET="yourauthsecretgoeshere" # Generate key using https://www.better-auth.com/docs/installation
BETTER_AUTH_SECRET=qtD4Ssa0t5jY7ewALgai97sKhAtn7Ysc
# Google OAuth (Get from Google Cloud Console) # Google OAuth (Get from Google Cloud Console)
GOOGLE_CLIENT_ID= GOOGLE_CLIENT_ID=

View File

@@ -5,7 +5,7 @@ type StatusLevel = "ok" | "warn" | "error";
interface DiagnosticsResponse { interface DiagnosticsResponse {
timestamp: string; timestamp: string;
env: { env: {
DATABASE_URL: boolean; POSTGRES_URL: boolean;
BETTER_AUTH_SECRET: boolean; BETTER_AUTH_SECRET: boolean;
GOOGLE_CLIENT_ID: boolean; GOOGLE_CLIENT_ID: boolean;
GOOGLE_CLIENT_SECRET: boolean; GOOGLE_CLIENT_SECRET: boolean;
@@ -29,7 +29,7 @@ interface DiagnosticsResponse {
export async function GET(req: Request) { export async function GET(req: Request) {
const env = { const env = {
DATABASE_URL: Boolean(process.env.DATABASE_URL), POSTGRES_URL: Boolean(process.env.POSTGRES_URL),
BETTER_AUTH_SECRET: Boolean(process.env.BETTER_AUTH_SECRET), BETTER_AUTH_SECRET: Boolean(process.env.BETTER_AUTH_SECRET),
GOOGLE_CLIENT_ID: Boolean(process.env.GOOGLE_CLIENT_ID), GOOGLE_CLIENT_ID: Boolean(process.env.GOOGLE_CLIENT_ID),
GOOGLE_CLIENT_SECRET: Boolean(process.env.GOOGLE_CLIENT_SECRET), GOOGLE_CLIENT_SECRET: Boolean(process.env.GOOGLE_CLIENT_SECRET),
@@ -41,7 +41,7 @@ export async function GET(req: Request) {
let dbConnected = false; let dbConnected = false;
let schemaApplied = false; let schemaApplied = false;
let dbError: string | undefined; let dbError: string | undefined;
if (env.DATABASE_URL) { if (env.POSTGRES_URL) {
try { try {
const [{ db }, { sql }, schema] = await Promise.all([ const [{ db }, { sql }, schema] = await Promise.all([
import("@/lib/db"), import("@/lib/db"),
@@ -65,7 +65,7 @@ export async function GET(req: Request) {
} else { } else {
dbConnected = false; dbConnected = false;
schemaApplied = false; schemaApplied = false;
dbError = "DATABASE_URL is not set"; dbError = "POSTGRES_URL is not set";
} }
// Auth route check: we consider the route responding if it returns any HTTP response // Auth route check: we consider the route responding if it returns any HTTP response
@@ -95,7 +95,7 @@ export async function GET(req: Request) {
const aiConfigured = env.OPENAI_API_KEY; // We avoid live-calling the AI provider here const aiConfigured = env.OPENAI_API_KEY; // We avoid live-calling the AI provider here
const overallStatus: StatusLevel = (() => { const overallStatus: StatusLevel = (() => {
if (!env.DATABASE_URL || !dbConnected || !schemaApplied) return "error"; if (!env.POSTGRES_URL || !dbConnected || !schemaApplied) return "error";
if (!authConfigured) return "error"; if (!authConfigured) return "error";
// AI is optional; warn if not configured // AI is optional; warn if not configured
if (!aiConfigured) return "warn"; if (!aiConfigured) return "warn";

View File

@@ -63,7 +63,7 @@ export default function Home() {
configure: configure:
</p> </p>
<ul className="text-sm text-muted-foreground space-y-1 list-disc list-inside"> <ul className="text-sm text-muted-foreground space-y-1 list-disc list-inside">
<li>DATABASE_URL (PostgreSQL connection string)</li> <li>POSTGRES_URL (PostgreSQL connection string)</li>
<li>GOOGLE_CLIENT_ID (OAuth credentials)</li> <li>GOOGLE_CLIENT_ID (OAuth credentials)</li>
<li>GOOGLE_CLIENT_SECRET (OAuth credentials)</li> <li>GOOGLE_CLIENT_SECRET (OAuth credentials)</li>
<li>OPENAI_API_KEY (for AI functionality)</li> <li>OPENAI_API_KEY (for AI functionality)</li>
@@ -86,22 +86,16 @@ export default function Home() {
<div className="p-4 border rounded-lg"> <div className="p-4 border rounded-lg">
<h4 className="font-medium mb-2">3. Try the features</h4> <h4 className="font-medium mb-2">3. Try the features</h4>
<div className="space-y-2"> <div className="space-y-2">
{(loading || !isAuthReady) ? ( {loading || !isAuthReady ? (
<Button <Button size="sm" className="w-full glow" disabled={true}>
size="sm"
className="w-full glow"
disabled={true}
>
View Dashboard View Dashboard
</Button> </Button>
) : ( ) : (
<Button asChild size="sm" className="w-full glow"> <Button asChild size="sm" className="w-full glow">
<Link href="/dashboard"> <Link href="/dashboard">View Dashboard</Link>
View Dashboard
</Link>
</Button> </Button>
)} )}
{(loading || !isAiReady) ? ( {loading || !isAiReady ? (
<Button <Button
variant="outline" variant="outline"
size="sm" size="sm"
@@ -117,9 +111,7 @@ export default function Home() {
size="sm" size="sm"
className="w-full" className="w-full"
> >
<Link href="/chat"> <Link href="/chat">Try AI Chat</Link>
Try AI Chat
</Link>
</Button> </Button>
)} )}
</div> </div>
@@ -139,20 +131,18 @@ export default function Home() {
<footer className="border-t py-8 text-center text-sm text-muted-foreground"> <footer className="border-t py-8 text-center text-sm text-muted-foreground">
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<p className="mb-2"> <p className="mb-2">Boilerplate template by Leon van Zyl</p>
Boilerplate template by Leon van Zyl
</p>
<p> <p>
Visit{" "} Visit{" "}
<a <a
href="https://youtube.com/@leonvanzyl" href="https://youtube.com/@leonvanzyl"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-primary hover:underline" className="text-primary hover:underline"
> >
@leonvanzyl on YouTube @leonvanzyl on YouTube
</a> </a>{" "}
{" "}for tutorials on using this template for tutorials on using this template
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button";
type DiagnosticsResponse = { type DiagnosticsResponse = {
timestamp: string; timestamp: string;
env: { env: {
DATABASE_URL: boolean; POSTGRES_URL: boolean;
BETTER_AUTH_SECRET: boolean; BETTER_AUTH_SECRET: boolean;
GOOGLE_CLIENT_ID: boolean; GOOGLE_CLIENT_ID: boolean;
GOOGLE_CLIENT_SECRET: boolean; GOOGLE_CLIENT_SECRET: boolean;
@@ -69,12 +69,12 @@ export function SetupChecklist() {
key: "env", key: "env",
label: "Environment variables", label: "Environment variables",
ok: ok:
!!data?.env.DATABASE_URL && !!data?.env.POSTGRES_URL &&
!!data?.env.BETTER_AUTH_SECRET && !!data?.env.BETTER_AUTH_SECRET &&
!!data?.env.GOOGLE_CLIENT_ID && !!data?.env.GOOGLE_CLIENT_ID &&
!!data?.env.GOOGLE_CLIENT_SECRET, !!data?.env.GOOGLE_CLIENT_SECRET,
detail: detail:
"Requires DATABASE_URL, BETTER_AUTH_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET", "Requires POSTGRES_URL, BETTER_AUTH_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET",
}, },
{ {
key: "db", key: "db",

View File

@@ -5,7 +5,7 @@ import { useEffect, useState } from "react";
type DiagnosticsResponse = { type DiagnosticsResponse = {
timestamp: string; timestamp: string;
env: { env: {
DATABASE_URL: boolean; POSTGRES_URL: boolean;
BETTER_AUTH_SECRET: boolean; BETTER_AUTH_SECRET: boolean;
GOOGLE_CLIENT_ID: boolean; GOOGLE_CLIENT_ID: boolean;
GOOGLE_CLIENT_SECRET: boolean; GOOGLE_CLIENT_SECRET: boolean;
@@ -51,7 +51,10 @@ export function useDiagnostics() {
fetchDiagnostics(); fetchDiagnostics();
}, []); }, []);
const isAuthReady = data?.auth.configured && data?.database.connected && data?.database.schemaApplied; const isAuthReady =
data?.auth.configured &&
data?.database.connected &&
data?.database.schemaApplied;
const isAiReady = data?.ai.configured; const isAiReady = data?.ai.configured;
return { return {
@@ -62,4 +65,4 @@ export function useDiagnostics() {
isAuthReady: Boolean(isAuthReady), isAuthReady: Boolean(isAuthReady),
isAiReady: Boolean(isAiReady), isAiReady: Boolean(isAiReady),
}; };
} }

View File

@@ -1,12 +1,12 @@
import { drizzle } from "drizzle-orm/postgres-js" import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres" import postgres from "postgres";
import * as schema from "./schema" import * as schema from "./schema";
const connectionString = process.env.DATABASE_URL as string const connectionString = process.env.POSTGRES_URL as string;
if (!connectionString) { if (!connectionString) {
throw new Error("DATABASE_URL environment variable is not set") throw new Error("POSTGRES_URL environment variable is not set");
} }
const client = postgres(connectionString) const client = postgres(connectionString);
export const db = drizzle(client, { schema }) export const db = drizzle(client, { schema });