===============================================================
  ARQUITECTURA — OASIS MOBILE (Node.js)
  Actualizado: 2026-05-02 | Version: 0.7.4
===============================================================

ENTRY POINT:
  nodejs-project/nodejs-project/main.js
    -> Inicia servidor SSB
    -> Arranca backend Koa en puerto 3000

--------------------------------------------------------------
BACKEND (Koa.js)
--------------------------------------------------------------
ARCHIVO: src/backend/backend.js (~4127 lineas, 100+ handlers)

  - Router con 100+ rutas GET/POST
  - Carga todos los modelos al inicio
  - Middleware: validacion host (CSRF), idioma (cookies), SSB sync status
  - Patron: ctx.body = await vistaView(datos)

RUTAS VERIFICADAS (HTTP 200 confirmado 2026-05-02):
  GET  /                   -> home (302 redirect a /activity)
  GET  /activity           -> feed de actividad
  GET  /inhabitants        -> lista de usuarios
  GET  /tribes             -> list de tribes
  GET  /invites            -> invites/pubs SSB
  GET  /peers              -> peers conectados
  GET  /blockexplorer      -> blockchain explorer SSB (NO es /blockchain)
  GET  /settings           -> configuracion
  GET  /modules            -> activar/desactivar modulos
  GET  /search             -> busqueda
  GET  /banking            -> banca ECOin
  GET  /market             -> mercado
  GET  /chats              -> chats directos
  GET  /pads               -> pads colaborativos
  GET  /games              -> 16 juegos en JS
  GET  /maps               -> mapas con tiles offline
  GET  /shops              -> tiendas
  GET  /torrents           -> torrents
  GET  /calendars          -> calendarios
  GET  /logs               -> logs del sistema
  GET  /AI                 -> integracion IA (302 redirect)

  POST /settings/invite/accept -> acepta pub invite SSB
    -> Requiere header Referer (CSRF protection)
    -> Publica SSB msg type:'pub-invite' con pubHost, pubKey, acceptedAt
  POST /tribes/generate-invite -> genera invite code (con inviteLog)
  POST /tribes/join-code       -> unirse a tribe

--------------------------------------------------------------
MODELOS (src/models/)
--------------------------------------------------------------
  MODELOS CORE:
    about_model.js       -> perfiles de usuario
    main_models.js       -> SSB core: peers, acceptInvite, rebuild
    blockchain_model.js  -> listBlockchain() con filtros por tipo
    tribes_model.js      -> tribes + inviteLog trazabilidad completa
      - generateInvite(tribeId) -> registra en inviteLog[] con generatedBy
      - joinByInvite(code, userId) -> actualiza inviteLog (status, usedBy, usedAt)

  MODELOS NUEVOS (upstream 0.7.4):
    calendars_model.js, chats_model.js, games_model.js, logs_model.js
    maps_model.js, pads_model.js, shops_model.js, torrents_model.js
    viewer_filters.js, tribe_crypto.js

  TOTAL: 30+ modelos

  ARCHIVO CRITICO — src/backend/media-favorites.js:
    Gestiona favoritos de media. Kinds validos:
    audios, bookmarks, calendars, chats, documents,
    images, maps, pads, shops, torrents, videos
    (Si falta un kind -> "Invalid favorites kind" -> 500 en esa ruta)

--------------------------------------------------------------
VISTAS (src/views/) — Hyperaxe SSR — 51 VISTAS TOTALES
--------------------------------------------------------------
  Patron:
    const { div, h2, p } = require('../server/node_modules/hyperaxe');
    exports.miVista = async (datos) => template('Titulo', section(...))

  VISTAS CORE:
    activity_view.js, agenda_view.js, AI_view.js, audio_view.js,
    banking_views.js, blockchain_view.js, bookmark_view.js,
    cipher_view.js, courts_view.js, cv_view.js, document_view.js,
    event_view.js, favorites_view.js, feed_view.js, forum_view.js,
    image_view.js, indexing_view.js, inhabitants_view.js,
    invites_view.js, jobs_view.js, legacy_view.js, main_views.js,
    markdown.js, market_view.js, modules_view.js, opinions_view.js,
    parliament_view.js, peers_view.js, pixelia_view.js, pm_view.js,
    projects_view.js, report_view.js, search_view.js, settings_view.js,
    stats_view.js, tags_view.js, task_view.js, transfer_view.js,
    trending_view.js, tribes_view.js, video_view.js, vote_view.js,
    wallet_view.js

  VISTAS NUEVAS (upstream 0.7.4):
    calendars_view.js, chats_view.js, games_view.js, logs_view.js
    maps_view.js, pads_view.js, shops_view.js, torrents_view.js

  VISTAS CON QR (modificadas):
    inhabitants_view.js  -> QR del SSB ID en perfil y lista
    invites_view.js      -> QR del pub invite code
    tribes_view.js       -> QR del tribe invite code (+ mapa, ancestro privado)
    wallet_view.js       -> QR de direccion ECOin
    blockchain_view.js   -> renderInviteExtra con detalle de inviteLog

