Skip to main content

Arquitectura general

Aplicación Angular 18 monolítica en un único proyecto (backoffice), organizada con NgModules: los schematics de angular.json generan componentes, directivas y pipes con standalone: false. Excepciones standalone: true: DateTimePickerComponent, los componentes de mensajes programados (ScheduledMessagesFilterComponent, ScheduledMessagesTableComponent) y los del chat PostponeDialogComponent, ScheduleMessageDialogComponent, ScheduledMessageStripComponent y ScheduleSendButtonComponent. El builder es @angular-devkit/build-angular:browser y la salida va a dist/backoffice.

Estructura de src/​

src/
├── main.ts # bootstrapModule(AppModule); enableProdMode si environment.production
├── index.html, styles.scss # estilos globales y variables CSS (--zg-chat-*)
├── environments/ # ignorado por git (ver Entornos)
├── assets/
│ ├── i18n/ # es.json, en.json
│ ├── scss/, fonts/, images/, svg/, audio/, mocks/
└── app/
├── app.module.ts, app-routing.module.ts, app.component.ts
├── core/ # singleton: guards, interceptores, servicios, estado, interfaces, helpers
├── shared/ # componentes, directivas, pipes, validadores y rutas de layout
└── features/ # un módulo lazy por área de negocio

El alias src/app/... se usa en imports (por baseUrl: "./" en tsconfig.json).

Arranque (AppModule)​

src/app/app.module.ts configura:

  • StoreModule.forRoot(ROOT_REDUCERS) y EffectsModule.forRoot(ROOT_EFFECTS); StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }).
  • TranslateModule.forRoot con TranslateHttpLoader apuntando a ./assets/i18n/ y extensión .json.
  • ToastrModule.forRoot(DEFAULT_GLOBAL_TOASTR_CONFIG), NgbModule, OverlayModule (CDK), barras de carga (LoadingBarHttpClientModule, LoadingBarRouterModule, LoadingBarModule).
  • Providers HTTP: AUTH_TOKEN_INTERCEPTOR_PROVIDERS, ERROR_INTERCEPTOR_PROVIDERS, DEVICE_TOKEN_INTERCEPTOR_PROVIDERS (ver Auth e interceptores).
  • provideHighcharts con importación diferida de highcharts/highstock.

AppComponent (app.component.ts), al construirse, despacha UserActions.loadUserSession() y loadPreviewLanguage(), y aplica el idioma del store salvo que la URL traiga ?lang=.

core/​

CarpetaContenido
guards/auth.guard.ts, loggedIn.guard.ts, admin.guard.ts, permission.guard.ts
interceptors/auth-token, http-error, device-token
services/api/Clientes HTTP por recurso (ver Servicios)
services/ui/Servicios de UI, sockets, sesión, permisos
states/NgRx: app.state.ts y una carpeta por slice (ver Estado)
interfaces/api, interfaces/uiTipos del dominio y de UI
helpers/global, helpers/uiConstantes (API_URLS, PAGE_URLS, SOCKET_EVENTS, ...), utilidades y el menú lateral (nav.constant.ts)

:::note Constantes heredadas helpers/global contiene constantes de otros dominios (casino.constants.ts, sport-manaments.constant.ts, virtualBets.constans.ts, affiliates.constants.ts, ...). Ningún otro archivo de src/app las importa: parecen restos de una base de backoffice anterior. :::

shared/​

Un único SharedModule (shared/shared.module.ts) declara y exporta componentes, directivas y pipes reutilizables. Detalle en Compartido. Las rutas de los dos layouts viven en shared/routes/content.routes.ts y shared/routes/full.routes.ts (ver Rutas).

features/​

Cada carpeta es un NgModule con su *-routing.module.ts, pages/ (contenedores) y components/ (presentacionales: filtro, tabla, modal). El patrón repetido en los CRUD es pagina → filtro + tabla + modal-formulario. Ver Features.

Convenciones observadas en el código​

  • Contenedor / presentacional: las páginas (*-page.component.ts) solo componen; la lógica vive en las tablas, modales y servicios.
  • Plantillas con control flow nuevo (@if, @for) en los componentes recientes, como las conexiones.
  • Selectores con prefijo de feature, por ejemplo connections-connections-table.
  • Estado local vs NgRx: el estado de tickets, autenticación, idioma, tema, departamentos, chat interno, mensajes programados y settings va a NgRx; el resto (conexiones, contactos, etc.) se carga por HTTP desde el componente.