Files
akmon/push-receiver-service/SUPABASE_ADAPTATION.md
2026-01-20 08:04:15 +08:00

168 lines
5.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` 表结构
```sql
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` 表结构
```sql
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` 表结构
```sql
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. 数据库操作调整
#### 设备信息处理
```javascript
// 旧方式:自动创建/更新设备
await this.upsertDevice(deviceData);
// 新方式:检查并更新现有设备状态
await this.upsertDevice({
device_id: deviceData.device_id, // 必须是现有设备的 UUID
metadata: deviceData.metadata
});
```
#### 用户信息处理
```javascript
// 旧方式:自动创建/更新用户
await this.upsertUser(userData);
// 新方式:检查现有用户(不自动创建)
await this.upsertUser({
user_id: userData.user_id // 必须是现有用户的 UUID
});
```
## API 调用变更
### 推送消息接口
```javascript
// 发送推送消息时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 的情况
- ✅ 通过外键约束保证数据一致性
### 统计和查询
- ✅ 可以通过关联查询获取用户和设备的详细信息
- ✅ 统计功能完全兼容现有表结构
## 使用建议
1. **用户和设备管理**:通过专门的用户管理和设备管理接口创建和维护用户、设备信息
2. **推送消息**:只负责接收和存储推送消息,不处理用户/设备的创建
3. **数据关联**:通过外键关联获取完整的用户和设备信息
4. **监控告警**:监控日志中关于不存在用户/设备的警告信息