--------------------------------------------------------------
SSB (Secure Scuttlebutt)
--------------------------------------------------------------
  Identidad: @<base64_ed25519_pubkey>.ed25519
  ID actual: @DCiP6BJlx5z56fYD0qd0c1x+YhmNKYOuWX+5DzRYtHw=.ed25519
  Data dir: ~/.ssb/
    gossip.json  -> pubs conocidos (vacio en dev, se llena al aceptar invites)
    conn.json    -> estado de conexiones activas
    secret       -> clave privada ed25519 (NO TOCAR)
    flume/       -> base de datos SSB (log.offset, contacts2.json)
    ebt/         -> datos de replicacion por peer

  Mensajes firmados, append-only, cadena de bloques real
  Replicacion via pubs (gossip.json en ~/.ssb/)

  FLUJO DE PUB INVITE:
    1. Usuario va a /invites y pega un codigo formato:
       net:HOST:PORT~shs:PUBKEY=~invite:TOKEN=
    2. POST /settings/invite/accept (con Referer header)
    3. main_models.js::acceptInvite() llama ssb.invite.accept()
    4. Publica SSB msg { type:'pub-invite', pubHost, pubKey, acceptedAt }
    5. El pub queda en gossip.json y el nodo se conecta

  NOTA: gossip.json en dev esta vacio. Los pubs se añaden
  aceptando invites desde la UI en /invites.

--------------------------------------------------------------
BLOCKCHAIN EXPLORER
--------------------------------------------------------------
  RUTA CORRECTA: /blockexplorer  (NO /blockchain — ese da 404)
  blockchain_model.js -> listBlockchain()
    - Filtra por tipo: post, about, vote, tribe, pub-invite, etc.
  blockchain_view.js -> renderBlockchainView()
    - renderInviteExtra(): tabla de inviteLog (tribes) y datos pub-invite

--------------------------------------------------------------
MAPAS OFFLINE
--------------------------------------------------------------
  src/maps/
    map_renderer.js     -> renderizador de mapas
    tiles/              -> 5461 PNG tiles zoom 0-8 (~42 MB)
  NOTA: src/maps/maps/ era un duplicado accidental, eliminado.
  Tiles de zoom 0-8 cubren el mundo entero a baja resolución.

--------------------------------------------------------------
JUEGOS
--------------------------------------------------------------
  src/games/ -> 16 juegos JS puro:
    8ball, arkanoid, artillery, asteroids, audiopendulum,
    cocoland, cocoman, ecoinflow, flipflop, labyrinth,
    neoninfiltrator, pingpong, rockpaperscissors,
    spaceinvaders, tetris, tiktaktoe

--------------------------------------------------------------
FRONTEND (CSS/Assets)
--------------------------------------------------------------
  styles/style.css       -> CSS principal ~5180 lineas (upstream + custom)
  styles/mobile.css      -> movil (safe-area, touch, QR, mode-buttons)
  themes/OasisMobile.css -> tema dark gold
  public/js/mobile-ui.js -> flechas scroll + expand en .mode-buttons
  translations/          -> i18n es, en, de, fr, it, pt, eu

--------------------------------------------------------------
COMPARACION CON UPSTREAM (github.com/epsylon/oasis)
--------------------------------------------------------------
  UPSTREAM: v0.7.4 (referencia: /home/sito/COFRE/CODERS/ULTIMO_OASIS/oasis/)
  LOCAL:    v0.7.4 con modificaciones:
    - QR codes en inhabitants, invites, tribes, wallet
    - inviteLog trazabilidad en tribes
    - SSB msg type:'pub-invite' al aceptar pub invite
    - blockchain explorer con filtro 'invites'
    - menu hamburger movil (CSS puro)
    - mobile.css + mobile-ui.js para movil
    - viewport-fit=cover para notch Android/iOS
    - Economy + Media activados por defecto en config
