5.1 KiB
5.1 KiB
Supabase 数据库适配说明
概述
推送消息接收服务的数据库结构已适配现有的 ak_users 和 ak_devices 表结构,以避免重复创建表和数据冲突。所有推送消息相关的表都使用 ps_ 前缀命名。
主要变更
1. 移除独立表
- ❌ 移除独立的
devices表 - ❌ 移除独立的
users表 - ✅ 使用现有的
public.ak_devices表 - ✅ 使用现有的
public.ak_users表
2. 表命名规范
- ✅
ps_push_messages- 推送消息主表 - ✅
ps_push_types- 推送类型配置表 - ✅
ps_message_processing_logs- 消息处理日志表 - ✅
ps_system_stats- 系统统计表
3. 修改关联字段
ps_push_messages.user_id: VARCHAR(255) → UUID,关联到public.ak_users(id)ps_push_messages.device_id: VARCHAR(255) → UUID,关联到public.ak_devices(id)
ps_push_messages 表结构
CREATE TABLE ps_push_messages (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
message_id VARCHAR(255),
push_type VARCHAR(50) NOT NULL,
user_id UUID REFERENCES public.ak_users(id) ON DELETE SET NULL,
device_id UUID REFERENCES public.ak_devices(id) ON DELETE SET NULL,
raw_data JSONB NOT NULL,
parsed_data JSONB,
received_at TIMESTAMPTZ DEFAULT NOW(),
processing_status VARCHAR(20) DEFAULT 'pending',
-- 其他字段...
);
4. 适配表结构
public.ak_users 表结构
CREATE TABLE public.ak_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(64) UNIQUE NOT NULL,
email VARCHAR(128) UNIQUE NOT NULL,
password_hash VARCHAR(256) NOT NULL,
gender VARCHAR(16) DEFAULT 'other',
birthday DATE,
height_cm INT,
weight_kg INT,
bio TEXT,
phone VARCHAR(32),
avatar_url TEXT,
region_id UUID REFERENCES public.ak_regions(id),
school_id UUID REFERENCES public.ak_schools(id),
grade_id UUID REFERENCES public.ak_grades(id),
class_id UUID REFERENCES public.ak_classes(id),
role VARCHAR(32) DEFAULT 'student',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
auth_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
preferred_language UUID REFERENCES public.ak_languages(id)
);
public.ak_devices 表结构
CREATE TABLE public.ak_devices (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES public.ak_users(id) ON DELETE CASCADE,
device_type VARCHAR(32) NOT NULL,
device_name VARCHAR(64),
device_mac VARCHAR(64),
bind_time TIMESTAMPTZ DEFAULT now(),
status VARCHAR(16) DEFAULT 'active',
extra JSONB
);
5. 数据库操作调整
设备信息处理
// 旧方式:自动创建/更新设备
await this.upsertDevice(deviceData);
// 新方式:检查并更新现有设备状态
await this.upsertDevice({
device_id: deviceData.device_id, // 必须是现有设备的 UUID
metadata: deviceData.metadata
});
用户信息处理
// 旧方式:自动创建/更新用户
await this.upsertUser(userData);
// 新方式:检查现有用户(不自动创建)
await this.upsertUser({
user_id: userData.user_id // 必须是现有用户的 UUID
});
API 调用变更
推送消息接口
// 发送推送消息时,user_id 和 device_id 必须使用 UUID 格式
const response = await fetch('/api/push/message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your-api-key'
},
body: JSON.stringify({
type: 'HEALTH',
data: {
user_id: '123e4567-e89b-12d3-a456-426614174000', // UUID 格式
device_id: '987fcdeb-51a2-43d7-8f9e-123456789abc', // UUID 格式
H: 72, // 心率
O: 98, // 血氧
T: 36.5 // 体温
}
})
});
错误处理
如果推送消息中包含不存在的 user_id 或 device_id:
- 消息仍会被存储到
push_messages表 - 会在日志中记录警告信息
- 不会自动创建用户或设备记录
部署注意事项
1. 数据库初始化
确保在执行 database/supabase-init.sql 之前,现有的 ak_users 和 ak_devices 表已经存在。
2. 外键约束
推送消息表与现有表建立了外键关联:
ps_push_messages.user_id→public.ak_users(id)ps_push_messages.device_id→public.ak_devices(id)
3. 权限设置
确保 Supabase Service Role 对现有表有适当的访问权限。
数据完整性
推送消息存储
- ✅ 所有推送消息都会完整存储
- ✅ 支持 user_id 或 device_id 为 NULL 的情况
- ✅ 通过外键约束保证数据一致性
统计和查询
- ✅ 可以通过关联查询获取用户和设备的详细信息
- ✅ 统计功能完全兼容现有表结构
使用建议
- 用户和设备管理:通过专门的用户管理和设备管理接口创建和维护用户、设备信息
- 推送消息:只负责接收和存储推送消息,不处理用户/设备的创建
- 数据关联:通过外键关联获取完整的用户和设备信息
- 监控告警:监控日志中关于不存在用户/设备的警告信息