Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/lucavallini/aibar-frontend/llms.txt

Use this file to discover all available pages before exploring further.

Aibar SRL App follows a layered Angular architecture with three clear zones — core, features, and shared — all wired together by a centralized router configuration and a functional HTTP interceptor. Every component in the application is an Angular standalone component; there are no NgModule declarations. Reactive state is managed through Angular’s signal() primitive, and all cross-cutting concerns such as authentication and HTTP token injection are handled once at the application level rather than inside individual features.

Directory Structure

The entire application lives under src/app/. The three top-level subdirectories each have a distinct responsibility:
src/app/
├── app.ts                          # Root application component
├── app.config.ts                   # Application-level providers
├── app.routes.ts                   # Top-level route definitions

├── core/                           # Singleton services, guards, interceptors, and models
│   ├── guards/
│   │   ├── auth.guard.ts           # Redirects unauthenticated users to /login
│   │   └── admin.guard.ts          # Redirects non-administrators to /viajes
│   ├── interceptors/
│   │   └── auth.interceptor.ts     # Injects Authorization: Bearer <token> on every request
│   ├── models/
│   │   ├── auditoria.model.ts
│   │   ├── camion.model.ts
│   │   ├── chofer.model.ts
│   │   ├── combustible.model.ts
│   │   ├── multa.model.ts
│   │   ├── paginacion.model.ts
│   │   ├── usuario.model.ts
│   │   └── viaje.model.ts
│   └── services/
│       ├── auth.service.ts
│       ├── auditoria.service.ts
│       ├── camiones.service.ts
│       ├── choferes.service.ts
│       ├── combustible.service.ts
│       ├── multas.service.ts
│       ├── theme.service.ts
│       ├── usuarios.service.ts
│       └── viajes.service.ts

├── features/                       # One subdirectory per business domain
│   ├── auth/
│   │   └── login/
│   ├── auditoria/
│   │   └── lista-auditoria/
│   ├── camiones/
│   │   └── lista-camiones/
│   ├── choferes/
│   │   └── lista-choferes/
│   ├── combustible/
│   │   └── lista-combustible/
│   ├── multas/
│   │   └── lista-multas/
│   ├── usuarios/
│   │   └── lista-usuarios/
│   └── viajes/
│       └── lista-viajes/

└── shared/                         # Reusable UI components and the root layout shell
    ├── components/
    │   ├── confirmar/              # Confirmation dialog component
    │   ├── header/                 # Top navigation bar
    │   ├── paginacion/             # Pagination controls
    │   └── sidebar/                # Side navigation menu
    └── layout/                     # Root layout shell wrapping all authenticated routes

Layer Responsibilities

Core Layer

Contains everything that must exist as a single instance for the lifetime of the application: injectable services (AuthService, ViajesService, etc.), typed domain models, the two route guards (authGuard, adminGuard), and the authInterceptor. Nothing in core/ depends on a specific feature.

Features Layer

Each subdirectory under features/ maps to one business domain and one application route. Feature components are standalone, import only what they need from @angular/common, @angular/forms, and shared/, and inject their domain service directly. There is no cross-feature dependency.

Shared Layer

Houses components that are used by two or more features: ConfirmarComponent (delete confirmation dialog), HeaderComponent (top bar with user info and logout), PaginacionComponent (page controls), and SidebarComponent (navigation links). The Layout component in shared/layout/ wraps all authenticated routes and renders the header and sidebar around the active feature.

Routing & Guards

app.routes.ts defines all routes in one file. authGuard protects the entire authenticated shell; adminGuard further restricts the /auditoria and /usuarios routes to the administrador role. Unauthorized navigation is intercepted before any component renders.

Routing Configuration

