Files
fullstack-starter/apps/server/src/lib/device-init.ts
imbytecat 8952bf4205 feat: 完善许可证激活功能及数据库初始化
- 将 db 中间件重命名为 dbProvider,同时保留 db 作为别名以避免破坏现有路由。
- 记录并解决开发环境中数据库迁移和类型检查工具使用问题。
- 完善许可证激活功能,新增数据表与初始化逻辑,实现UPSERT操作及单例模式,添加RPC接口支持,修复时间戳类型不匹配问题。
- 创建设备信息和待办事项数据表,并为设备指纹添加唯一索引。
- 添加许可证激活表及指纹唯一索引
- 添加设备信息和待办事项表的数据库模式快照,包含字段定义、主键约束及指纹唯一索引。
- 添加初始数据库模式快照,包含设备信息、许可证激活和待办事项三张表的结构定义。
- 添加新的迁移日志文件以记录数据库版本变更和迁移步骤
- 确保设备信息在数据库中正确初始化,使用硬件指纹唯一标识设备并支持并发安全的单例模式初始化。
- 初始化许可证激活记录,确保基于硬件指纹创建或更新激活信息。
- 添加许可证激活管理页面,包含设备指纹展示、许可证输入激活功能及激活状态实时反馈。
- 添加许可证页面路由配置并更新相关路由类型和路径映射。
- 添加设备信息获取与许可证设置的接口契约定义,包含数据校验 schema 和接口输入输出规范。
- 添加设备和许可证合约接口到导出契约对象中
- 添加许可证相关API契约,定义获取激活状态和激活许可证的输入输出结构。
- 初始化设备和许可激活状态,并将数据库中间件重命名为dbProvider,同时导出原始db名称以保持兼容性。
- 添加设备信息获取和许可证设置接口,确保设备初始化并安全处理数据读写。
- 添加设备和许可证路由到API路由器中。
- 添加许可证激活状态查询和激活功能,支持通过数据库记录管理许可证信息并返回激活时间戳。
- 添加设备信息表结构,包含指纹、指纹质量等级、许可证及激活时间字段。
- 添加设备信息和许可证激活相关数据模型导出
- 添加许可证激活记录表,包含指纹、许可证信息及激活时间字段。
2026-01-26 15:03:33 +08:00

62 lines
1.6 KiB
TypeScript

import { getHardwareFingerprint } from '@/lib/fingerprint'
import { getDB } from '@/server/db'
import { deviceInfoTable } from '@/server/db/schema'
let initPromise: Promise<void> | null = null
/**
* 确保设备信息已在数据库中初始化
* 使用单例模式防止并发重复初始化
*/
export async function ensureDeviceInitialized(): Promise<void> {
if (initPromise) {
return initPromise
}
initPromise = (async () => {
try {
const db = getDB()
// 获取硬件指纹
let result: { fingerprint: string; quality: 'strong' | 'medium' | 'weak' }
try {
result = await getHardwareFingerprint({
cacheTtlMs: 10 * 60 * 1000,
includePrimaryDisk: true,
})
} catch (error) {
console.error('Failed to get hardware fingerprint:', error)
// 回退逻辑
result = {
fingerprint: `unknown-${Date.now()}`,
quality: 'weak' as const,
}
}
// 使用 UPSERT 逻辑更新或插入设备信息
await db
.insert(deviceInfoTable)
.values({
fingerprint: result.fingerprint,
fingerprintQuality: result.quality,
license: null,
licenseActivatedAt: null,
})
.onConflictDoUpdate({
target: deviceInfoTable.fingerprint,
set: {
fingerprintQuality: result.quality,
updatedAt: new Date(),
},
})
} catch (error) {
console.error('Failed to initialize device info:', error)
// 重置 promise 以允许重试
initPromise = null
throw error
}
})()
return initPromise
}