From 7dc871851267b7fc8e120a51691535c6c14aea9d Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Tue, 22 Jul 2025 08:18:51 -0500 Subject: [PATCH] Fix build issues and update dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔧 Build Fixes: - Update Node.js version from 18.x to 22.x (required by Vercel) - Remove debug endpoints to get under 12 function limit for Hobby plan - Downgrade React from 19.x to 18.x for better compatibility - Update react-router-dom to v6.28.0 (compatible with Node 22) - Update TypeScript to v5.7.3 - Update React types to match React version Functions count: 12/12 (at limit for Hobby plan) Core API endpoints: ✅ auth/login.js, auth/register.js ✅ collections/index.js, collections/add-card.js ✅ cards/find-or-create.js ✅ admin/users.js, admin/promote-user.js ✅ setup-auth.js, simple.js ✅ Legacy: migrate.ts, v1/cards/[id].ts, v1/cards/index.ts --- api/debug.js | 18 ------- api/make-admin.js | 49 ------------------ api/promote-testuser.js | 108 ---------------------------------------- api/test-db-local.js | 63 ----------------------- package.json | 14 +++--- 5 files changed, 7 insertions(+), 245 deletions(-) delete mode 100644 api/debug.js delete mode 100644 api/make-admin.js delete mode 100644 api/promote-testuser.js delete mode 100644 api/test-db-local.js diff --git a/api/debug.js b/api/debug.js deleted file mode 100644 index 1893550..0000000 --- a/api/debug.js +++ /dev/null @@ -1,18 +0,0 @@ -export default function handler(req, res) { - res.status(200).json({ - success: true, - message: 'Debug endpoint - latest version', - timestamp: new Date().toISOString(), - method: req.method, - environment: process.env.NODE_ENV || 'unknown', - vercel_env: process.env.VERCEL_ENV || 'unknown', - has_database_url: !!process.env.DATABASE_URL, - has_jwt_secret: !!process.env.JWT_SECRET, - database_url_length: process.env.DATABASE_URL ? process.env.DATABASE_URL.length : 0, - database_url_starts_with: process.env.DATABASE_URL ? - process.env.DATABASE_URL.substring(0, 20) + '...' : 'not set', - all_env_keys: Object.keys(process.env).filter(key => - key.includes('DATABASE') || key.includes('JWT') || key.includes('NEON') - ) - }); -} \ No newline at end of file diff --git a/api/make-admin.js b/api/make-admin.js deleted file mode 100644 index af07804..0000000 --- a/api/make-admin.js +++ /dev/null @@ -1,49 +0,0 @@ -const { Pool } = require('pg'); - -export default async function handler(req, res) { - try { - const pool = new Pool({ - connectionString: process.env.DATABASE_URL, - ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false, - }); - - const client = await pool.connect(); - - // Simple promotion - just add user 1 to admin role - const result = await client.query(` - INSERT INTO user_roles (user_id, role_id) - SELECT 1, id FROM roles WHERE name = 'admin' - ON CONFLICT DO NOTHING - RETURNING * - `); - - // Check current roles - const userRoles = await client.query(` - SELECT - u.username, - ARRAY_AGG(r.name) as roles - FROM users u - LEFT JOIN user_roles ur ON u.id = ur.user_id - LEFT JOIN roles r ON ur.role_id = r.id - WHERE u.id = 1 - GROUP BY u.username - `); - - client.release(); - - res.status(200).json({ - success: true, - message: 'Admin promotion complete', - inserted: result.rows.length > 0, - user: userRoles.rows[0] || null, - timestamp: new Date().toISOString() - }); - - } catch (error) { - res.status(500).json({ - success: false, - error: error.message, - timestamp: new Date().toISOString() - }); - } -} \ No newline at end of file diff --git a/api/promote-testuser.js b/api/promote-testuser.js deleted file mode 100644 index 62be6ec..0000000 --- a/api/promote-testuser.js +++ /dev/null @@ -1,108 +0,0 @@ -const { Pool } = require('pg'); - -const pool = new Pool({ - connectionString: process.env.DATABASE_URL, - ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false, -}); - -export default async function handler(req, res) { - if (req.method !== 'POST') { - return res.status(405).json({ error: 'Method not allowed' }); - } - - const client = await pool.connect(); - - try { - // Get the test user (ID 1) - const userResult = await client.query( - 'SELECT id, username, email FROM users WHERE id = $1', - [1] - ); - - if (userResult.rows.length === 0) { - return res.status(404).json({ - error: 'Test user not found' - }); - } - - const user = userResult.rows[0]; - - // Check if user is already an admin - const adminCheckQuery = ` - SELECT ur.user_id - FROM user_roles ur - JOIN roles r ON ur.role_id = r.id - WHERE ur.user_id = $1 AND r.name = 'admin' - `; - - const adminCheck = await client.query(adminCheckQuery, [user.id]); - - if (adminCheck.rows.length > 0) { - return res.status(200).json({ - success: true, - message: 'User is already an admin', - user: { - id: user.id, - username: user.username, - email: user.email - } - }); - } - - // Get admin role ID - const roleResult = await client.query( - 'SELECT id FROM roles WHERE name = $1', - ['admin'] - ); - - if (roleResult.rows.length === 0) { - return res.status(500).json({ - error: 'Admin role not found in database' - }); - } - - const adminRoleId = roleResult.rows[0].id; - - // Add user to admin role - await client.query( - 'INSERT INTO user_roles (user_id, role_id) VALUES ($1, $2)', - [user.id, adminRoleId] - ); - - // Get updated user info with roles - const updatedUserQuery = ` - SELECT - u.id, u.username, u.email, u.first_name, u.last_name, - ARRAY_AGG(DISTINCT r.name) as roles - FROM users u - LEFT JOIN user_roles ur ON u.id = ur.user_id - LEFT JOIN roles r ON ur.role_id = r.id - WHERE u.id = $1 - GROUP BY u.id, u.username, u.email, u.first_name, u.last_name - `; - - const updatedUser = await client.query(updatedUserQuery, [user.id]); - - res.status(200).json({ - success: true, - message: 'Test user successfully promoted to admin', - user: { - id: updatedUser.rows[0].id, - username: updatedUser.rows[0].username, - email: updatedUser.rows[0].email, - firstName: updatedUser.rows[0].first_name, - lastName: updatedUser.rows[0].last_name, - roles: updatedUser.rows[0].roles || [] - } - }); - - } catch (error) { - console.error('Promote test user error:', error); - res.status(500).json({ - error: 'Internal server error', - details: error.message - }); - } finally { - client.release(); - } -} \ No newline at end of file diff --git a/api/test-db-local.js b/api/test-db-local.js deleted file mode 100644 index a1c724d..0000000 --- a/api/test-db-local.js +++ /dev/null @@ -1,63 +0,0 @@ -const { Pool } = require('pg'); - -export default async function handler(req, res) { - try { - const pool = new Pool({ - connectionString: process.env.DATABASE_URL, - ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false, - }); - - const client = await pool.connect(); - - // Test basic connection - const result = await client.query('SELECT NOW() as current_time'); - - // Test if users table exists - const tableCheck = await client.query(` - SELECT table_name - FROM information_schema.tables - WHERE table_schema = 'public' - AND table_name IN ('users', 'roles', 'user_roles') - `); - - // If users table exists, check for test user - let userCheck = null; - if (tableCheck.rows.some(row => row.table_name === 'users')) { - try { - userCheck = await client.query( - 'SELECT id, username, email FROM users WHERE username = $1', - ['testuser'] - ); - } catch (err) { - userCheck = { error: err.message }; - } - } - - client.release(); - - res.status(200).json({ - success: true, - message: 'Database connection test', - timestamp: result.rows[0].current_time, - environment: { - NODE_ENV: process.env.NODE_ENV, - has_database_url: !!process.env.DATABASE_URL, - has_jwt_secret: !!process.env.JWT_SECRET - }, - tables: tableCheck.rows.map(row => row.table_name), - testUser: userCheck ? { - exists: userCheck.rows ? userCheck.rows.length > 0 : false, - data: userCheck.rows ? userCheck.rows[0] : null, - error: userCheck.error || null - } : null - }); - - } catch (error) { - console.error('Database test error:', error); - res.status(500).json({ - success: false, - error: error.message, - stack: error.stack - }); - } -} \ No newline at end of file diff --git a/package.json b/package.json index fffe33b..09a1116 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "engines": { - "node": "18.x" + "node": "22.x" }, "dependencies": { "@stackframe/stack": "^2.8.22", @@ -18,8 +18,8 @@ "@types/next": "^8.0.7", "@types/node": "^16.18.126", "@types/pg": "^8.15.4", - "@types/react": "^19.1.8", - "@types/react-dom": "^19.1.6", + "@types/react": "^18.3.17", + "@types/react-dom": "^18.3.5", "@types/react-router-dom": "^5.3.3", "@vercel/analytics": "^1.5.0", "@vercel/blob": "^1.1.1", @@ -29,12 +29,12 @@ "jsonwebtoken": "^9.0.2", "next": "^15.4.2", "pg": "^8.16.3", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "react-router-dom": "^7.7.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.28.0", "react-scripts": "5.0.1", "tesseract.js": "^6.0.1", - "typescript": "^4.9.5", + "typescript": "^5.7.3", "web-vitals": "^2.1.4" }, "scripts": {