diff --git a/docs/refactor/ARCHITECTURE_AUDIT.md b/docs/refactor/ARCHITECTURE_AUDIT.md new file mode 100644 index 0000000..3be17e9 --- /dev/null +++ b/docs/refactor/ARCHITECTURE_AUDIT.md @@ -0,0 +1,108 @@ +# Architecture Audit + +Este documento resume el estado arquitectónico actual de Scoreko y debe usarse como referencia para el refactor. No redefine la arquitectura objetivo; documenta el diagnóstico existente y los riesgos detectados. + +## Estado Actual + +La repo es un bundle NodeCG con Vite, Vue 3, Quasar, Pinia y `vite-plugin-nodecg`. + +| Área | Ruta | Responsabilidad actual | +| --- | --- | --- | +| Extension | `src/extension` | Lógica server NodeCG, OAuth, brackets y pack manager. | +| Dashboard | `src/dashboard/scoreko-dev` | App Quasar/Pinia para control. | +| Graphics | `src/graphics` | Overlays broadcast: `scoreboard`, `scoreboard-2xko`, `commentary`. | +| Browser shared | `src/browser_shared/replicants.ts` | Acceso browser a replicants. | +| Shared | `src/shared` | Tipos, utilidades, países, packs y personajes. | +| Schemas | `schemas` | Schemas de replicants principales. | +| Build outputs | `dashboard`, `graphics`, `extension`, `shared/dist` | Outputs ignorados por git. | + +## Replicants + +### Declarados por Schema + +- `scoreboard` +- `players` +- `commentary` +- `graphicsSettings` +- `exampleReplicant` + +### Declarados Solo en Código + +- `installedPacks` +- `packRegistry` +- `downloadStates` +- `availableUpdates` + +### Problema Principal + +El contrato realtime está dividido entre schemas y código runtime. Parte vive en `schemas`, y parte en `pack-manager` o `usePackRegistry`. Esto dificulta validar cambios, regenerar tipos y entender qué estado público existe realmente. + +## Flujo de Datos + +1. El dashboard escribe en Pinia stores. +2. Los stores sincronizan con replicants mediante `store-sync.ts`. +3. Los overlays leen replicants directamente desde `browser_shared/replicants.ts`. +4. La extensión escucha mensajes NodeCG como `startgg:*`, `challonge:*` y `downloadPack`. +5. La extensión actualiza replicants o disco. +6. `graphicsSettings.scoreboardSkin` redirige entre overlays `scoreboard` y `scoreboard-2xko`. + +## Zonas Grandes o de Riesgo + +| Archivo | Riesgo | +| --- | --- | +| `src/dashboard/scoreko-dev/views/Players.vue` | Vista demasiado grande: tabla, CRUD, import/export, integraciones y dialogs. | +| `src/dashboard/scoreko-dev/components/PlayerSidePanel.vue` | UI duplicada para left/right. | +| `src/dashboard/scoreko-dev/views/Settings.vue` | Mezcla idioma, shortcuts, OAuth y tokens. | +| `src/dashboard/scoreko-dev/composables/useIntegration.ts` | Mezcla estado UI, localStorage, polling OAuth, importación y cleanup. | +| `src/extension/pack-manager.ts` | Mezcla config, tipos, FS, HTTP static, downloads, updates, replicants y handlers. | +| `src/graphics/scoreboard/main.vue` | Lógica, layout, animaciones, flags y CSS mezclados. | +| `src/graphics/scoreboard-2xko/main.vue` | Mismo riesgo que `scoreboard/main.vue`. | + +## Hallazgos Técnicos + +- No se detectaron ciclos de imports en los archivos TS/Vue revisados. +- Sí hay accesos frágiles al entorno NodeCG: + - `nodecg` global en composables. + - `NodeCG.Replicant` declarado manualmente. + - Imports a `package.json` desde UI. + - Tipos generados desalineados. + - Acceso directo a replicants fuera de stores o servicios. + +## Problemas Reales + +- La frontera NodeCG está rota: `browser_shared/replicants.ts`, stores, `Graphics.vue`, overlays y `usePackRegistry` acceden a NodeCG de formas distintas. +- Los contratos realtime no están centralizados. +- `pack-manager.ts` necesita reescritura controlada, no parcheo incremental. +- `usePackRegistry.ts` y `fighting-characters.ts` necesitan reescritura controlada. +- `startgg.ts` y `challonge.ts` duplican estructura: OAuth mode, proxy exchange, session polling API y parsing básico. +- `Players.vue` y `Settings.vue` son feature modules completos metidos en vistas. +- Los overlays son de alto riesgo visual y deben tocarse con mucho cuidado. +- Hay dead code claro: `exampleReplicant`, `example.ts`, `ExampleType` y schema de ejemplo. +- `src/types/schemas/configschema.d.ts` está stale: contiene `exampleProperty`, pero `configschema.json` ya no lo define. +- `lint` falla por `_id` en `Players.vue` y `_config` en `startgg.ts` y `challonge.ts`. +- El resto de lint son warnings de formato Vue. + +## Impacto a Medio y Largo Plazo + +- Añadir providers o skins duplicará lógica. +- Contributors externos no sabrán dónde tocar: store, composable, replicant o extensión. +- Refactors visuales pueden romper overlays porque no hay separación entre view model y presentación. +- El sistema de packs es el mayor riesgo por acoplar descarga, estado realtime, manifests, FS y UI. + +## Zonas a Preservar + +- La idea de `syncStateWithReplicant`. +- Stores `scoreboard`, `players` y `commentary` como base razonable. +- `oauth-server.ts` como pieza reusable. +- `countries.ts`, que está bien encapsulado. +- Schemas JSON como fuente de tipos. +- UI Quasar existente, preservando comportamiento visual mientras se divide. + +## Baseline de Checks + +| Check | Estado | +| --- | --- | +| `vue-tsc` | Pasa. | +| `tsc` | Pasa. | +| `lint` | Falla con 3 errores reales y 243 warnings de formato. | + diff --git a/docs/refactor/ARCHITECTURE_RULES.md b/docs/refactor/ARCHITECTURE_RULES.md new file mode 100644 index 0000000..88b5f64 --- /dev/null +++ b/docs/refactor/ARCHITECTURE_RULES.md @@ -0,0 +1,97 @@ +# Architecture Rules + +Estas reglas son obligatorias para cualquier refactor posterior. Están pensadas para mantener boundaries claros, reducir acoplamiento y preservar comportamiento durante la migración. + +## TypeScript + +- No usar `any`. +- Usar `unknown` solo en boundaries. +- Normalizar `unknown` inmediatamente al entrar al dominio. +- No duplicar tipos entre extension y browser. +- Todo replicant nuevo debe tener schema y tipo generado. +- Regenerar tipos siempre desde schemas. + +## Boundaries NodeCG + +- No acceder directamente a replicants fuera de `nodecg/browser` o `nodecg/extension`. +- No usar `nodecg.sendMessage` directo en componentes o composables de feature. +- No usar `nodecg.Replicant` directo fuera de la capa `nodecg`. +- No depender de `nodecg` global salvo dentro del boundary correspondiente. +- Centralizar nombres de replicants en `replicantNames`. +- Centralizar nombres de messages en una capa de messages. + +## Shared y Dominio + +- `shared/domain` solo puede contener funciones puras, tipos, normalizadores y mapping. +- `shared/domain` no puede importar Vue. +- `shared/domain` no puede importar NodeCG. +- `shared/domain` no puede acceder al DOM. +- Preferir funciones puras para normalización, parsing, derivación y mapping. +- Validar o normalizar datos externos al cruzar boundaries. + +## Dashboard + +- Los stores mantienen estado de aplicación y sync con replicants. +- Los stores no deben contener UI compleja. +- Las vistas no deben implementar features completos. +- Los componentes deben ser pequeños y orientados a UI. +- Los composables de feature no deben hablar directamente con NodeCG. +- Toda lógica de negocio debe vivir en dominio, services o stores según corresponda. + +## Extension + +- `extension/modules` debe contener handlers pequeños registrados desde bootstrap explícito. +- No mezclar FS, HTTP, replicants, downloads y parsing en el mismo módulo. +- Todo handler NodeCG debe declarar claramente qué message escucha y qué replicants toca. +- Todo acceso a `nodecg.listenFor`, `nodecg.Replicant`, `nodecg.mount` y logging debe pasar por `nodecg/extension`. + +## Packs + +- Pack registry, manifests, downloads y estado instalado deben compartir tipos comunes. +- Todo replicant de packs debe tener schema. +- Mantener nombres y defaults actuales durante la migración. +- Validar manifests en el boundary antes de exponerlos al dominio o UI. +- No mantener estado mutable de módulo opaco para packs instalados. +- No usar `ref` de Vue dentro de shared. + +## Integraciones + +- Providers como Start.gg y Challonge deben compartir patrón de OAuth, session polling y parsing. +- Cada provider debe tener cliente propio y normalizadores propios. +- El flujo OAuth debe apoyarse en `oauth-server.ts` cuando aplique. +- Todo timer o polling debe tener cleanup. +- Todo listener debe tener cleanup. + +## Graphics y Overlays + +- Los overlays se refactorizan al final. +- Primero preservar píxel y comportamiento; después limpiar internals. +- No cambiar CSS, SVG, posiciones o markup sensible sin baseline visual. +- Extraer view models antes de deduplicar layout. +- Helpers compartidos de flags, score animation y text fitting deben vivir en `graphics/shared`. + +## Side Effects + +- No side effects en imports salvo bootstrap explícito. +- No estado mutable de módulo salvo singleton justificado y documentado. +- Todo timer/listener debe registrar cleanup. +- No wrappers vacíos. +- No inventar un patrón si una función simple basta. + +## Naming + +| Elemento | Regla | Ejemplo | +| --- | --- | --- | +| Replicants | `camelCase`, constantes en `replicantNames` | `graphicsSettings` | +| Messages | Namespaced por dominio | `packs:download` | +| Stores | `useStore` | `useScoreboardStore` | +| Services | `createService` o `createClient` | `createPackService` | +| View models | `useViewModel` | `useScoreboardOverlayViewModel` | + +## Compatibilidad + +- Mantener comportamiento público durante la migración. +- Mantener nombres públicos hasta completar el refactor. +- No romper overlays sin baseline visual y verificación. +- Priorizar eliminar legacy muerto antes que envolverlo. + diff --git a/docs/refactor/MIGRATION_PLAN.md b/docs/refactor/MIGRATION_PLAN.md new file mode 100644 index 0000000..b3448b3 --- /dev/null +++ b/docs/refactor/MIGRATION_PLAN.md @@ -0,0 +1,187 @@ +# Migration Plan + +Este plan define el orden de migración. Debe ejecutarse de forma secuencial para reducir riesgo, preservar comportamiento y evitar reescrituras amplias sin baseline. + +## Principios + +- Mantener nombres públicos y comportamiento hasta completar la migración. +- Congelar comportamiento antes de mover responsabilidades. +- Eliminar legacy muerto antes de envolverlo. +- Separar boundaries antes de reescribir módulos complejos. +- Tocar overlays al final y con verificación visual. + +## Secuencia + +| Paso | Objetivo | Tipo | +| --- | --- | --- | +| 1 | Congelar comportamiento con screenshots de overlays, fixtures de replicants, build, typecheck y lint baseline. | Baseline | +| 2 | Quitar `example*`, regenerar schema types y eliminar `.js` redundantes en `src/shared` si no se usan. | Limpieza | +| 3 | Crear `nodecg/browser` y `nodecg/extension` sin cambiar comportamiento. | Boundary | +| 4 | Añadir schemas para replicants de packs manteniendo nombres y defaults exactos. | Contratos | +| 5 | Extraer tipos/config de packs a `shared` y ajustar `tsconfig.extension` para no duplicar. | Shared | +| 6 | Reescribir controladamente `pack-manager`. | Reescritura | +| 7 | Reescribir controladamente `usePackRegistry` y `fighting-characters`. | Reescritura | +| 8 | Dividir `useIntegration`. | Modularización | +| 9 | Dividir `Players.vue`. | Modularización | +| 10 | Dividir `Settings.vue`. | Modularización | +| 11 | Refactor suave de dashboard scoreboard para eliminar duplicación left/right. | Modularización | +| 12 | Extraer view models y helpers de overlays sin tocar CSS/markup al inicio. | Overlays | +| 13 | Añadir tests puros para normalizadores y lógica de dominio. | Tests | +| 14 | Añadir verificación visual Playwright para overlays principales. | Visual QA | + +## Detalle por Fase + +### 1. Congelar Comportamiento + +Crear una baseline antes de refactorizar: + +- Screenshots de `scoreboard`, `scoreboard-2xko` y `commentary`. +- Fixtures representativos de replicants. +- Resultado actual de build y typecheck. +- Resultado actual de lint, incluyendo los 3 errores reales conocidos. + +### 2. Limpiar Dead y Stale Code + +Eliminar código que no representa comportamiento productivo: + +- `exampleReplicant`. +- `example.ts`. +- `ExampleType`. +- Schema de ejemplo. +- Tipos generados stale. +- `.js` redundantes en `src/shared` si se confirma que no se usan. + +### 3. Crear Boundaries NodeCG + +Introducir APIs sin cambiar comportamiento: + +- `src/nodecg/browser/replicants.ts` +- `src/nodecg/browser/messages.ts` +- `src/nodecg/extension/replicants.ts` +- `src/nodecg/extension/messages.ts` +- `src/nodecg/extension/context.ts` + +El objetivo es centralizar acceso a replicants, messages, logging y NodeCG globals. + +### 4. Centralizar Contratos Realtime + +Añadir schemas para: + +- `installedPacks` +- `packRegistry` +- `downloadStates` +- `availableUpdates` + +Los nombres y defaults deben mantenerse exactamente para no romper dashboard, extensión ni overlays. + +### 5. Extraer Shared de Packs + +Mover a `shared`: + +- Tipos de manifest. +- Tipos de registry. +- Tipos de estado de descarga. +- Config derivada común. +- Validación ligera en boundaries. + +No duplicar tipos entre extension y browser. + +### 6. Reescritura Controlada de Pack Manager + +Separar `pack-manager.ts` en módulos pequeños: + +| Módulo | Responsabilidad | +| --- | --- | +| Registry client | Fetch y normalización del registry remoto. | +| Downloader | Descargas, progreso y errores. | +| Disk store | Lectura/escritura en disco. | +| Static mount | Exposición HTTP de assets instalados. | +| Handlers | Registro de mensajes NodeCG. | +| Replicant sync | Actualización centralizada de replicants. | + +### 7. Reescritura de Pack Registry Runtime + +Rehacer `usePackRegistry` y `fighting-characters` para: + +- Quitar estado mutable de módulo opaco. +- Evitar `ref` en shared. +- Modelar packs instalados como estado explícito. +- Cargar manifests mediante boundaries claros. +- Eliminar comentarios que contradicen el estado real de assets. + +### 8. Dividir Integraciones + +Extraer `useIntegration` en piezas: + +- `nodecgMessageClient` +- `oauthClient` +- `temporaryPlayers` +- `tournamentImport` + +Cada pieza debe tener cleanup explícito para timers/listeners. + +### 9. Dividir Players + +Extraer desde `Players.vue`: + +- `PlayersTable` +- `PlayerEditorDialog` +- `IntegrationImportCard` +- `ImportPlayersDialog` + +La vista debe coordinar el feature, no contener la implementación completa. + +### 10. Dividir Settings + +Extraer desde `Settings.vue`: + +- `LanguageSettings` +- `ShortcutSettings` +- `IntegrationSettings` + +Mantener UI Quasar y comportamiento actual. + +### 11. Refactor Suave de Scoreboard Dashboard + +Eliminar duplicación left/right con subcomponentes pequeños, sin cambiar el comportamiento público ni el layout principal. + +### 12. Overlays al Final + +Primero extraer sin modificar presentación: + +- View models. +- Helpers de flags. +- Helpers de score animation. +- Helpers de text fitting. + +Después de verificar baseline visual, deduplicar internals. + +### 13. Tests Puros + +Añadir tests para: + +- Normalizadores. +- Pack registry. +- Shortcut parsing. +- Country resolving. +- Bracket round formatting. + +### 14. Verificación Visual + +Añadir Playwright para overlays principales: + +- `scoreboard`. +- `scoreboard-2xko`. +- `commentary`. + +Debe validar screenshots o checks visuales estables antes de tocar CSS sensible. + +## Clasificación de Trabajo + +| Categoría | Incluye | +| --- | --- | +| Automatizable | Moves/imports, schema generation, lint autofix, snapshots. | +| Reescritura controlada | Packs y registry runtime. | +| División | `Players.vue`, `Settings.vue`, overlays. | +| Conservar | Quasar UI, Pinia, schemas, `oauth-server`, concepto de `store-sync`, layout visual de overlays. | + diff --git a/docs/refactor/SESSION_HANDOFF.md b/docs/refactor/SESSION_HANDOFF.md new file mode 100644 index 0000000..c1bdacd --- /dev/null +++ b/docs/refactor/SESSION_HANDOFF.md @@ -0,0 +1,70 @@ +# Session Handoff + +Este handoff resume el contexto que debe asumir cualquier sesión futura antes de continuar el refactor. El análisis arquitectónico ya está hecho; no debe repetirse desde cero. + +## Estado de la Sesión + +- No se habían modificado archivos antes de crear esta documentación. +- Se leyó la estructura del proyecto, configs, schemas, extensión, dashboard, overlays y shared. +- `vue-tsc` pasa. +- `tsc` pasa. +- `lint` falla con 3 errores reales y 243 warnings de formato. + +## Documentación Creada + +| Documento | Propósito | +| --- | --- | +| `docs/refactor/ARCHITECTURE_AUDIT.md` | Diagnóstico del estado actual y riesgos. | +| `docs/refactor/MIGRATION_PLAN.md` | Orden secuencial de migración. | +| `docs/refactor/ARCHITECTURE_RULES.md` | Reglas accionables para implementación posterior. | +| `docs/refactor/TARGET_ARCHITECTURE.md` | Source of truth de la arquitectura objetivo. | +| `docs/refactor/SESSION_HANDOFF.md` | Contexto operativo para futuras sesiones. | + +## Source of Truth + +Para futuras sesiones: + +1. Usar `TARGET_ARCHITECTURE.md` como referencia principal. +2. Aplicar siempre `ARCHITECTURE_RULES.md`. +3. Ejecutar `MIGRATION_PLAN.md` en orden. +4. Consultar `ARCHITECTURE_AUDIT.md` solo para entender el diagnóstico original. + +## Próximo Paso Recomendado + +El siguiente paso técnico, cuando se decida continuar, es iniciar el Paso 1 del plan: + +- Congelar comportamiento. +- Capturar screenshots de overlays. +- Crear fixtures de replicants. +- Registrar baseline de build, typecheck y lint. + +No empezar moviendo código antes de tener esa baseline. + +## Riesgos a Recordar + +- El sistema de packs es el área de mayor riesgo. +- Los overlays son sensibles a cambios visuales y deben tocarse al final. +- La frontera NodeCG debe centralizarse antes de reescribir features. +- Los replicants de packs deben formalizarse con schemas antes de limpiar runtime. +- `Players.vue` y `Settings.vue` deben dividirse, no reescribirse desde cero. + +## Checks Conocidos + +| Check | Resultado | +| --- | --- | +| `vue-tsc` | Pasa. | +| `tsc` | Pasa. | +| `lint` | Falla con 3 errores reales. | + +Errores lint reales conocidos: + +- `_id` en `Players.vue`. +- `_config` en `startgg.ts`. +- `_config` en `challonge.ts`. + +Los demás avisos conocidos son warnings de formato Vue. + +## Instrucción para Futuras Sesiones + +No reanalizar el proyecto desde cero salvo que el código haya cambiado de forma sustancial. Continuar desde estos documentos y ejecutar el plan en orden. + diff --git a/docs/refactor/TARGET_ARCHITECTURE.md b/docs/refactor/TARGET_ARCHITECTURE.md new file mode 100644 index 0000000..84d2118 --- /dev/null +++ b/docs/refactor/TARGET_ARCHITECTURE.md @@ -0,0 +1,203 @@ +# Target Architecture + +Este documento es la source of truth para la arquitectura objetivo del refactor. Las futuras sesiones deben alinearse con esta estructura y con las reglas de `ARCHITECTURE_RULES.md`. + +## Objetivo + +Crear una arquitectura simple y realista que: + +- Centralice la frontera NodeCG. +- Centralice contratos realtime. +- Separe dominio puro de UI y runtime. +- Permita añadir providers, packs y skins sin duplicación. +- Preserve el comportamiento visual de overlays durante la migración. + +## Estructura Objetivo + +```text +src/ + shared/ + schemas/ + types/ + domain/ + scoreboard/ + players/ + commentary/ + packs/ + integrations/ + utils/ + nodecg/ + browser/ + replicants.ts + messages.ts + extension/ + context.ts + replicants.ts + messages.ts + extension/ + modules/ + packs/ + integrations/ + startgg/ + challonge/ + oauth/ + dashboard/ + app/ + features/ + scoreboard/ + players/ + graphics/ + settings/ + integrations/ + packs/ + stores/ + ui/ + graphics/ + shared/ + composables/ + view-models/ + assets/ + scoreboard/ + scoreboard-2xko/ + commentary/ +``` + +## Boundaries + +| Boundary | Puede hacer | No puede hacer | +| --- | --- | --- | +| `shared/domain` | Tipos, funciones puras, normalizadores, mapping. | Importar Vue, NodeCG o DOM. | +| `nodecg/browser` | Acceso browser a replicants y messages. | Contener lógica de negocio o UI. | +| `nodecg/extension` | Acceso server a `nodecg.Replicant`, `listenFor`, `mount` y logging. | Implementar lógica específica de features. | +| `dashboard/stores` | Estado de aplicación y sync con replicants. | Contener UI compleja. | +| `dashboard/features` | Componentes y composables por feature. | Acceder directamente a NodeCG. | +| `graphics/shared` | View models, helpers visuales compartidos, assets compartidos. | Cambiar contratos realtime. | +| `extension/modules` | Handlers y servicios pequeños registrados desde bootstrap. | Mezclar responsabilidades sin separación. | + +## Flujo Realtime Objetivo + +```text +schemas + -> generated types + -> nodecg/browser + nodecg/extension + -> dashboard stores / extension modules / graphics view models +``` + +Reglas del flujo: + +- Todo replicant persistente o realtime tiene schema. +- Los tipos se generan desde schemas. +- Dashboard y graphics no crean replicants directamente. +- Extension modules no exponen replicants sin pasar por `nodecg/extension`. + +## Replicants + +### Fuente de Verdad + +Los schemas son la fuente de verdad para todos los replicants. + +### Replicants a Mantener + +- `scoreboard` +- `players` +- `commentary` +- `graphicsSettings` + +### Replicants de Packs a Formalizar + +- `installedPacks` +- `packRegistry` +- `downloadStates` +- `availableUpdates` + +### Replicants a Eliminar + +- `exampleReplicant` + +## Messages + +Los messages deben estar namespaced por dominio. + +| Dominio | Ejemplos | +| --- | --- | +| Packs | `packs:fetchRegistry`, `packs:download` | +| Start.gg | `integrations:startgg:createOAuthSession` | +| Challonge | `integrations:challonge:createOAuthSession` | + +Los componentes y composables de feature no deben llamar `nodecg.sendMessage` directamente. Deben usar clientes o services definidos en el boundary browser. + +## Shared Domain + +`shared/domain` contiene lógica reusable sin runtime: + +- `scoreboard`: normalización de estado, mapping de jugadores, derivaciones de marcador. +- `players`: normalizadores, import/export, validación ligera. +- `commentary`: estado y mapping de comentaristas. +- `packs`: manifests, registry, installed packs y derivaciones. +- `integrations`: tipos normalizados, parsing básico y modelos comunes. + +## Extension Modules + +La extensión debe registrarse desde un bootstrap explícito y delegar en módulos: + +| Módulo | Responsabilidad | +| --- | --- | +| `packs` | Registry, downloads, disk store, static mount, replicant sync y handlers. | +| `integrations/startgg` | Cliente Start.gg, OAuth session polling y parsing. | +| `integrations/challonge` | Cliente Challonge, OAuth session polling y parsing. | +| `oauth` | Reuso de `oauth-server.ts` y flujos comunes OAuth. | + +## Dashboard + +El dashboard se organiza por features: + +- `scoreboard` +- `players` +- `graphics` +- `settings` +- `integrations` +- `packs` + +Las vistas coordinan features. Los componentes implementan UI. Los stores mantienen estado y sincronización. + +## Graphics + +Los overlays deben leer estado mediante view models: + +- `useScoreboardOverlayViewModel` +- `useCommentaryOverlayViewModel` + +`graphics/shared` contiene: + +- Composables visuales. +- View models. +- Helpers de flags. +- Helpers de score animation. +- Helpers de text fitting. +- Assets compartidos. + +El layout visual existente se conserva hasta tener verificación visual estable. + +## Naming Canónico + +| Tipo | Convención | Ejemplo | +| --- | --- | --- | +| Replicant | `camelCase` | `graphicsSettings` | +| Replicant constants | `replicantNames` | `replicantNames.graphicsSettings` | +| Message | `:` | `packs:download` | +| Integration message | `integrations::` | `integrations:startgg:createOAuthSession` | +| Store | `useStore` | `usePlayersStore` | +| Service | `create` | `createPackService` | +| Provider client | `createClient` | `createStartggClient` | +| Overlay view model | `useOverlayViewModel` | `useScoreboardOverlayViewModel` | + +## Arquitectura a Preservar + +- Pinia como estado del dashboard. +- Quasar como UI principal. +- Schemas JSON como fuente de tipos. +- `syncStateWithReplicant` como concepto. +- `oauth-server.ts` como base reusable. +- `countries.ts` como utilidad encapsulada. +- Layout visual de overlays hasta completar verificación visual. +