跳到主要内容

Device Binding & Integration Readiness — Interface Contract Matrix

Version: 1.0 | Date: 2026-05-12
Purpose: Map every external interface to its source-of-truth document, current code state, and sample-integration readiness.
This is a working document, not a production spec. Provisional contracts are explicitly marked.


1. Document Source List

#DocumentPathSource of Truth For
D01AGENTS.mdAGENTS.mdProject rules, brand, scope boundaries, deploy SOP
D02AOVIS App 登录认证接口规范 v1.0docs/AOVIS_App_登录认证接口规范_v1.0.mdApp auth API contract
D03App JWT Token Issuancedocs/app-jwt-token-issuance.mdApp token lifecycle
D04Mobile App Auth API Handoffdocs/mobile-app-auth-api-handoff.mdApp auth architecture context
D05EIOTCLUB Apifox Exportdocs/eiotclub-apifox-export.mdEIOTCLUB API sign, error codes, card/package APIs
D06EIOTCLUB Claude Dev Briefdocs/eiotclub-claude-dev-brief.mdEIOTCLUB implementation guidance
D07EIOTCLUB Integration Handoffdocs/eiotclub-integration-handoff.mdEIOTCLUB state machine, dedup, webhook mapping
D08EIOTCLUB Integrationdocs/eiotclub-integration.mdEIOTCLUB env vars, IP whitelist, smoke tests
D09Stripe Data Plan Webhook Setupdocs/stripe-data-plan-webhook-setup.mdData plan webhook contract
D10AWS KVS Technical Quickstart PDFOnedrive path (see below)AWS KVS/IoT/Cognito architecture
D11Prisma Schemaprisma/schema.prismaData models
D12.env.example.env.exampleEnv var baseline

PDF path: /Users/guorui/Library/CloudStorage/OneDrive-Personal/IP Camera/AWS KVS/AOVIS — AWS 技术快速上手指南.pdf


2. Interface Contract Matrix

2.1 App Auth Token

FieldValue
Source of TruthD02 §4.1, D03 §3.1
Current Codeapp/api/auth/app-token/route.ts, lib/app-token.ts, lib/verify-app-request.ts
Current StatePartially compliant
IssuesMissing invalid_provider error (currently returns invalid_token for bad provider); missing_fields returns invalid_token instead of 400
Fix NeededAdd provider validation → invalid_provider (400); missing fields → missing_fields (400)
VerificationUnit test: bad provider returns 400, missing fields returns 400
Affects Production Payment/AuthNo
Formal or ProvisionalFormal (per D02)
FieldValue
Source of TruthD02 §4.2
Current Codeapp/api/auth/app-magic-link/route.ts
Current StateCompliant
IssuesNone identified
Fix NeededNone
VerificationExisting test coverage
Affects Production Payment/AuthNo
Formal or ProvisionalFormal

2.3 App Token Revoke

FieldValue
Source of TruthD02 §4.4, D03 §3.4
Current Codeapp/api/auth/app-token/route.ts (DELETE handler)
Current StateCompliant
IssuesNone identified
Fix NeededNone
VerificationUI test: DELETE with valid token returns {revoked: true}, subsequent usage returns 401
Affects Production Payment/AuthNo
Formal or ProvisionalFormal

2.4 Stripe Data Plan Checkout

FieldValue
Source of TruthD09
Current Codelib/data-plans.ts, app/api/checkout/data-plan/route.ts
Current StateCompliant
IssuesNone identified
Fix NeededNone
VerificationCheckout flow test
Affects Production Payment/AuthNo (separate endpoint)
Formal or ProvisionalFormal

2.5 Stripe Data Plan Webhook

FieldValue
Source of TruthD09
Current Codeapp/api/webhooks/data-plan/route.ts
Current StateNon-compliant
Issues(1) Missing STRIPE_DATA_PLAN_WEBHOOK_SECRET returns 200 instead of 500. (2) stripeSessionId lacks unique constraint in DB. (3) Signature errors return 200 not 400.
Fix NeededReturn 500 when secret missing; add @unique on DataPlanPurchase.stripeSessionId; return 400 on signature error
VerificationUnit test: no secret → 500; bad signature → 400; replay → only one purchase
Affects Production Payment/AuthYes — webhook path
Formal or ProvisionalFormal

