Initial commit of akmon project

This commit is contained in:
2026-01-20 08:04:15 +08:00
commit 77a2bab985
1309 changed files with 343305 additions and 0 deletions

View File

@@ -0,0 +1,249 @@
/**
* Supabase 数据库初始化脚本
* 自动检查并初始化 Supabase 数据库表结构
*/
const SupabaseDatabaseManager = require('./lib/supabase-database');
const fs = require('fs');
const path = require('path');
require('dotenv').config();
class SupabaseDatabaseSetup {
constructor() {
this.db = new SupabaseDatabaseManager();
}
async setup() {
try {
console.log('🔧 开始 Supabase 数据库初始化...');
// 测试 Supabase 连接
console.log('📡 测试 Supabase 数据库连接...');
await this.db.testConnection();
console.log('✅ Supabase 数据库连接成功');
// 检查环境变量
console.log('🔍 检查环境配置...');
this.checkEnvironmentVariables();
// 验证表结构
console.log('🔍 验证数据库表结构...');
await this.verifyTables();
// 插入测试数据
console.log('📝 插入测试数据...');
await this.insertTestData();
// 测试基本功能
console.log('🧪 测试基本功能...');
await this.testBasicFunctionality();
console.log('🎉 Supabase 数据库初始化完成!');
} catch (error) {
console.error('❌ Supabase 数据库初始化失败:', error.message);
throw error;
} finally {
await this.db.close();
}
}
checkEnvironmentVariables() {
const requiredEnvVars = [
'SUPABASE_URL',
'SUPABASE_SERVICE_ROLE_KEY'
];
const missingVars = requiredEnvVars.filter(varName => !process.env[varName]);
if (missingVars.length > 0) {
throw new Error(`缺少必要的环境变量: ${missingVars.join(', ')}`);
}
console.log('✅ 环境配置检查通过');
console.log(` - Supabase URL: ${process.env.SUPABASE_URL}`);
console.log(` - Service Role Key: ${'*'.repeat(20)}${process.env.SUPABASE_SERVICE_ROLE_KEY.slice(-10)}`);
}
async verifyTables() {
const expectedTables = [
'ps_push_messages',
'ps_push_types',
'message_processing_logs',
'devices',
'users',
'system_stats'
];
try {
// 检查每个表是否存在
for (const tableName of expectedTables) {
const { data, error } = await this.db.supabase
.from(tableName)
.select('*')
.limit(1);
if (error) {
console.log(`❌ 数据表 ${tableName} 不存在或无法访问`);
console.log(` 错误: ${error.message}`);
console.log(` 📋 请在 Supabase Dashboard 的 SQL Editor 中执行 database/supabase-init.sql`);
throw new Error(`数据表 ${tableName} 不可用: ${error.message}`);
} else {
console.log(`✅ 数据表 ${tableName} 可用`);
}
}
console.log('✅ 所有必要数据表验证通过');
} catch (error) {
throw new Error(`数据表验证失败: ${error.message}`);
}
}
async insertTestData() {
try {
// 检查是否已有测试数据
const { data: existingData } = await this.db.supabase
.from('ps_push_messages')
.select('id')
.eq('user_id', 'test_user_supabase')
.limit(1);
if (existingData && existingData.length > 0) {
console.log(' 测试数据已存在,跳过插入');
return;
}
// 插入测试推送消息
const testMessages = [
{
pushType: 'HEALTH',
userId: 'test_user_supabase',
deviceId: 'device_supabase_001',
H: 75,
O: 98,
T: 36.5,
source_ip: '127.0.0.1',
user_agent: 'Supabase Test Client'
},
{
pushType: 'SOS',
userId: 'test_user_supabase_002',
deviceId: 'device_supabase_002',
emergencyLevel: 'HIGH',
lat: 39.9042,
lng: 116.4074,
source_ip: '127.0.0.1',
user_agent: 'Supabase Test Client'
},
{
pushType: 'LOCATION',
userId: 'test_user_supabase_003',
deviceId: 'device_supabase_003',
lat: 31.2304,
lng: 121.4737,
accuracy: 10,
source_ip: '127.0.0.1',
user_agent: 'Supabase Test Client'
}
];
for (const message of testMessages) {
await this.db.insertPushMessage(message);
}
console.log('✅ 测试数据插入完成');
} catch (error) {
console.warn('⚠️ 测试数据插入失败:', error.message);
// 不阻止初始化过程
}
}
async testBasicFunctionality() {
try {
// 测试插入消息
const testMessage = {
pushType: 'TEST',
userId: 'setup_test_user',
deviceId: 'setup_test_device',
testData: 'Supabase setup test',
source_ip: '127.0.0.1',
user_agent: 'Setup Test Client'
};
const insertResult = await this.db.insertPushMessage(testMessage);
console.log('✅ 消息插入测试通过');
// 测试获取统计信息
const stats = await this.db.getMessageStats(1);
console.log('✅ 统计信息获取测试通过');
// 测试获取健康状态
const health = await this.db.getHealthStatus();
console.log('✅ 健康状态检查测试通过');
// 测试获取消息列表
const messages = await this.db.getPushMessages({ limit: 5 });
console.log('✅ 消息列表获取测试通过');
console.log('✅ 所有基本功能测试通过');
} catch (error) {
throw new Error(`基本功能测试失败: ${error.message}`);
}
}
async showSetupInstructions() {
console.log('\n📋 Supabase 数据库设置说明:');
console.log('');
console.log('1. 创建 Supabase 项目:');
console.log(' - 访问 https://supabase.com/dashboard');
console.log(' - 点击 "New project" 创建新项目');
console.log(' - 记录项目的 URL 和 API Keys');
console.log('');
console.log('2. 执行数据库初始化脚本:');
console.log(' - 在 Supabase Dashboard 中打开 "SQL Editor"');
console.log(' - 复制 database/supabase-init.sql 文件内容');
console.log(' - 粘贴到 SQL Editor 中并执行');
console.log('');
console.log('3. 配置环境变量:');
console.log(' - 复制 .env.supabase 为 .env');
console.log(' - 更新 SUPABASE_URL 为您的项目 URL');
console.log(' - 更新 SUPABASE_SERVICE_ROLE_KEY 为您的 Service Role Key');
console.log('');
console.log('4. 启用实时功能 (可选):');
console.log(' - 在 Database > Replication 中');
console.log(' - 启用 push_messages 表的实时复制');
console.log('');
}
}
// 如果直接运行此脚本
if (require.main === module) {
const setup = new SupabaseDatabaseSetup();
// 检查是否有必要的环境变量
if (!process.env.SUPABASE_URL || !process.env.SUPABASE_SERVICE_ROLE_KEY) {
console.log('⚠️ 缺少 Supabase 环境配置');
setup.showSetupInstructions();
process.exit(1);
}
setup.setup()
.then(() => {
console.log('🎉 Supabase 数据库设置完成,可以启动服务了!');
console.log('');
console.log('🚀 启动服务命令:');
console.log(' node supabase-server.js');
console.log('');
process.exit(0);
})
.catch((error) => {
console.error('❌ Supabase 数据库设置失败:', error.message);
setup.showSetupInstructions();
process.exit(1);
});
}
module.exports = SupabaseDatabaseSetup;