Files
sf-app-platform/Resumen_Integracion_Juphoon.md

9.0 KiB

Integración Videollamadas Juphoon — Resumen del progreso

Contexto

SaveFamily S.L (Bizkaia) está integrando videollamadas y chat entre su app móvil Flutter y sus smartwatches infantiles (RTOS/Android), usando el SDK de Juphoon (jc_sdk).

Actores:

  • Grupo SaveFamily S.L — Cliente, dueño de la app y backend
  • Shenzhen i365-Tech Co., Limited (Jane Zhang, Carmen) — Fabricante hardware, intermediario comercial
  • Juphoon/JUQU (Allen) — Proveedor del SDK de videollamadas
  • SeTracker — Proveedor del firmware del reloj y servidores auxiliares

Cotización aprobada: $8,835 (Integración $2,200 + Chat $2,950 + Cloud Photo Album $735 + Encryption $2,950)


Lo que se hizo

1. Análisis de documentación (3 rondas)

  • Ronda 1 (31-03-2026): 50 preguntas técnicas → 27/50 respondidas (54%)
  • Ronda 2 (01-04-2026): 17 preguntas generales → 17/17 respondidas (calidad desigual)
  • Ronda 3 (09-04-2026): Documentación oficial SDK recibida — Quickstart V1.1 Flutter (13 páginas), sequence diagrams, protocolo TCP, connection/mutual dialing process
  • Documentos generados: análisis completo, conclusiones, preguntas bilingües ES/EN, análisis cruzado de respuestas

2. Cuenta Juphoon Cloud creada (16-04-2026)

  • Consola: juphoon.com (+34)
  • App creada: "SaveFamily" (tipo IoT, escenario Smartwatch)
  • AppKey: 9efcf2d889dc8a0320925096
  • AppSecret: ui7pr73ggl5rr0gf01np (solo backend)
  • AES_KEY IoT: 8e3637pG7E9144E0 (solo backend)
  • Token auth activado en consola

3. Paquete packages/videocall_sdk/ creado

Wrapper 100% del jc_sdk v2.16.5 con arquitectura sólida (patrón sca_treezor del monorepo):

  • 7 servicios cubriendo toda la API pública del SDK:
    • VideocallClient → JCClient (auth, login, logout, messaging)
    • VideocallCallService → JCCall (llamadas 1-to-1)
    • VideocallDeviceService → JCMediaDevice (cámara, mic, speaker)
    • VideocallChannelService → JCMediaChannel (llamadas grupales)
    • VideocallPushService → JCPush (push notifications)
    • VideocallNetService → JCNet (estado de red)
    • VideocallLogService → JCLog (logging)
  • Constructor injection (no singletons estáticos)
  • GetIt module (videocallSdkModule(config))
  • VideocallSdkManager orquestador de inicialización (Client → Device → Call/Channel/Push)
  • VideocallSdkConfig abstracto para config por entorno
  • Riverpod providers + StreamProviders para UI reactiva
  • Callbacks del SDK → Dart Streams

4. Permisos nativos configurados

  • Android: RECORD_AUDIO, ACCESS_WIFI_STATE, MODIFY_AUDIO_SETTINGS, BLUETOOTH + uses-feature (camera, bluetooth) + ProGuard rules (juphoon, justalk)
  • iOS: NSMicrophoneUsageDescription, NSPhotoLibraryUsageDescription, NSCameraUsageDescription actualizado + Podfile GCC_PREPROCESSOR_DEFINITIONS (PERMISSION_CAMERA, PHOTOS, MICROPHONE)

5. AppKey configurado por entorno

  • juphoonAppKey en development.json, staging.json, production.json
  • Environment.juphoonAppKey via String.fromEnvironment()
  • SaveFamilyVideocallConfig implementa VideocallSdkConfig
  • videocallSdkModule(config) integrado en init_app.dart

6. Feature videocall/ creada en device_management

Feature completa siguiendo el patrón del monorepo (builder + domain + data + presentation):

Domain:

  • videocall_error.dart — enums de error/success/screenMode
  • videocall_participant.dart — entidad Freezed para participantes grupales
  • videocall_signaling_repository.dart — interface señalización backend

Data:

  • videocall_signaling_datasource.dart — interface
  • videocall_signaling_datasource_impl.dart — placeholder (TODO cuando backend dé spec)
  • videocall_signaling_repository_impl.dart — impl

State:

  • videocall_view_state.dart — Freezed state 1-to-1 (screenMode, sdk ready, mic/speaker/camera, canvas, error/success events)
  • videocall_view_model.dart — Notifier 1-to-1 (init, login, call, answer, hangup, mute, speaker, camera, streams del SDK)
  • group_call_view_state.dart — Freezed state grupal
  • group_call_view_model.dart — Notifier grupal (join, leave, participants, streams)