All routes are defined in src/app/app.routes.ts. The structure uses a single parent route with the Layout shell component and authGuard, with feature routes as children:
import { Routes } from '@angular/router';
import { LoginComponent } from './features/auth/login/login';
import { ListaChoferesComponent } from './features/choferes/lista-choferes/lista-choferes';
import { ListaViajes } from './features/viajes/lista-viajes/lista-viajes';
import { Layout } from './shared/layout/layout';
import { authGuard } from './core/guards/auth.guard';
import { ListaCamiones } from './features/camiones/lista-camiones/lista-camiones';
import { ListaMultas } from './features/multas/lista-multas/lista-multas';
import { ListaCombustible } from './features/combustible/lista-combustible/lista-combustible';
import { ListaAuditoria } from './features/auditoria/lista-auditoria/lista-auditoria';
import { adminGuard } from './core/guards/admin.guard';
import { ListaUsuarios } from './features/usuarios/lista-usuarios/lista-usuarios';

export const routes: Routes = [
  { path: 'login', component: LoginComponent },
  {
    path: '',
    component: Layout,
    canActivate: [authGuard],
    children: [
      { path: 'viajes', component: ListaViajes },
      { path: 'choferes', component: ListaChoferesComponent },
      { path: '', redirectTo: 'viajes', pathMatch: 'full' },
      { path: 'camiones', component: ListaCamiones },
      { path: 'multas', component: ListaMultas },
      { path: 'combustible', component: ListaCombustible },
      { path: 'auditoria', component: ListaAuditoria },
      { path: 'auditoria', component: ListaAuditoria, canActivate: [adminGuard] },
      { path: 'usuarios', component: ListaUsuarios, canActivate: [adminGuard] },
    ]
  },
];
The routing rules in plain language:
  • /login is fully public — no guard.
  • All other routes are children of the Layout shell, which is protected by authGuard. Any unauthenticated navigation attempt redirects to /login.
  • /viajes, /choferes, /camiones, /multas, and /combustible are accessible to any authenticated user regardless of role.
  • /auditoria and /usuarios have adminGuard applied and are only accessible to users whose JWT payload contains "rol": "administrador". Employees who navigate to these paths are redirected to /viajes.
  • The root path / redirects to /viajes via redirectTo: 'viajes'.

HTTP Interceptor

The authInterceptor in src/app/core/interceptors/auth.interceptor.ts is a functional HttpInterceptorFn that runs on every outgoing HTTP request:
import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = sessionStorage.getItem('aibar_token');

  if (token) {
    const reqClonado = req.clone({
      setHeaders: { Authorization: `Bearer ${token}` }
    });
    return next(reqClonado);
  }

  return next(req);
};
When a JWT is present in sessionStorage under the key aibar_token, the interceptor clones the outgoing request and adds an Authorization: Bearer <token> header before forwarding it. Requests made before login (i.e., the login POST itself) are forwarded unmodified.

Application Bootstrap and Providers

The application is bootstrapped in src/main.ts using Angular’s standalone bootstrapApplication API:
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { App } from './app/app';

bootstrapApplication(App, appConfig)
  .catch((err) => console.error(err));
All application-level providers are declared once in src/app/app.config.ts:
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { routes } from './app.routes';
import { authInterceptor } from './core/interceptors/auth.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient(withInterceptors([authInterceptor]))
  ]
};
provideRouter(routes) registers the full route table. provideHttpClient(withInterceptors([authInterceptor])) sets up Angular’s HTTP client and attaches the authInterceptor to the interceptor chain. There is no root NgModule — the entire configuration is expressed as a plain object.

Reactive State with Angular Signals

All feature components manage local state using Angular’s signal() primitive rather than RxJS subjects or imperative property assignments. Services such as AuthService expose signals directly:
// From src/app/core/services/auth.service.ts
isLoggedIn = signal<boolean>(this.hayToken());
Components read signals in templates and effect-free expressions, and update them by calling .set() or .update(). This makes change detection boundaries explicit and avoids the overhead of zone-based dirty checking for local component state.
The aibar_token JWT is stored in sessionStorage, which means it is cleared automatically when the browser tab is closed. Users will need to log in again in a new session. This is by design for the security requirements of the application.

Build docs developers (and LLMs) love