Fix build issues and update dependencies
🔧 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
This commit is contained in:
parent
e4b00ea227
commit
7dc8718512
5 changed files with 7 additions and 245 deletions
18
api/debug.js
18
api/debug.js
|
|
@ -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')
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
@ -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()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
14
package.json
14
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": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue