From abc1963aea89e39fa0e711483ea94db9a8da1f64 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 18:23:47 -0700 Subject: [PATCH 1/7] feat: add database test safety configuration --- package.json | 8 +++--- playwright.config.ts | 2 +- scripts/check-test-records.js | 14 ++++++++-- scripts/cleanup-prod-db.js | 14 ++++++++-- scripts/reset-dev-db.js | 26 +++++++++++++----- src/__tests__/e2e/global.setup.ts | 29 +++++++++++++++++--- vitest.setup.ts | 44 +++++++++++++++++++++++++++++++ 7 files changed, 120 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index f041b93..4756f06 100644 --- a/package.json +++ b/package.json @@ -7,16 +7,18 @@ "build": "next build", "start": "next start", "lint": "eslint", - "test": "vitest", - "test:run": "vitest run", + "test": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" vitest", + "test:run": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" vitest run", "test:acceptance": "playwright test src/__tests__/e2e/", "test:acceptance:headed": "playwright test src/__tests__/e2e/ --headed", "db:switch": "node scripts/switch-database.js", "db:setup-postgres": "node scripts/setup-postgres.js", "db:setup-dev": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" node scripts/setup-postgres.js", "db:setup-dev:clean": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" node scripts/setup-postgres.js --drop", - "db:reset-dev": "node scripts/reset-dev-db.js", + "db:reset-dev": "DEV_DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" node scripts/reset-dev-db.js", "db:use-dev": "node scripts/use-dev-db.js", + "db:cleanup-prod": "PROD_DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp\" node scripts/cleanup-prod-db.js", + "db:check-prod": "PROD_DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp\" node scripts/check-test-records.js", "db:cleanup-prod": "node scripts/cleanup-prod-db.js", "db:seed": "node scripts/seed.js", "docker:up": "docker-compose up -d", diff --git a/playwright.config.ts b/playwright.config.ts index d4c8ea2..f532df6 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -66,7 +66,7 @@ export default defineConfig({ ], // Run your local dev server before starting the tests webServer: { - command: 'npm run dev', + command: 'DATABASE_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev" npm run dev', url: 'http://localhost:3000', timeout: 120000, reuseExistingServer: !process.env.CI, diff --git a/scripts/check-test-records.js b/scripts/check-test-records.js index 2d8185b..00f6699 100755 --- a/scripts/check-test-records.js +++ b/scripts/check-test-records.js @@ -7,8 +7,18 @@ const { execSync } = require('child_process'); -// Database connection string -const DB_URL = 'postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp'; +// Database connection string - use environment variable or default to production +const DB_URL = process.env.PROD_DATABASE_URL || + process.env.DATABASE_URL || + 'postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp'; + +// Validate that we're not accidentally using dev database +if (DB_URL.includes('_dev') || DB_URL.includes('_dev_')) { + console.error('❌ ERROR: This script should not be used with the development database!'); + console.error(' Current DATABASE_URL:', DB_URL); + console.error(' Please set PROD_DATABASE_URL for production database operations.'); + process.exit(1); +} // Helper to run SQL and log results function runSQL(sql, description) { diff --git a/scripts/cleanup-prod-db.js b/scripts/cleanup-prod-db.js index aa0afdb..46f2ac3 100755 --- a/scripts/cleanup-prod-db.js +++ b/scripts/cleanup-prod-db.js @@ -10,8 +10,18 @@ const { execSync } = require('child_process'); -// Database connection string -const DB_URL = 'postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp'; +// Database connection string - use environment variable or default to production +const DB_URL = process.env.PROD_DATABASE_URL || + process.env.DATABASE_URL || + 'postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp'; + +// Validate that we're not accidentally using dev database +if (DB_URL.includes('_dev') || DB_URL.includes('_dev_')) { + console.error('❌ ERROR: This script should not be used with the development database!'); + console.error(' Current DATABASE_URL:', DB_URL); + console.error(' Please set PROD_DATABASE_URL for production database operations.'); + process.exit(1); +} // Helper to run SQL and log results function runSQL(sql, description) { diff --git a/scripts/reset-dev-db.js b/scripts/reset-dev-db.js index c3a1540..3ee4f19 100755 --- a/scripts/reset-dev-db.js +++ b/scripts/reset-dev-db.js @@ -11,21 +11,35 @@ const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); -// Load environment variables +// Load environment variables - prioritize explicit DEV_DATABASE_URL +// Falls back to DATABASE_URL, then .env.development const envPath = path.resolve(__dirname, '..', '.env.development'); if (fs.existsSync(envPath)) { require('dotenv').config({ path: envPath }); } -// Check if DATABASE_URL is set -if (!process.env.DATABASE_URL) { - console.error('❌ DATABASE_URL is not set'); - console.error('Please set it in .env.development'); +// Use DEV_DATABASE_URL if set, otherwise use DATABASE_URL +const databaseUrl = process.env.DEV_DATABASE_URL || process.env.DATABASE_URL; + +// Check if database URL is set +if (!databaseUrl) { + console.error('❌ No database URL set'); + console.error('Please set DEV_DATABASE_URL or DATABASE_URL environment variable'); + console.error('Or ensure .env.development file exists with DATABASE_URL'); + process.exit(1); +} + +// Validate that we're using the dev database +if (!databaseUrl.includes('_dev') && !databaseUrl.includes('_dev_')) { + console.error('❌ ERROR: This script should only be used with the development database!'); + console.error(' Current URL:', databaseUrl); + console.error(' Expected pattern: euchre_camp_dev'); + console.error(' Please set DEV_DATABASE_URL for development database operations.'); process.exit(1); } // Extract database name from URL -const dbUrl = process.env.DATABASE_URL; +const dbUrl = databaseUrl; const dbName = dbUrl.split('/').pop(); console.log('🔄 Resetting development database...\n'); diff --git a/src/__tests__/e2e/global.setup.ts b/src/__tests__/e2e/global.setup.ts index 89ab771..f69f946 100644 --- a/src/__tests__/e2e/global.setup.ts +++ b/src/__tests__/e2e/global.setup.ts @@ -16,11 +16,34 @@ function isDevDatabase(): boolean { return dbUrl.includes('euchre_camp_dev'); } -// Warn if not using dev database +function isProductionDatabase(): boolean { + const dbUrl = process.env.DATABASE_URL || ''; + return dbUrl.includes('euchre_camp') && !dbUrl.includes('_dev'); +} + +// Strict check - fail if using production database +if (isProductionDatabase()) { + console.error(''); + console.error('='.repeat(80)); + console.error('CRITICAL ERROR: Tests are attempting to run against PRODUCTION database!'); + console.error('='.repeat(80)); + console.error(''); + console.error('Current DATABASE_URL:', process.env.DATABASE_URL); + console.error(''); + console.error('Tests MUST run against the development database (euchre_camp_dev)'); + console.error(''); + console.error('To fix this:'); + console.error(' 1. Run: npm run test:acceptance'); + console.error(' 2. Or set: DATABASE_URL="postgresql://euchre_camp:password@dhg.lol:5432/euchre_camp_dev"'); + console.error(''); + console.error('Aborting test execution to prevent data corruption.'); + console.error(''); + process.exit(1); +} + if (!isDevDatabase()) { - console.warn('⚠️ WARNING: Not using dev database!'); + console.warn('⚠️ WARNING: DATABASE_URL does not contain euchre_camp_dev'); console.warn(' Current DATABASE_URL:', process.env.DATABASE_URL); - console.warn(' Expected to contain: euchre_camp_dev'); } export default async function globalSetup(config: FullConfig) { diff --git a/vitest.setup.ts b/vitest.setup.ts index c44951a..7ebc2ac 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -1 +1,45 @@ import '@testing-library/jest-dom' + +/** + * Vitest Setup File + * + * This file runs before each test file in the Vitest environment. + * It validates that tests are running against the development database + * to prevent accidental data corruption. + */ + +// Check if DATABASE_URL is set and points to dev database +const databaseUrl = process.env.DATABASE_URL; + +if (databaseUrl) { + const isDevDatabase = databaseUrl.includes('euchre_camp_dev'); + const isProductionDatabase = + databaseUrl.includes('euchre_camp') && + !databaseUrl.includes('_dev') && + !databaseUrl.includes('_dev_'); + + if (isProductionDatabase) { + console.error(''); + console.error('='.repeat(80)); + console.error('CRITICAL ERROR: Tests are attempting to run against PRODUCTION database!'); + console.error('='.repeat(80)); + console.error(''); + console.error('Current DATABASE_URL:', databaseUrl); + console.error(''); + console.error('Tests MUST run against the development database (euchre_camp_dev)'); + console.error(''); + console.error('To fix this:'); + console.error(' 1. Run: npm run test:run'); + console.error(' 2. Or set: DATABASE_URL="postgresql://euchre_camp:password@dhg.lol:5432/euchre_camp_dev"'); + console.error(''); + console.error('Aborting test execution to prevent data corruption.'); + console.error(''); + process.exit(1); + } + + if (isDevDatabase) { + console.log('✓ Tests running against development database (euchre_camp_dev)'); + } +} else { + console.warn('⚠ No DATABASE_URL set - tests may fail or use unexpected database'); +} From a9fc5c312abf8b3b3c4a54bb808baa60577eef0e Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 18:24:53 -0700 Subject: [PATCH 2/7] fix: set DATABASE_URL for acceptance tests --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4756f06..32ddfc2 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "lint": "eslint", "test": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" vitest", "test:run": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" vitest run", - "test:acceptance": "playwright test src/__tests__/e2e/", - "test:acceptance:headed": "playwright test src/__tests__/e2e/ --headed", + "test:acceptance": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" playwright test src/__tests__/e2e/", + "test:acceptance:headed": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" playwright test src/__tests__/e2e/ --headed", "db:switch": "node scripts/switch-database.js", "db:setup-postgres": "node scripts/setup-postgres.js", "db:setup-dev": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" node scripts/setup-postgres.js", From 4e112c92aed0aeaeb2c00c533be2c2e3998e85c0 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 18:28:17 -0700 Subject: [PATCH 3/7] fix: remove hardcoded database URLs and use environment variables --- package.json | 17 ++++++++--------- scripts/check-test-records.js | 14 ++++++++++---- scripts/cleanup-prod-db.js | 14 ++++++++++---- scripts/setup-postgres.js | 6 +++++- src/__tests__/e2e/global.setup.ts | 7 ++++--- vitest.setup.ts | 3 ++- 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 32ddfc2..96018d1 100644 --- a/package.json +++ b/package.json @@ -7,19 +7,18 @@ "build": "next build", "start": "next start", "lint": "eslint", - "test": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" vitest", - "test:run": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" vitest run", - "test:acceptance": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" playwright test src/__tests__/e2e/", - "test:acceptance:headed": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" playwright test src/__tests__/e2e/ --headed", + "test": "vitest", + "test:run": "vitest run", + "test:acceptance": "playwright test src/__tests__/e2e/", + "test:acceptance:headed": "playwright test src/__tests__/e2e/ --headed", "db:switch": "node scripts/switch-database.js", "db:setup-postgres": "node scripts/setup-postgres.js", - "db:setup-dev": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" node scripts/setup-postgres.js", - "db:setup-dev:clean": "DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" node scripts/setup-postgres.js --drop", - "db:reset-dev": "DEV_DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev\" node scripts/reset-dev-db.js", + "db:setup-dev": "node scripts/setup-postgres.js", + "db:setup-dev:clean": "node scripts/setup-postgres.js --drop", + "db:reset-dev": "node scripts/reset-dev-db.js", "db:use-dev": "node scripts/use-dev-db.js", - "db:cleanup-prod": "PROD_DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp\" node scripts/cleanup-prod-db.js", - "db:check-prod": "PROD_DATABASE_URL=\"postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp\" node scripts/check-test-records.js", "db:cleanup-prod": "node scripts/cleanup-prod-db.js", + "db:check-prod": "node scripts/check-test-records.js", "db:seed": "node scripts/seed.js", "docker:up": "docker-compose up -d", "docker:down": "docker-compose down", diff --git a/scripts/check-test-records.js b/scripts/check-test-records.js index 00f6699..5bd9aaa 100755 --- a/scripts/check-test-records.js +++ b/scripts/check-test-records.js @@ -7,10 +7,16 @@ const { execSync } = require('child_process'); -// Database connection string - use environment variable or default to production -const DB_URL = process.env.PROD_DATABASE_URL || - process.env.DATABASE_URL || - 'postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp'; +// Database connection string - must be explicitly set via environment variable +const DB_URL = process.env.PROD_DATABASE_URL || process.env.DATABASE_URL; + +// Check if database URL is set +if (!DB_URL) { + console.error('❌ No database URL set'); + console.error('Please set PROD_DATABASE_URL or DATABASE_URL environment variable'); + console.error('For production: PROD_DATABASE_URL="postgresql://user:pass@host:port/dbname"'); + process.exit(1); +} // Validate that we're not accidentally using dev database if (DB_URL.includes('_dev') || DB_URL.includes('_dev_')) { diff --git a/scripts/cleanup-prod-db.js b/scripts/cleanup-prod-db.js index 46f2ac3..c8fa0fa 100755 --- a/scripts/cleanup-prod-db.js +++ b/scripts/cleanup-prod-db.js @@ -10,10 +10,16 @@ const { execSync } = require('child_process'); -// Database connection string - use environment variable or default to production -const DB_URL = process.env.PROD_DATABASE_URL || - process.env.DATABASE_URL || - 'postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp'; +// Database connection string - must be explicitly set via environment variable +const DB_URL = process.env.PROD_DATABASE_URL || process.env.DATABASE_URL; + +// Check if database URL is set +if (!DB_URL) { + console.error('❌ No database URL set'); + console.error('Please set PROD_DATABASE_URL or DATABASE_URL environment variable'); + console.error('For production: PROD_DATABASE_URL="postgresql://user:pass@host:port/dbname"'); + process.exit(1); +} // Validate that we're not accidentally using dev database if (DB_URL.includes('_dev') || DB_URL.includes('_dev_')) { diff --git a/scripts/setup-postgres.js b/scripts/setup-postgres.js index 3e2a680..51aee6e 100755 --- a/scripts/setup-postgres.js +++ b/scripts/setup-postgres.js @@ -9,8 +9,12 @@ const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); -// Load .env file if it exists +// Load .env.development file first (if it exists), then .env file +const envDevPath = path.resolve(__dirname, '..', '.env.development'); const envPath = path.resolve(__dirname, '..', '.env'); +if (fs.existsSync(envDevPath)) { + require('dotenv').config({ path: envDevPath }); +} if (fs.existsSync(envPath)) { require('dotenv').config({ path: envPath }); } diff --git a/src/__tests__/e2e/global.setup.ts b/src/__tests__/e2e/global.setup.ts index f69f946..c7d808c 100644 --- a/src/__tests__/e2e/global.setup.ts +++ b/src/__tests__/e2e/global.setup.ts @@ -32,9 +32,10 @@ if (isProductionDatabase()) { console.error(''); console.error('Tests MUST run against the development database (euchre_camp_dev)'); console.error(''); - console.error('To fix this:'); - console.error(' 1. Run: npm run test:acceptance'); - console.error(' 2. Or set: DATABASE_URL="postgresql://euchre_camp:password@dhg.lol:5432/euchre_camp_dev"'); + console.error('To fix this:'); + console.error(' 1. Run: npm run test:acceptance'); + console.error(' 2. Or set: DATABASE_URL environment variable to dev database URL'); + console.error(' 3. Or load .env.development: source .env.development && npm run test:acceptance'); console.error(''); console.error('Aborting test execution to prevent data corruption.'); console.error(''); diff --git a/vitest.setup.ts b/vitest.setup.ts index 7ebc2ac..a9dd55f 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -30,7 +30,8 @@ if (databaseUrl) { console.error(''); console.error('To fix this:'); console.error(' 1. Run: npm run test:run'); - console.error(' 2. Or set: DATABASE_URL="postgresql://euchre_camp:password@dhg.lol:5432/euchre_camp_dev"'); + console.error(' 2. Or set: DATABASE_URL environment variable to dev database URL'); + console.error(' 3. Or load .env.development: source .env.development && npm run test:run'); console.error(''); console.error('Aborting test execution to prevent data corruption.'); console.error(''); From 6989decf6f4dfa08ba916ceb3d53c64832b3e025 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 18:30:19 -0700 Subject: [PATCH 4/7] fix: load .env.development in test setup files --- src/__tests__/e2e/global.setup.ts | 16 ++++++++++++++++ vitest.setup.ts | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/__tests__/e2e/global.setup.ts b/src/__tests__/e2e/global.setup.ts index c7d808c..1419a62 100644 --- a/src/__tests__/e2e/global.setup.ts +++ b/src/__tests__/e2e/global.setup.ts @@ -6,6 +6,22 @@ import { chromium, type FullConfig } from '@playwright/test'; import { prisma } from '@/lib/prisma'; import { cleanupAllTestData } from '@/__tests__/test-utils'; +import path from 'path'; +import fs from 'fs'; + +// Load .env file first, then .env.development (which will override .env) +const envPath = path.resolve(process.cwd(), '.env'); +const envDevPath = path.resolve(process.cwd(), '.env.development'); + +// Load base .env file +if (fs.existsSync(envPath)) { + require('dotenv').config({ path: envPath }); +} + +// Load .env.development file (will override .env settings) +if (fs.existsSync(envDevPath)) { + require('dotenv').config({ path: envDevPath, override: true }); +} const authFile = 'playwright/.auth/user.json'; const adminAuthFile = 'playwright/.auth/admin.json'; diff --git a/vitest.setup.ts b/vitest.setup.ts index a9dd55f..75e7800 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -1,4 +1,6 @@ import '@testing-library/jest-dom' +import path from 'path' +import fs from 'fs' /** * Vitest Setup File @@ -8,6 +10,20 @@ import '@testing-library/jest-dom' * to prevent accidental data corruption. */ +// Load .env file first, then .env.development (which will override .env) +const envPath = path.resolve(process.cwd(), '.env'); +const envDevPath = path.resolve(process.cwd(), '.env.development'); + +// Load base .env file +if (fs.existsSync(envPath)) { + require('dotenv').config({ path: envPath }); +} + +// Load .env.development file (will override .env settings) +if (fs.existsSync(envDevPath)) { + require('dotenv').config({ path: envDevPath, override: true }); +} + // Check if DATABASE_URL is set and points to dev database const databaseUrl = process.env.DATABASE_URL; From 237f128779f0e9836f548264c0cfece55e12d199 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 18:32:32 -0700 Subject: [PATCH 5/7] fix: remove hardcoded passwords from docker-compose generation --- playwright.config.ts | 2 +- scripts/generate-docker-compose.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index f532df6..d4c8ea2 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -66,7 +66,7 @@ export default defineConfig({ ], // Run your local dev server before starting the tests webServer: { - command: 'DATABASE_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_dev" npm run dev', + command: 'npm run dev', url: 'http://localhost:3000', timeout: 120000, reuseExistingServer: !process.env.CI, diff --git a/scripts/generate-docker-compose.js b/scripts/generate-docker-compose.js index 470c754..b5fe034 100755 --- a/scripts/generate-docker-compose.js +++ b/scripts/generate-docker-compose.js @@ -64,8 +64,8 @@ services: environment: # Database Configuration (REQUIRED: Set via CasaOS environment variables) - DATABASE_PROVIDER=postgresql - - DATABASE_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp" - - DATABASE_SHADOW_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_shadow" + - DATABASE_URL=\${DATABASE_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp} + - DATABASE_SHADOW_URL=\${DATABASE_SHADOW_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp_shadow} # Better Auth Configuration - BETTER_AUTH_SECRET=\${BETTER_AUTH_SECRET:-change-this-secret-in-production} @@ -113,8 +113,8 @@ services: environment: # Database Configuration - DATABASE_PROVIDER=postgresql - - DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp - - DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow + - DATABASE_URL=\${DATABASE_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp} + - DATABASE_SHADOW_URL=\${DATABASE_SHADOW_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp_shadow} # Better Auth Configuration - BETTER_AUTH_SECRET=\${BETTER_AUTH_SECRET:-change-this-secret-in-production} @@ -181,8 +181,8 @@ services: environment: # Database Configuration - DATABASE_PROVIDER=postgresql - - DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp - - DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow + - DATABASE_URL=\${DATABASE_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp} + - DATABASE_SHADOW_URL=\${DATABASE_SHADOW_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp_shadow} # Better Auth Configuration - BETTER_AUTH_SECRET=\${BETTER_AUTH_SECRET:-dev-secret-change-in-production} From b38b88f67d36deba622f683f140b51e863194bc2 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 18:33:51 -0700 Subject: [PATCH 6/7] chore: regenerate docker-compose files with environment variables --- docker-compose.casaos.yml | 6 +++--- docker-compose.dev.yml | 4 ++-- docker-compose.yml | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docker-compose.casaos.yml b/docker-compose.casaos.yml index ab21e57..fe0d9f5 100644 --- a/docker-compose.casaos.yml +++ b/docker-compose.casaos.yml @@ -7,15 +7,15 @@ services: app: - image: euchre-camp/euchre-camp:0.1.0 + image: euchre-camp/euchre-camp:0.1.0.dev container_name: euchre-camp ports: - "51193:3000" environment: # Database Configuration (REQUIRED: Set via CasaOS environment variables) - DATABASE_PROVIDER=postgresql - - DATABASE_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp" - - DATABASE_SHADOW_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_shadow" + - DATABASE_URL=${DATABASE_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp} + - DATABASE_SHADOW_URL=${DATABASE_SHADOW_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp_shadow} # Better Auth Configuration - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-change-this-secret-in-production} diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 52821e9..0b3b009 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -14,8 +14,8 @@ services: environment: # Database Configuration - DATABASE_PROVIDER=postgresql - - DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp - - DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow + - DATABASE_URL=${DATABASE_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp} + - DATABASE_SHADOW_URL=${DATABASE_SHADOW_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp_shadow} # Better Auth Configuration - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-dev-secret-change-in-production} diff --git a/docker-compose.yml b/docker-compose.yml index 8f103c8..dfeee88 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,15 +3,15 @@ services: app: - image: euchre-camp/euchre-camp:0.1.0 + image: euchre-camp/euchre-camp:0.1.0.dev container_name: euchre-camp-app ports: - "3000:3000" environment: # Database Configuration - DATABASE_PROVIDER=postgresql - - DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp - - DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow + - DATABASE_URL=${DATABASE_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp} + - DATABASE_SHADOW_URL=${DATABASE_SHADOW_URL:-postgresql://euchre_camp:password@db:5432/euchre_camp_shadow} # Better Auth Configuration - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-change-this-secret-in-production} From f9d6321721946c0780cd33715bd61f5107b71d99 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 18:39:27 -0700 Subject: [PATCH 7/7] fix: use ELO change instead of win rate for best partner calculation --- src/app/players/[id]/profile/page.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/players/[id]/profile/page.tsx b/src/app/players/[id]/profile/page.tsx index 837b0f2..445760c 100644 --- a/src/app/players/[id]/profile/page.tsx +++ b/src/app/players/[id]/profile/page.tsx @@ -86,12 +86,14 @@ export default async function PlayerProfilePage({ params }: PageProps) { const totalWins = player.wins const winRate = totalGames > 0 ? ((totalWins / totalGames) * 100).toFixed(1) : "0.0" - // Get best partnership + // Get best partnership based on ELO contribution + // Best partner is the one who contributed most to your rating (highest totalEloChange) + // Must have played at least 2 games together to be considered const bestPartnership = partnershipStats.reduce((best, stat) => { - if (stat.gamesPlayed < 3) return best // Need at least 3 games for partnership to be meaningful - const currentRate = stat.wins / stat.gamesPlayed - const bestRate = best ? best.wins / best.gamesPlayed : 0 - return currentRate > bestRate ? stat : best + if (stat.gamesPlayed < 2) return best // Need at least 2 games for partnership to be meaningful + const currentEloChange = stat.totalEloChange + const bestEloChange = best ? best.totalEloChange : -Infinity + return currentEloChange > bestEloChange ? stat : best }, null as (typeof partnershipStats[0] | null)) return (