2.6 EIOTCLUB API Request Signing

FieldValue
Source of TruthD05 (sign algorithm), D06, D07
Current Codelib/eiotclub.tsbuildSignatureSource(), generateSign()
Current StateCompliant
IssuesNone — golden sample test passes
Fix NeededNone
VerificationGolden sample test in lib/__tests__/eiotclub-sign.test.ts
Affects Production Payment/AuthNo (EIOTCLUB outbound)
Formal or ProvisionalFormal

2.7 EIOTCLUB Webhook Signing

FieldValue
Source of TruthD05 (sign algorithm — webhooks exclude appkey), D07
Current Codelib/eiotclub.tsverifyCallbackSignature()
Current StateNon-compliant (security)
IssuesSecret leaked in logs. Logs include stringParmSign: source which contains the full secret=xxx value. Also in app/api/webhooks/eiotclub/route.ts line 117.
Fix NeededRedact secret from webhook signature failure logs. Log hash or truncated expected/received sign only.
VerificationAudit logs must not contain secret=; use rg "secret=" to confirm
Affects Production Payment/AuthNo (security hardening)
Formal or ProvisionalFormal

2.8 EIOTCLUB Webhook PkgEffective (Package Activated)

FieldValue
Source of TruthD07 (event mapping table)
Current Codelib/eiotclub-webhook-handlers.tshandlePackageActivated()
Current StateCompliant
IssuesNone identified
Fix NeededNone
VerificationTest passes: webhook promotes purchase to ACTIVE
Affects Production Payment/AuthNo (webhook path)
Formal or ProvisionalFormal

2.9 EIOTCLUB Webhook Refund

FieldValue
Source of TruthD07
Current Codelib/eiotclub-webhook-handlers.tshandleRefund()
Current StateCompliant
IssuesNone identified
Fix NeededNone
VerificationTest passes: refund → REFUNDED; replay → duplicate
Affects Production Payment/AuthNo (webhook path)
Formal or ProvisionalFormal

2.10 EIOTCLUB SIM Usage / Flow Alert

FieldValue
Source of TruthD07
Current Codelib/eiotclub-webhook-handlers.tshandleFlowWarning()
Current StateCompliant
IssuesNone identified
Fix NeededNone
VerificationManual via replay script
Affects Production Payment/AuthNo
Formal or ProvisionalFormal

2.11 Device Binding / Activation

FieldValue
Source of TruthNo formal document exists. Only informal references in README and AGENTS.md
Current Codeapp/api/devices/activate/route.ts
Current StateNon-compliant (provisional only)
Issues(1) No proof-of-possession (accepts aovis_device_id alone). (2) Does NOT create DeviceOwnership record. (3) Writes directly to Device.ownerUserId without unified ownership model. (4) No audit log. (5) No activation code / claim token / QR secret. (6) Stripe payment success is NOT distinguished from entitlement activation. (7) AWS provisioning in activation is provisional (registerDevice creates real AWS resources which may fail in non-configured environments).
Fix NeededAdd DeviceOwnership creation; add audit log; distinguish ownerUserId vs DeviceOwnership source of truth; mark as provisional
VerificationTest: activation creates DeviceOwnership; same-user reactivation is idempotent; other-user activation returns 403
Affects Production Payment/AuthNo (deferred feature)
Formal or ProvisionalProvisional — Sample Integration Contract

2.12 DeviceOwnership

FieldValue
Source of TruthD11 (Prisma schema)
Current Codeprisma/schema.prismaDeviceOwnership model
Current StatePartially compliant
IssuesDeviceOwnership exists as a join table with unique (deviceId, userId) constraint, but device activation writes to Device.ownerUserId instead of creating DeviceOwnership. The account devices page reads from DeviceOwnership.
Fix NeededDevice activation must create DeviceOwnership record. Make DeviceOwnership the unified source of truth for ownership checks.
VerificationAfter activation, DeviceOwnership exists for userId
Affects Production Payment/AuthNo
Formal or ProvisionalFormal (model) / Provisional (activation flow)

2.13 SIM / ICCID / EID / IMSI Relationship

