AOVIS AI Push Pipeline Sprint 1 部署与验证归档
归档日期:2026-05-17 关联文档:
ai-push-pipeline-implementation-plan.md
1. 范围
本次 Sprint 1 实现了 Type 1 实时分类推送的后端完整链路(IoT webhook → S3 GetObject → Nova Lite thumbnail classification → CloudEvent 持久化 → SNS endpoint push 函数层),不含以下部分:
- 手机 App push token 注册与真机推送(依赖 App 端开发完成)
- SNS Platform Application 配置(APNS p8 key / FCM credentials 未就绪)
- Daily Summary / Type 2 推送(Sprint 2 独立任务)
- 边端 SoC 缩略图抓取与上传协议(Sprint 3 跨团队)
2. 代码与部署
| 项目 | 值 |
|---|---|
| Release commit | dc538791f4befdb551876b67b1195e6ecc879d7a |
| 部署路径 | /opt/aovis/aovis-store-staging |
| PM2 进程 | aovis-store-aws |
| Prisma Migrations | 20260517000000_add_cloud_event, 20260517000000_add_push_token |
npm run build | 通过 |
pm2 restart | 通过 |
npm run deploy:verify | 7/7 通过 |
3. 本次新增能力
| 组件 | 文件/位置 | 说明 |
|---|---|---|
| PushToken 模型 | prisma/schema.prisma | 用户设备 push token 注册表,含 endpointArn 回填 |
| CloudEvent 模型 | prisma/schema.prisma | AI 分类结果持久化,含 pushSent 状态追踪 |
| Push token 注册 API | app/api/internal/push/register/route.ts | POST /api/internal/push/register,接收 App token 并创建 SNS Platform Endpoint |
| Bedrock 缩略图分类器 | lib/aws/bedrock-thumbnail.ts | Nova Lite (us.amazon.nova-lite-v1:0 messages-v1) 分类缩略图 JPEG |
| SNS endpoint push | lib/aws/sns.ts | createPlatformEndpoint, deletePlatformEndpoint, sendPushToEndpoint |
| IoT 事件 worker | lib/aws/event-push-worker.ts | fire-and-forget 异步工作流:S3 → Bedrock → CloudEvent → SNS push |
| IoT webhook 路由 | app/api/internal/aws/iot-event/route.ts | HMAC 验证 + dedup + fire-and-forget 触发 worker |
| 推送文案格式化 | lib/aws/event-push-format.ts | 英文 push title,≤50 chars |
| 事件类型白名单 | lib/aws/iot-event-types.ts | IotEventPayload 接口定义 |
| SNS Platform 创建脚本 | scripts/deploy/setup-sns-platform-apps.sh | 幂等创建 APNS/FCM Platform Application,支持 --dry-run |
4. 生产/测试验证过程
4.1 Preflight
npm run build通过npm run deploy:verify7/7 通过- PM2 重启后进程正常
4.2 S3 exact object 验证
在 VM 上确认 aovis-backend-service IAM user 可 HeadObject + GetObject 读取测试 JPEG:
s3://aovis-video-storage/thumbnails/aovis-n4k-000001/sprint1-test-20260517155241.jpg
ContentLength=111015, ContentType=image/jpeg, magic bytes=ff d8 ff ✅
HeadBucket (s3:ListBucket) 返回 403 但非阻塞——worker 仅使用 GetObjectCommand。
4.3 Mock IoT event 第一次(IAM 失败)
event_id: sprint1-mock-1779004660458
webhook: 200 {"received":true}
| 表 | 结果 |
|---|---|
| IotEvent | created, processed=false |
| CloudEvent | created, status=failed |
| PushToken count | 0 |
错误日志:
[event-push-worker] classifyThumbnails failed
AccessDeniedException:
User: arn:aws:iam::288669178338:user/aovis-backend-service
is not authorized to perform: bedrock:InvokeModel
on resource: arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-lite-v1:0
4.4 IAM 修复
- User:
aovis-backend-service(IAM account288669178338) - Policy:
aovis-backend-service-policyv3 → v5 - 变更:Nova Lite foundation model 和 inference profile ARN 由固定
us-east-1改为通配 region* - 理由:cross-region inference profile
us.amazon.nova-lite-v1:0动态路由到us-west-2/us-east-2/us-east-1等 - 约束仍精确到
bedrock:InvokeModel+amazon.nova-lite-v1:0/us.amazon.nova-lite-v1:0
4.5 Bedrock direct test
在 VM 上用 @aws-sdk/client-bedrock-runtime 直接调用 Nova Lite:
eventType: other
confidence: 0.95
summary: "Diagram of AOVIs Avare Prime 4K camera features"
durationMs: 849
tokens: { input: 834, output: 45 }
测试图片是旧版 OG sample(含 Avare 品牌文字),Nova 输出 Avare 字样属正常的模型识别结果,非 prompt 污染。
4.6 Mock IoT event 第二次(全链路通过)
event_id: sprint1-mock-bedrockfix-1779005092627
webhook: 200 {"received":true}
| 表 | 结果 |
|---|---|
| IotEvent.processed | true |
| IotEvent.processedAt | 2026-05-17T08:04:53.725Z |
| CloudEvent.status | classified |
| CloudEvent.classifyEventType | other |
| CloudEvent.classifyConfidence | 0.95 |
| CloudEvent.classifySummaryShort | "Diagram of AOVIs Avare Prime 4K camera features" |
| CloudEvent.s3ThumbnailKey | thumbnails/aovis-n4k-000001/sprint1-test-20260517155241.jpg |
| CloudEvent.pushSent | false |
| Active PushToken count | 0 |
pushSent=false 符合预期——没有注册的真机 APNS/FCM token。
5. 验证结果
| 链路 | 状态 | 证据 |
|---|---|---|
| Webhook HMAC 鉴权 | ✅ | 200 {"received":true} |
| JSON 解析与字段校验 | ✅ | 同上 |
| IoT 事件写 IotEvent 表 | ✅ | DB 记录存在 |
| IotEvent dedup | ✅ | 相同 payload 返回 duplicate |
| shouldTriggerPushProcessing 白名单 | ✅ | motion 事件触发 worker |
| S3 GetObject 缩略图 | ✅ | 111015 bytes JPEG 正确读取 |
| Nova Lite thumbnail classification | ✅ | eventType=other, confidence=0.95, 849ms |
| CloudEvent 持久化 | ✅ | status=classified, 字段完整 |
| IotEvent.processed 更新 | ✅ | processed=true |
| SNS endpoint push(deferred) | ⏳ | pushSent=false(无 token) |
| PushToken endpoint count | ⏳ | 0(App 端未完成) |
6. 当前剩余边界
- 真机 push 推迟到手机 App 端开发完成、调用
POST /api/internal/push/register注册 token SNS_APNS_PLATFORM_ARN/SNS_FCM_PLATFORM_ARN未配置(需 Apple p8 key + Firebase credentials)- PushToken
endpointArn数量 = 0 - 固件
thumbnail_s3_key协议仍属 Sprint 3(跨团队) - 测试 JPEG 使用了旧 sample 图(含 Avare 字样),后续正式上线前替换为产品缩略图
7. 后续动作
- App 端完成 push token 注册后,测
POST /api/internal/push/register - 配置 SNS Platform Application ARNs(运行
setup-sns-platform-apps.sh) - 用真实事件缩略图再发 mock IoT event,验证
pushSent=true - Sprint 2 Daily Summary 另起任务