Widgets:

  • video_view_widget.dart — renderiza JCMediaDeviceVideoCanvas (iOS/Android)
  • call_controls_widget.dart — mic, speaker, camera, hangup (botones circulares)
  • call_status_indicator.dart — "Llamando...", "Conectando..."
  • incoming_call_overlay.dart — aceptar/rechazar llamada entrante (fullscreen)
  • participant_tile_widget.dart — tile individual con video + nombre
  • participant_grid_widget.dart — grid responsivo de participantes

Screen:

  • videocall_screen.dart — 4 modos: idle (input userID + botón llamar), outgoing (llamando...), incoming (overlay aceptar/rechazar), inCall (video fullscreen + PIP + controles)

Routing:

  • videocall_builder.dart — GoRouter builder
  • Ruta: /legacy/dashboard/device_management/videocall

7. Code review realizado

Score: 6/10 — Request changes

Issues identificados (pendientes de corregir):

  1. Hardcoded test credentials (p_test1/test123) en UI de producción → guardar con kDebugMode
  2. _onCallItemRemove llama async sin await → race condition
  3. Todos los errores mapean a I18n.errorGeneric → sin diferenciación para el usuario
  4. videocall_screen.dart (310 líneas) demasiado grande → extraer _IdleView y _InCallView a ficheros separados como ConsumerWidget
  5. group_call_view_model.dart es dead code (no lo consume ninguna screen)
  6. Signaling placeholder con throw UnimplementedError → cambiar a no-op
  7. VideocallParticipant (domain) expone tipo SDK (JCMediaDeviceVideoCanvas) → mover al ViewModel

Dónde quedamos

  • Rama: feature/videocall-sdk-integration
  • Los cambios del paquete videocall_sdk están commiteados y pusheados (3 commits)
  • Los cambios de la feature están en disco pero sin commitear (necesitan correcciones del code review)
  • fusion-app avanzó y revirtió algunos cambios compartidos (permisos, rutas) → hay que re-sincronizar

Pendiente

Correcciones del code review

  • Guardar test credentials con kDebugMode
  • Fix async race en _onCallItemRemove
  • Implementar mensajes de error diferenciados
  • Extraer _IdleView y _InCallView a ficheros separados
  • Integrar o excluir group call ViewModel
  • Cambiar signaling placeholder de throw a no-op
  • Remover SDK type de domain entity

Pruebas APP↔APP (primera llamada real)

  • Login con 2 userIDs de prueba (p_test1, p_test2)
  • Videollamada entre dos teléfonos físicos
  • Probar incoming call, reject, hangup, mute, camera switch
  • Probar app cerrada en iOS (riesgo #1 — push/background)

Integración con backend

  • Obtener API REST del backend SaveFamily para señalización
  • Definir formato userID con backend (p_<cuenta> + sanitización emails)
  • Implementar datasource de señalización

Pruebas APP↔Reloj

  • Llamada APP → Reloj
  • Llamada Reloj → APP
  • Llamadas grupales

Producción

  • Token auth (backend genera tokens con AppSecret)
  • AppKeys separadas por entorno
  • Push/background iOS (PushKit + CallKit si necesario)

3 riesgos abiertos antes del pago ($8,835)

# Riesgo Estado
1 Push/background iOS — la doc no menciona FCM/APNs, CallKit ni ConnectionService. App cerrada = no recibe llamadas. Posible deal-breaker Sin respuesta
2 GDPR sin DPA — servidores UE pero sin DPA, sin control routing, datos de menores Email enviado 01-04, sin respuesta
3 Chat sin spec — $2,950 sin lista de features, "mira SeTracker2" Sin spec
+ Encryption — $2,950 pagados, cero documentación del módulo Sin spec

Arquitectura confirmada

APP (Flutter + jc_sdk)  ←→  Juphoon Cloud (solo media)
        ↕ API REST
Backend SaveFamily  ←→  Backend i365/SeTracker  ←→  Smartwatch (firmware + jrtc_* C API)
                              ↕ TCP plano
  • El "Server" del protocolo TCP es i365, NO Juphoon
  • Juphoon Cloud solo rutea audio/video (media plane)
  • La señalización (quién llama a quién) va por el backend

Naming conventions (protocolo TCP)

Tipo Formato Ejemplo
Watch userID w_ + IMEI w_000078932675810
Mobile userID p_ + APP account p_abc10086
Group room did + _group 0245423235_group
Single room did + _ + APP account 0245423235_abc10086

@ y . se reemplazan por _ en room numbers y userIDs.

Documentación de referencia

  • Quickstart V1.1: ~/Downloads/Video call API_ Juphoon Flutter SDK quickstart V1.1.pdf
  • TCP Protocol: ~/Downloads/Juphoon Video Call TCP Protocol.docx
  • Connection process: ~/Downloads/video call connection process Rev2.docx
  • Mutual dialing: ~/Downloads/video call mutual dialing process.docx
  • Schematics: ~/Downloads/schematics _2025.03.26 (2)/
  • pub.dev: https://pub.dev/packages/jc_sdk
  • Consola Juphoon: https://developer.juphoon.com