FieldValue
Source of TruthD11 (SimCard model), D05 (EIOTCLUB API fields)
Current Codeprisma/schema.prismaSimCard model
Current StateCompliant
IssuesICCID lacks front-end masking (only data-plans.ts maskIccid exists). Need to ensure ICCID not returned in public API responses.
Fix NeededAdd ICCID masking helper for public API responses
Verificationgrep for ICCID exposure in public API responses
Affects Production Payment/AuthNo
Formal or ProvisionalFormal

2.14 KVS Stream Access

FieldValue
Source of TruthD10 (PDF §架构, §App/Web端)
Current Codeapp/api/devices/[id]/stream/route.ts, lib/aws/kvs.ts
Current StatePartially compliant
Issues(1) verifyDeviceAccess checks ownerUserId but NOT DeviceOwnership. (2) No entitlement check. (3) AWS SDK clients use default credential chain (may fall back to env vars causing long-term key exposure concern; but actually only region is set in awsConfig). (4) No assertDeviceServiceAccess unified function. (5) No mockable service layer — currently creates real AWS clients.
Fix NeededCreate lib/aws/device-service-access.ts with assertDeviceServiceAccess(); add entitlement check
VerificationTest: non-owner gets 404; owner without entitlement gets 403
Affects Production Payment/AuthNo (KVS is future feature)
Formal or ProvisionalProvisional — Sample Integration Contract

2.15 KVS Clip Access

FieldValue
Source of TruthD10 (PDF §GetClip API)
Current Codeapp/api/devices/[id]/clip/route.ts, lib/aws/kvs.ts
Current StateSame as Stream Access
IssuesSame as KVS Stream Access
Fix NeededSame as KVS Stream Access
Formal or ProvisionalProvisional

2.16 KVS WebRTC Access

FieldValue
Source of TruthD10 (PDF §KVS WebRTC)
Current Codeapp/api/devices/[id]/webrtc/route.ts, lib/aws/kvs-webrtc.ts
Current StateSame as Stream Access
IssuesSame as KVS Stream Access. Additionally: WebRTC endpoints expose channel_arn directly in response.
Fix NeededSame as KVS Stream Access
Formal or ProvisionalProvisional

2.17 IoT Event Ingestion

FieldValue
Source of TruthD10 (PDF §IoT Rule / Lambda data flow)
Current Codeapp/api/internal/aws/iot-event/route.ts
Current StateNon-compliant
Issues(1) HMAC timingSafeEqual called without length check — will throw if signature length differs from expected. (2) No timestamp window for replay protection. (3) No dedup key / event id. (4) No audit log for failures/duplicates. (5) No structured error logging.
Fix NeededAdd length check before timingSafeEqual; add timestamp window; add dedup via event hash; add audit logging
VerificationTest: bad sig returns 401, stale timestamp rejected, replay rejected
Affects Production Payment/AuthNo (future IoT path)
Formal or ProvisionalProvisional — Sample Integration Contract

2.18 AI Event / Bedrock Nova Lite

FieldValue
Source of TruthD10 (PDF §AI 事件分类), PDF model ID: us.amazon.nova-lite-v1:0
Current Codelib/aws/bedrock.ts
Current StatePartially compliant
Issues(1) No ownership check before AI analysis. (2) No entitlement check. (3) Uses full video to Bedrock (not thumbnail/frame). (4) Model ID default is us.amazon.nova-pro-v1:0 not us.amazon.nova-lite-v1:0.
Fix NeededAdd ownership+entitlement check; change default to lite model for classification; add env for not_configured handling
VerificationTest: non-owner gets 403; not_configured returns feature_disabled
Affects Production Payment/AuthNo
Formal or ProvisionalProvisional

2.19 Entitlement Check

FieldValue
Source of TruthD11 (Entitlement model), implied by PDF
Current Codelib/entitlement.ts (not yet read, but referenced in activate route)
Current StateNot integrated
IssuesNo unified entitlement check in device service access layer. startTrial() is called on activation but no assertDeviceServiceAccess capability check.
Fix NeededCreate assertDeviceServiceAccess() that checks ownership + entitlement
VerificationTest: access without entitlement returns 403
Affects Production Payment/AuthNo
Formal or ProvisionalProvisional

2.20 AuditLog

