From 45dfbc42d3680ba7a933fefeee8541135d1c8ca2 Mon Sep 17 00:00:00 2001 From: Albert Date: Sun, 9 Nov 2025 15:44:05 +0000 Subject: [PATCH] feat: Add production schema deployment scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create apply-schema-prod.js for deploying schema to any SurrealDB instance - Create deploy-schema.sh to easily deploy using .prod.env - Add npm scripts: schema:apply (local) and schema:deploy (production) Usage: pnpm schema:deploy # Deploy to production using .prod.env 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- package.json | 4 +- scripts/apply-schema-prod.js | 105 +++++++++++++++++++++++++++++++++++ scripts/deploy-schema.sh | 23 ++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100755 scripts/apply-schema-prod.js create mode 100755 scripts/deploy-schema.sh diff --git a/package.json b/package.json index fa24803..d80bde3 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "build": "next build", "start": "next start", "lint": "next lint", - "test": "npx magnitude" + "test": "npx magnitude", + "schema:apply": "node scripts/apply-schema.js", + "schema:deploy": "./scripts/deploy-schema.sh" }, "dependencies": { "@ai-sdk/google": "latest", diff --git a/scripts/apply-schema-prod.js b/scripts/apply-schema-prod.js new file mode 100755 index 0000000..e00a687 --- /dev/null +++ b/scripts/apply-schema-prod.js @@ -0,0 +1,105 @@ +#!/usr/bin/env node + +/** + * Apply SurrealDB schema to production database + * + * Usage: + * SURREALDB_URL= SURREALDB_USER= SURREALDB_PASS= \ + * SURREALDB_NS= SURREALDB_DB= SURREALDB_JWT_SECRET= \ + * node scripts/apply-schema-prod.js + */ + +const Surreal = require('surrealdb').default; +const fs = require('fs'); +const path = require('path'); + +async function applySchema() { + // Read config from environment + const config = { + url: process.env.SURREALDB_URL, + username: process.env.SURREALDB_USER, + password: process.env.SURREALDB_PASS, + namespace: process.env.SURREALDB_NS, + database: process.env.SURREALDB_DB, + jwtSecret: process.env.SURREALDB_JWT_SECRET, + }; + + // Validate required config + const missing = Object.entries(config) + .filter(([_, value]) => !value) + .map(([key]) => key); + + if (missing.length > 0) { + console.error('[Schema] ✗ Missing required environment variables:', missing.join(', ')); + console.error('[Schema] Please set all required variables:'); + console.error('[Schema] SURREALDB_URL, SURREALDB_USER, SURREALDB_PASS,'); + console.error('[Schema] SURREALDB_NS, SURREALDB_DB, SURREALDB_JWT_SECRET'); + process.exit(1); + } + + const db = new Surreal(); + + try { + console.log('[Schema] Connecting to SurrealDB...'); + console.log(`[Schema] URL: ${config.url}`); + await db.connect(config.url); + + console.log('[Schema] Signing in...'); + await db.signin({ + username: config.username, + password: config.password, + }); + + console.log('[Schema] Using namespace and database...'); + console.log(`[Schema] Namespace: ${config.namespace}`); + console.log(`[Schema] Database: ${config.database}`); + await db.use({ + namespace: config.namespace, + database: config.database, + }); + + console.log('[Schema] Reading schema file...'); + const schemaPath = path.join(__dirname, '..', 'db', 'schema.surql'); + let schema = fs.readFileSync(schemaPath, 'utf-8'); + + // Replace $env.SURREALDB_JWT_SECRET with actual value + schema = schema.replace('$env.SURREALDB_JWT_SECRET', `'${config.jwtSecret}'`); + + console.log('[Schema] Executing schema...'); + let result; + try { + result = await db.query(schema); + } catch (error) { + // If error contains "already exists", it's OK - schema was already applied + if (error.message.includes('already exists')) { + console.log('[Schema] ⚠ Some schema elements already exist (this is OK)'); + console.log('[Schema] ✓ Schema is up to date!'); + return; + } else { + throw error; + } + } + + if (result) { + console.log(`[Schema] Executed ${result.length} queries`); + + // Log any errors + result.forEach((r, i) => { + if (r.status === 'ERR') { + console.error(`[Schema] Error in query ${i + 1}:`, r.result); + } else { + console.log(`[Schema] ✓ Query ${i + 1} succeeded`); + } + }); + } + + console.log('[Schema] ✓ Schema applied successfully!'); + } catch (error) { + console.error('[Schema] ✗ Failed to apply schema:', error); + process.exit(1); + } finally { + await db.close(); + } +} + +applySchema(); diff --git a/scripts/deploy-schema.sh b/scripts/deploy-schema.sh new file mode 100755 index 0000000..e254280 --- /dev/null +++ b/scripts/deploy-schema.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Deploy schema to production SurrealDB +# This script reads from .prod.env and applies the schema + +set -e + +if [ ! -f .prod.env ]; then + echo "Error: .prod.env file not found" + echo "Please create .prod.env with your production database credentials" + exit 1 +fi + +echo "Loading production environment variables..." +export $(cat .prod.env | grep -v '^#' | grep '=' | xargs) + +echo "Applying schema to production database..." +node scripts/apply-schema-prod.js + +echo "" +echo "✓ Schema deployment complete!" +echo "" +echo "You can now test your deployment at: https://www.ponderants.com"