探鸽摄像头产品 SDK 与云服务接入研发计划
文档版本:v1.0
编写日期:2026-04-02
项目:AOVIS / NEXA 独立站(aovis.app)
里程碑基线:aovis-direct-store-v0.5
当前阶段:Launch Validation 之后,设备与云服务接入准备期
A. 一页式结论
我们接下来要做的事情,本质是"把已经预埋好的骨架填入真实肌肉"。
aovis.app 当前已具备完整的电商主链路(购物车 → Stripe 支付 → 订单 → Webhook 回写)和账户体系(NextAuth + User/Session),以及设备/套餐的完整数据模型预埋(Device、DeviceOwnership、Entitlement、DataPlan、SimCard)。缺失的是:
- 探鸽 SDK token 桥接——aovis 用户登录后,服务端如何从探鸽获取 SDK 鉴权 token 并下发给 Flutter APP
- 设备绑定写回——APP 端完成配网绑定后,如何将绑定关系写入 aovis 数据库
- 套餐履约闭环——DataPlan 购买成功后,如何真正调用外部供应商 API 激活套餐
- 状态同步机制——设备在线状态、SIM 用量、套餐余量如何从云端同步回站内
推荐的实施顺序:Phase 0(文档与账号)→ Phase 1(Token 桥接,只读同步)→ Phase 2(设备绑定)→ Phase 3(套餐激活履约)→ Phase 4(云服务/订阅联动)→ Phase 5(运维与补偿机制)。
核心原则:所有实现必须在现有框架内填充,不推翻现有 UI、不改变 Stripe 链路、不引入新账号体系。
B. 当前系统真实状态判断
B.1 系统域分层状态
| 域 | 模块 | 真实状态 |
|---|---|---|
| 前台电商 | 首页、商品页、购物车、Checkout | ✅ 已完成,launch-ready |
| 前台电商 | 硬件订单 Stripe 支付主链路 | ✅ 已通过 test mode 验证 |
| 账户中心 | Google / Apple / Email magic link 登录 | ✅ 已验证(Apple 有 VM 环境变量注意事项) |
| 账户中心 | /account/orders、/account/profile | ✅ 真实可用 |
| 账户中心 | /account/devices — 列表展示 | ⚠️ 页面存在,"Add Device" 仍 disabled |
| 账户中心 | /account/services — 套餐/权益展示 | ⚠️ 展示占位,entitlement auto-granting 未实现 |
| 数字商品 | /data-plans 购买页 + /api/checkout/data-plan | ✅ 购买链路通,但激活是 stub |
| 数字商品 | /api/webhooks/data-plan — 落库 DataPlanPurchase | ✅ 写库完成,fulfillment 未调供应商 |
| 后台运营 | admin devices、SIM cards、data plans | ⚠️ 页面和表结构有,数据依赖手动种子 |
| 外部 API | lib/eiotclub.ts — IoT API client | ❌ STATUS: STUB,所有方法返回 null/false |
| 外部 API | /api/webhooks/eiotclub — 事件落库 | ⚠️ 接收并写 SimEvent,无业务状态推进 |
| 探鸽 SDK | 设备绑定、云端管理、实时 RTC | ❌ 尚未接入,此次研发目标 |
B.2 关键半成品的性质说明
lib/eiotclub.ts:接口签名设计合理,已预留 getCardInfo、subscribePackage、bindDevice 等方法,但方法体均为占位返回。这是直接填充实现的位置,不需要重新设计接口层。
Device / DeviceOwnership 模型:字段足够支撑设备注册与绑定关系,缺少的是 externalDeviceId(探鸽平台的设备 ID)和同步时间戳类字段。
DataPlan / DataPlanPurchase 模型:已有 eiotclubProductId、eiotclubPackageId、fulfillmentStatus、activatedAt、expiresAt,结构已预留履约回写位置。
Entitlement 模型:有 status、quota、startedAt、expiresAt,但与探鸽云服务的映射关系尚未建立。
C. 探鸽接入的推荐目标架构
C.1 探鸽在 aovis.app 中的职责边界
| 职责 | 由谁承担 | 实现方式 |
|---|---|---|
| 用户身份映射(aovis user → 探鸽 token) | aovis 服务端 | /api/tange/token 路由,调用探鸽「自有账户登录」API |
| 摄像头配网/绑定 | Flutter APP + 探鸽 SDK | APP 完成后回调 aovis /api/tange/device-bind |
| 设备基础信息(型号/序列号/固件) | 探鸽云 API | 绑定时同步写入 Device 表,后续定期同步 |
| 设备在线/离线状态 | 探鸽 webhook | /api/webhooks/tange/device-event 接收推送 |
| SIM 卡用量/套餐余量 | 定时同步 + Eiotclub API | scheduled sync job,回写 SimCard |
| 云存储套餐开通 | aovis 服务端 | 支付成功后调用探鸽/Eiotclub API |
| 设备视频播放/P2P 控制 | Flutter APP + 探鸽 SDK | 纯客户端,aovis 服务端不介入 |
| 报警事件存储与展示 | 探鸽云 | 站内不做主存储,通过 API 查询展示 |
C.2 系统分层架构
┌──────────────────────────────────────────────────────────────┐
│ 前端层(Next.js App Router / React) │
│ /account/devices /account/services /admin/* │
├──────────────────────────────────────────────────────────────┤
│ Next.js Route Handlers(API 层) │
│ /api/tange/token → 探鸽 token 桥接 │
│ /api/tange/device-bind → 设备绑定写回 │
│ /api/webhooks/tange/* → 探鸽事件接收 │
│ /api/admin/devices → 后台设备列表 │
├──────────────────────────────────────────────────────────────┤
│ Service 层(lib/) │
│ lib/tange.ts → 探鸽 HTTP API client(新增) │
│ lib/eiotclub.ts → Eiotclub SIM API(填充实现) │
│ lib/device-sync.ts → 设备状态同步逻辑(新增) │
├──────────────────────────────────────────────────────────────┤
│ Prisma 数据层(PostgreSQL) │
│ Device / DeviceOwnership / Entitlement(扩展字段) │
│ SimCard / DataPlanPurchase(填充真实数据) │
├──────────────────────────────────────────────────────────────┤
│ 外部依赖层 │
│ 探鸽云 API(设备注册、状态查询、云服务开通) │
│ Eiotclub API(SIM 卡管理、流量套餐) │
│ 探鸽 webhook 推送(设备事件) │
└──────────────────────────────────────────────────────────────┘
↑ Flutter APP(探鸽 SDK rapid_kit)通过 aovis REST API 桥接
D. 关键流程设计
D.1 用户购买摄像头 → 发货 → 首次激活 → 设备绑定
1. 用户在 aovis.app 购买 NEXA Prime 4K
└─ Stripe Checkout → /api/stripe/webhook → Order.status = FULFILLED
2. 仓库发货(线下,aovis 后台更新 fulfillmentStatus)
3. 用户收货,下载 AOVIS Flutter APP,登录
└─ APP 调用 POST /api/tange/token(携带 NextAuth session token)
└─ aovis 服务端 → 调用探鸽「自有账户登录」API → 获取 tangeToken
└─ 返回 tangeToken 给 APP
└─ APP 调用 RapidKit.initialize() + Authenticate.configure(tangeToken)
4. 用户扫码/AP 配网摄像头(Flutter SDK 完成配网与探鸽侧绑定)
5. 配网成功后 APP 回调 POST /api/tange/device-bind
请求体:{ deviceUuid, model, serialNumber, firmwareVersion }
aovis 服务端:
└─ Upsert Device(by deviceUuid)
└─ Create DeviceOwnership(userId, deviceId, role=OWNER, boundAt=now())
└─ 触发初始 Entitlement(如有购买云存储套餐)
6. /account/devices 展示绑定成功的设备
D.2 用户购买 Data Plan → 套餐激活履约闭环
1. 用户在 /data-plans 选购套餐,关联已绑定的 SIM 卡
2. POST /api/checkout/data-plan → Stripe Checkout Session
metadata: { type: 'data_plan', dataPlanId, simCardId, userId }
3. Stripe 支付成功 → POST /api/webhooks/data-plan(已有)
└─ 创建 DataPlanPurchase(paymentStatus=succeeded)
└─ [新增] 调用 Eiotclub subscribePackage(iccid, packageId)
└─ [新增] 回写 DataPlanPurchase.fulfillmentStatus、activatedAt、expiresAt
└─ [新增] 回写 SimCard.currentPlanName、planExpiry、dataUsedMb=0
4. 若 Eiotclub API 调用失败:
└─ DataPlanPurchase.fulfillmentStatus = 'failed'
└─ 写入 SimEvent(type='activation_failed', payload=error)
└─ 触发 admin 告警(或标记为待人工处理)
5. /account/services 展示激活成功的套餐
D.3 设备状态和 SIM 用量同步
触发方式一(Webhook 推送):
探鸽/Eiotclub 推送事件 → POST /api/webhooks/tange/device-event
└─ 解析 payload,写入 SimEvent
└─ 更新 SimCard(dataUsedMb、planExpiry、status)
└─ 更新 Device(status、firmwareVersion)
触发方式二(定时主动拉取):
Cron / 定时任务(Node cron 或 PM2 cron job)
每 30 分钟:遍历活跃 SimCard → 调用 eiotclub.getCardInfo(iccid)
└─ 回写 SimCard.dataUsedMb、dataTotalMb、lastSyncedAt
注意:VM 部署形态下,定时任务可用 PM2 ecosystem cron_restart
或在 Next.js 中暴露一个 /api/admin/sync 内部接口,由外部 cron 调用。
D.4 外部 Webhook 到站内状态更新
POST /api/webhooks/tange/device-event
├─ 验证签名(HMAC-SHA256,key = TANGE_WEBHOOK_SECRET)
├─ 写入 SimEvent(eventType, payload, processed=false)
└─ 根据 eventType 分发处理:
├─ 'device.online' / 'device.offline' → 更新 Device.status
├─ 'sim.usage_update' → 更新 SimCard 用量字段
├─ 'plan.expired' → 更新 SimCard.status + Entitlement.status=EXPIRED
└─ 'device.unbound' → 更新 DeviceOwnership(软删除或标记)
D.5 /account/devices 和 /account/services 内容来源
/account/devices 数据来源:
SELECT Device + DeviceOwnership WHERE userId = currentUser
JOIN SimCard WHERE SimCard.deviceUid = Device.deviceUuid
→ 展示:设备名称、序列号、绑定时间、SIM 状态、在线状态
/account/services 数据来源:
SELECT Entitlement WHERE userId = currentUser AND status = ACTIVE
SELECT DataPlanPurchase WHERE userId = currentUser ORDER BY createdAt DESC
SELECT SimCard WHERE userId = currentUser
→ 展示:云存储权益(有效期/配额)、流量套餐(余量/到期)
E. 数据模型与接口设计建议
E.1 现有字段直接复用
| 模型 | 可直接复用的字段 |
|---|---|
Device | deviceUuid(唯一键)、model、serialNumber、firmwareVersion、status |
DeviceOwnership | userId、deviceId、role、boundAt |
Entitlement | userId、deviceId、entitlementType、status、quota、startedAt、expiresAt |
SimCard | iccid、userId、deviceUid、status、dataUsedMb、dataTotalMb、planExpiry、lastSyncedAt |
DataPlanPurchase | eiotclubOrderId、fulfillmentStatus、activatedAt、expiresAt |
SimEvent | simCardId、eventType、payload、processed |
E.2 建议新增字段
model Device {
// 新增
tangeDeviceId String? // 探鸽平台内部设备ID
isOnline Boolean @default(false)
lastSeenAt DateTime?
syncError String? // 最近一次同步错误信息
lastSyncedAt DateTime?
}
model DeviceOwnership {
// 新增
unboundAt DateTime? // 软解绑时间,null = 仍绑定
}
model User {
// 新增
tangeUserId String? // 探鸽平台用户ID(首次 token 桥接后写入)
}
model Entitlement {
// 新增
tangeServiceId String? // 探鸽云服务的外部 ID
lastWebhookAt DateTime? // 最近一次 webhook 更新时间
}
model DataPlanPurchase {
// 新增
syncError String? // Eiotclub API 调用失败原因
}
E.3 新增 lib/tange.ts(探鸽 API Client)
// lib/tange.ts
// 探鸽云端 REST API client(区别于 Flutter SDK)
export async function getTangeToken(params: {
externalUserId: string // aovis userId
externalEmail: string
}): Promise<{ token: string; userId: number; expiresIn: number }>
export async function getTangeDeviceList(tangeToken: string): Promise<TangeDevice[]>
export async function bindTangeDevice(params: {
tangeToken: string
deviceUuid: string
}): Promise<{ tangeDeviceId: string }>
export async function activateCloudService(params: {
tangeDeviceId: string
serviceType: string // 'cloud_storage_7d' | 'cloud_storage_30d' 等
orderId: string
}): Promise<{ serviceId: string; expiresAt: string }>
E.4 填充 lib/eiotclub.ts
优先实现以下方法(移除 STUB 注释,实现真实 API 调用):
getCardInfo(iccid)— 套餐余量、到期时间查询(只读同步首选)subscribePackage(iccid, packageId)— 套餐激活(DataPlan 购买后调用)refreshUsage(iccid)— 手动触发用量刷新
E.5 新建 API 路由
| 路由 | 方法 | 用途 | 调用方 |
|---|---|---|---|
/api/tange/token | POST | 生成并返回探鸽 SDK token | Flutter APP |
/api/tange/device-bind | POST | 设备绑定写回 aovis DB | Flutter APP |
/api/webhooks/tange/device-event | POST | 接收探鸽设备事件推送 | 探鸽平台 |
/api/admin/devices | GET | 后台设备列表 | Admin UI |
/api/admin/sync/sim-cards | POST | 手动触发 SIM 用量同步 | Admin UI / Cron |
F. 分阶段研发计划
Phase 0:文档、账号与环境打通
目标:具备真实接入的所有前置条件。
任务清单:
- 联系探鸽团队申请:APPID、包名绑定、「自有账户登录」API 完整文档
- 确认探鸽沙箱环境地址和测试账号
- 确认探鸽 webhook 签名方式(HMAC key 申请)
- 确认探鸽云端管理 API 的 endpoint、认证方式、频率限制
- 联系 Eiotclub 获取真实 API credentials 和沙箱
- 在
.env中添加占位变量:TANGE_APP_ID、TANGE_API_BASE、TANGE_WEBHOOK_SECRET、EIOTCLUB_API_KEY、EIOTCLUB_API_SECRET
交付标准:能在本地用真实沙箱凭证调通一个探鸽 API(如获取 token)。
风险:供应商文档不完整或沙箱不稳定,导致 Phase 1 延迟。
Phase 1:Token 桥接与只读数据同步
目标:Flutter APP 能完成 SDK 初始化;后台能看到真实 SIM 卡数据。
涉及页面:/admin/sim-cards、Flutter APP 登录/启动流程
涉及后端模块:
- 新建
lib/tange.ts(实现getTangeToken) - 新建
app/api/tange/token/route.ts - 实现
lib/eiotclub.ts的getCardInfo、getAllCards
数据库变更:
ALTER TABLE "User" ADD COLUMN "tangeUserId" TEXT;
关键逻辑:
/api/tange/token需验证 NextAuth session,防止未授权调用- token 有效期管理:返回
expiresIn,APP 侧自行缓存,到期前重新请求 - SIM 数据同步:admin 页面增加"同步"按钮,调用
/api/admin/sync/sim-cards
风险:
- 探鸽「自有账户登录」API 参数格式未知(需要完整文档)
- Eiotclub API 可能需要 IP 白名单
验收标准:
- Flutter APP 能用 aovis 账号登录后调用
/api/tange/token获取有效 token - SDK
Authenticate.configure(token)返回 success - admin SIM 卡页能展示真实 Eiotclub 数据
Phase 2:设备绑定
目标:用户在 APP 内完成配网后,/account/devices 显示真实绑定设备;admin 设备页填充数据。
涉及页面:/account/devices(移除 disabled 限制)、/admin/devices
涉及后端模块:
- 新建
app/api/tange/device-bind/route.ts - 填充
app/api/admin/devices/route.ts - 更新
app/admin/devices/page.tsx(查询并展示真实数据)
数据库变更:
model Device {
tangeDeviceId String?
isOnline Boolean @default(false)
lastSeenAt DateTime?
lastSyncedAt DateTime?
syncError String?
}
model DeviceOwnership {
unboundAt DateTime?
}
model User {
tangeUserId String?
}
关键逻辑:
- 绑定接口需要幂等(同一 deviceUuid + userId 重复绑定不报错)
- 设备绑定后若用户已购买过云存储套餐,触发 Entitlement 补偿激活
风险:
- 配网流程(AP/蓝牙)纯由探鸽 SDK 负责,aovis 服务端只需接收回调
- 确保
/api/tange/device-bind有 CSRF 保护(验证 session)
验收标准:
- APP 配网成功后 aovis DB 中有对应 Device 和 DeviceOwnership 记录
/account/devices能显示设备基本信息/admin/devices管理员能看到所有用户的设备列表
Phase 3:套餐激活与履约闭环
目标:Data Plan 购买成功后自动激活,/account/services 展示真实套餐状态。
涉及页面:/account/services、/admin/data-plan-purchases
涉及后端模块:
- 修改
app/api/webhooks/data-plan/route.ts(购买成功后调用 Eiotclub API) - 实现
eiotclub.subscribePackage() - 新建
app/api/webhooks/tange/device-event/route.ts(接收外部事件)
关键逻辑:
// app/api/webhooks/data-plan/route.ts 修改点
// 原有:写入 DataPlanPurchase
// 新增:
try {
const result = await subscribePackage(iccid, eiotclubPackageId);
await prisma.dataPlanPurchase.update({
where: { id: purchase.id },
data: {
fulfillmentStatus: 'activated',
activatedAt: new Date(),
expiresAt: result.expiresAt,
eiotclubOrderId: result.orderId
}
});
await prisma.simCard.update({
where: { iccid },
data: { currentPlanName: plan.name, planExpiry: result.expiresAt, dataUsedMb: 0 }
});
} catch (err) {
// 不影响支付确认,记录失败待补偿
await prisma.dataPlanPurchase.update({
where: { id: purchase.id },
data: { fulfillmentStatus: 'failed', syncError: err.message }
});
await prisma.simEvent.create({
data: { simCardId, eventType: 'activation_failed', payload: { error: err.message } }
});
}
风险:
- Eiotclub API 失败不能回滚 Stripe 支付,需人工补偿机制
- 套餐激活有时延,需考虑异步状态轮询
验收标准:
- 购买 Data Plan 后 1 分钟内 SimCard.planExpiry 更新
/account/services显示真实套餐到期时间和用量- admin 能查看 fulfillmentStatus 和失败原因
Phase 4:云服务/订阅联动(Entitlement 自动授权)
目标:购买云存储订阅后自动开通探鸽云服务,Entitlement 状态与探鸽平台同步。
涉及页面:/account/services(云存储展示)
涉及后端模块:
- 修改
app/api/stripe/webhook/route.ts或lib/checkout-fulfillment.ts - 实现
lib/tange.ts的activateCloudService() - 建立 Entitlement 与探鸽云服务 ID 的映射
数据库变更:
model Entitlement {
tangeServiceId String?
lastWebhookAt DateTime?
}
验收标准:
- 用户购买云存储套餐后,Entitlement 状态自动变为 ACTIVE
- 探鸽 APP 内能看到云存储服务已开通
Phase 5:运维监控、失败补偿与后台运营能力
目标:系统可观测,失败可恢复,运营可介入。
任务清单:
- Admin 设备页:支持手动触发设备状态同步
- Admin 数据套餐购买页:展示
fulfillmentStatus,支持手动重试激活 - Admin SIM 卡页:展示同步时间和错误,支持手动刷新
- 定时同步:PM2 cron job 定期调用 SIM 用量同步接口
- Webhook 签名验证:实现 HMAC 校验(目前 eiotclub webhook 无签名验证)
- 错误告警:fulfillmentStatus='failed' 超过阈值时触发邮件通知
风险:定时任务在 VM 重启后需确保 PM2 自动重启。
G. 风险、依赖和待确认问题清单
G.1 外部依赖(必须在 Phase 0 解决)
| 依赖项 | 当前状态 | 需要获取 |
|---|---|---|
| 探鸽「自有账户登录」API 文档 | Apifox 需登录查看 | 向探鸽团队索取完整 endpoint + 参数 |
| 探鸽 APPID | 未申请 | 提供包名给探鸽申请 |
| 探鸽沙箱环境 | 未知 | 确认是否提供 staging 环境 |
| 探鸽 webhook 签名密钥 | 未申请 | 申请 TANGE_WEBHOOK_SECRET |
| 探鸽云端管理 API 文档 | 飞书 wiki 云端管理页 not found | 重新获取正确的 wiki 链接 |
| Eiotclub 真实 API credentials | STUB 状态 | 联系 Eiotclub 获取 API Key/Secret |
| Eiotclub IP 白名单 | 未确认 | 确认 VM 出口 IP 是否需要加白 |
G.2 工程风险
| 风险 | 等级 | 缓解措施 |
|---|---|---|
| 探鸽 API 不稳定影响 token 下发 | 高 | token 在服务端缓存(Redis 或内存),有效期内不重复请求 |
| Eiotclub 套餐激活失败导致用户已付费但未开通 | 高 | fulfillmentStatus='failed' + admin 可见 + 手动补偿接口 |
| schema 变更破坏现有数据 | 中 | 所有新字段均为 nullable,Prisma migrate 不影响现有记录 |
| webhook 伪造攻击 | 中 | 实现 HMAC 签名验证,优先于 Phase 3 前完成 |
| 设备 UUID 冲突(同一设备被多用户绑定) | 低 | DeviceOwnership 允许多条记录,OWNER 只能有一个(添加唯一约束) |
G.3 明确不在范围内的事项
- Shopify / refund / coupon / Apple IAP / Google Play Billing
- 推翻现有前台 UI 设计
- 修改现有 Stripe 支付链路(只扩展 webhook 后续逻辑)
- 引入新的账号体系(aovis NextAuth 账号继续作为唯一账号)
- 设备实时视频流在服务端中转(纯 P2P,SDK 负责)
G.4 待确认问题列表
- 探鸽「自有账户登录」API 的完整请求格式(参数、签名方式)是什么?
- 探鸽是否提供沙箱/测试环境?
- 探鸽 APPID 与 aovis 的包名绑定流程是什么?需要提供哪些信息?
- 飞书 wiki 中「云端管理」章节(token: EtrqwBPl5iHbBikbGycchNpDnfb)无法访问,需要重新获取链接
- Eiotclub API 是否有 IP 白名单要求?
- 设备绑定成功后,探鸽是否通过 webhook 主动推送,还是需要 APP 轮询?
- 套餐激活是否有时延(SLA)?如超时应如何处理?
- 探鸽平台的设备 UUID 与我们当前
Device.deviceUuid字段是否格式一致?
文档由 Claude Code 基于探鸽 SDK 飞书文档(rapid_kit)和 aovis.app 项目现状综合生成。 探鸽 SDK 文档来源:https://tange-ai.feishu.cn/wiki/Nj3pwV2HcimkUxk8dcScjfFUnQb
附录:当前独立站真实研发基线(供后续接手人快速对齐)
1. 前台站点当前不是纯展示站
- 首页、商品页、购物车、结账成功/取消页、条款/隐私/运输/退货/支持/联系页已经完成。
- 商品页、购物车、下单流程、订单中心都已和数据库、登录态、Stripe Checkout 打通。
- 当前公开站点围绕
NEXA Prime 4K做统一展示,且要求与aovis.app内容和结构方向保持一致。 - 现阶段不应推翻前台 UI,只应在现有结构里继续填充设备和云服务能力。
2. 账户与后台已具备真实基础设施
- Auth.js v5 + Prisma Adapter 已落地,支持 Google / Apple / Email Magic Link。
/account下已有 Overview / Profile / Orders / Devices / Services。/admin下已有订单、支付、客户、服务、Data Plans、SIM Cards、Data Plan Purchases、Access 等运营视图。- Admin 访问控制已具备两层模型:
ADMIN_EMAILS环境变量白名单AdminAccess数据库表托管授权
3. 已完成并验证的真实链路
- 硬件商品购买:
POST /api/cartPOST /api/checkoutPOST /api/stripe/webhook
- 支付成功后会创建 / 更新
Order、Payment、ShippingAddress,并在账户订单中心可见。 - Stripe test mode 已验证通过;live mode readiness 文档与环境规范已建立。
- Data Plan 购买链路也已成形:
POST /api/checkout/data-planPOST /api/webhooks/data-plan- 支付成功后会写入
DataPlanPurchase
4. 已预埋但尚未真实打通的能力
Device/DeviceOwnership已有模型和页面,但真实设备绑定尚未实现。Subscription/Entitlement已有模型、展示和 seed 数据,但 entitlement 自动发放尚未实现。SimCard/DataPlan/DataPlanPurchase/SimEvent已经形成一套完整的数据结构和后台视图。/account/devices和/account/services已能展示这些能力的壳层和数据库内容,但很多动作仍是 disabled / coming soon。
5. 外部设备云 / 运营商 API 的当前准备度
lib/eiotclub.ts已预留 IoT 平台 API client 结构,但目前仍是STUB:getCardInfogetAvailablePackagesrefreshUsagesubscribePackagegetAccountBalancebindDevicegetAllCards
- 上述方法当前没有真实 HTTP 请求实现,也还没有完成签名逻辑。
POST /api/webhooks/eiotclub已能接收外部 webhook 并把事件写入SimEvent,但还没有做业务状态推进。- 这意味着项目已经具备“外部 API 接入位”和“站内承接模型”,下一阶段应在此基础上填充探鸽 / 云服务真实能力,而不是重做架构。
6. 对下一阶段最重要的判断
- 当前项目已经完成“独立站电商 + 账户中心 + 订单支付 + 后台运营基础”。
- 当前项目还没有完成“探鸽 SDK + 设备绑定 + 云服务状态同步 + 套餐自动履约”。
- 下一阶段研发的正确方向是:
- 复用现有 Prisma 模型
- 复用现有 account/admin 页面
- 复用现有 Stripe 购买链路
- 在现有 Route Handlers 和
lib/*service 层中补齐探鸽与供应商对接