FieldValue
Source of TruthD11 (DataPlanPurchaseAuditLog, OrderAuditLog)
Current Codeprisma/schema.prisma — per-model audit logs
Current StatePartially compliant
IssuesNo unified AuditLog model. Each domain has its own audit log (DataPlanPurchaseAuditLog, OrderAuditLog, SimEvent). Missing audit for: device activation/binding, admin auth, IoT event failures.
Fix NeededAdd audit log creation in device activation; add IoT event failure audit
VerificationTest: activation creates audit entry
Affects Production Payment/AuthNo
Formal or ProvisionalProvisional

2.21 Checkout Success IDOR

FieldValue
Source of TruthSecurity best practice
Current Codeapp/checkout/success/page.tsxgetOrderByCheckoutSessionId(sessionId)
Current StateNon-compliant (security)
IssuesThe success page does NOT check if the logged-in user owns the order. getOrderByCheckoutSessionId looks up by session_id without userId filter.
Fix NeededAdd userId check: if user is logged in, verify order.userId === session.user.id; if not logged in (guest), show minimal info only.
VerificationTest: user A cannot see user B's order via session_id
Affects Production Payment/AuthYes — order PII exposure
Formal or ProvisionalFormal (security fix)

3. Required But Missing Environment Variables

The following AWS env vars are required by code but missing from .env.example:

Env VarUsed InStatus
AWS_COGNITO_USER_POOL_IDNot yet usedMissing — App auth should reference
AWS_COGNITO_CLIENT_IDNot yet usedMissing
AWS_COGNITO_IDENTITY_POOL_IDNot yet usedMissing
AWS_IOT_CREDENTIAL_PROVIDER_ENDPOINTNot yet usedMissing
AWS_IOT_ROLE_ALIASNot yet usedMissing
AWS_KVS_PLAYBACK_ROLE_ARNNot yet usedMissing
AWS_KVS_WEBRTC_ROLE_ARNNot yet usedMissing

Note: Per AGENTS.md §4, these AWS env vars are intended for Cognito-based device/app access but no Cognito pool is configured yet. Current code uses awsConfig = { region } only, relying on the default AWS credential chain (env vars, ~/.aws/credentials, etc.). This is acceptable for provisional readiness but not for production.


4. Required Prisma Schema Changes

ChangeReasonRisk
DataPlanPurchase.stripeSessionId@uniquePrevent duplicate purchase from webhook replayMedium — requires migration
DataPlanPurchase.stripePaymentId@uniquePrevent duplicate from payment webhookMedium — requires migration, some may be null

5. Summary: Changes Required for Sample Integration Readiness

#FileChangeRiskCategory
1lib/eiotclub.tsRedact secret from signature failure logsLowSecurity
2app/api/webhooks/eiotclub/route.tsRedact secret from signature failure logsLowSecurity
3app/api/webhooks/data-plan/route.tsMissing secret → 500; bad sig → 400MediumPayment
4prisma/schema.prismaAdd @unique on stripeSessionIdMediumDB
5app/api/devices/activate/route.tsCreate DeviceOwnership; add audit log; add activation proofMediumDevice
6app/api/devices/[id]/*/route.tsUse unified assertDeviceServiceAccessLowDevice/KVS
7lib/aws/verify-device-access.tsAdd entitlement check; use DeviceOwnershipLowKVS
8lib/aws/iot-event/route.tsFix timingSafeEqual; add timestamp window; add dedupMediumIoT
9app/checkout/success/page.tsxAdd userId ownership checkHighSecurity/IDOR
10lib/commerce.tsFilter order by userId in getOrderByCheckoutSessionIdHighSecurity/IDOR
11.env.exampleAdd missing AWS env varsLowConfig
12lib/aws/device-service-access.ts (new)Create assertDeviceServiceAccess()LowNew util
13Tests (multiple files)Add coverage for all fixesMediumTesting

6. Decision Record

DecisionRationale
assertDeviceServiceAccess as separate moduleKeeps ownership+entitlement check centralized, replaceable
Provisional activation endpoint → keep but fixNeed some endpoint for sample integration before formal provisioning contract
No new AuditLog model → use per-model logsConsistent with current pattern; DataPlanPurchaseAuditLog and OrderAuditLog already exist
Add IotEvent.dedupKey fieldEnable reliable dedup for IoT event ingestion
No DeviceAwsResource model yetCurrent schema embeds AWS fields on Device; adding a separate model would be a cleaner abstraction but unnecessary for sample readiness