Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Edwin950821/BodegaX/llms.txt

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

BodegaX is a classic three-tier web application: a browser-side Angular 17 single-page application communicates exclusively through REST API calls to a Spring Boot backend, which in turn reads from and writes to a PostgreSQL relational database. Understanding how these three layers interact — and how the frontend manages authentication state and routing access — is the foundation for working confidently with any part of the codebase.

Three-Tier Overview

┌───────────────────────────────────────┐
│         Browser (Port 4200)           │
│   Angular 17 SPA + Angular Material   │
│   Lazy-loaded feature modules         │
│   RxJS BehaviorSubject auth state     │
└──────────────┬────────────────────────┘
               │ HTTP REST (JSON)

┌───────────────────────────────────────┐
│        Spring Boot API (Port 8080)    │
│   REST controllers + session auth      │
│   Business logic & data validation    │
└──────────────┬────────────────────────┘
               │ JDBC / JPA

┌───────────────────────────────────────┐
│       PostgreSQL Database (5432)      │
│   Users, inventory, orders,           │
│   transactions, session records       │
└───────────────────────────────────────┘
The API base URL http://localhost:8080 is hardcoded directly in the Angular source files — including in login.component.ts, where the login POST request is sent. There is no environment-variable abstraction in the current codebase. Before deploying to a staging or production environment, replace all occurrences of http://localhost:8080 with your deployed backend URL, or introduce Angular environment files (environment.ts / environment.prod.ts) to manage this per build target.

Frontend Routing

BodegaX uses Angular’s RouterModule configured in AppRoutingModule. All feature modules are lazy-loaded — they are not bundled into the initial JavaScript payload, but fetched on demand when a user first navigates to a given route. This keeps the initial page load fast regardless of how many modules the application contains.

Route Table

PathLazy-Loaded ModuleDescriptionGuard
/loginLoginModuleAuthentication screen — username and password formCheckNotLoginGuard
/ (empty)HomeModuleDefault route — redirects authenticated users to Sales DispatchCheckLoginGuard
/homeHomeModuleSales Dispatch dashboard (Despachar / Solicitar Caja)CheckLoginGuard
/managementManagementModuleInventory management — Mi BodegaNone declared
/ordersOrdersModuleOrder tracking — PedidosNone declared
/historyHistoryModuleTransaction history — HistorialNone declared
/settingsSettingsModuleUser account managementNone declared
/viewViewModuleDetail view for individual recordsNone declared
/hsaleHsaleModuleHistorical sale detail viewNone declared
/registerRegisterModuleNew user registration flowNone declared

Route Guards

Two guards protect the application’s entry and exit points for authenticated sessions.

CheckLoginGuard

Applied to the / and /home routes. On activation, this guard checks whether a valid session exists in sessionStorage['bodegax']. If no session is found, the user is redirected to /login. This prevents unauthenticated users from accessing any operational module.

CheckNotLoginGuard

Applied exclusively to the /login route. If a session is already present in sessionStorage['bodegax'], this guard redirects the user away from the login screen to the home dashboard. This prevents a logged-in user from accidentally landing on the login page again.
The /management, /orders, /history, /settings, /view, /hsale, and /register routes do not have canActivate guards declared in app-routing.module.ts. Access control for these routes is enforced at the UI level through role-based component visibility rather than at the router level. For a hardened production deployment, adding CheckLoginGuard to all protected routes is strongly recommended.

Authentication and Session State

Authentication state is managed centrally by the root-level AppService, which is provided at the application root (via providedIn: 'root') and injected wherever auth state is needed.

AppService Observables

AppService uses RxJS BehaviorSubject instances to hold and broadcast three pieces of reactive state. Any component in the application can subscribe to these observables to react to state changes without polling or manual synchronization.
// src/app/app.service.ts

private showSidebar = new BehaviorSubject<boolean>(true);
private isLogged    = new BehaviorSubject<boolean>(true);
private role        = new BehaviorSubject<string>('client');
ObservableTypeInitial ValuePurpose
isLogged$Observable<boolean>Resolved from sessionStorage on initWhether a valid user session currently exists
role$Observable<string>'client' (or session value on init)The active user’s role — "admin" or "user"
showSidebar$Observable<boolean>trueControls sidebar visibility; toggled by the hamburger menu

Initialization Logic

When the Angular application boots, AppService’s constructor runs immediately. It reads sessionStorage.getItem('bodegax') and, if a session object is found, sets isLogged to true and role to the value stored in session.role. This means a browser refresh does not log the user out — the session persists until the tab is closed or logOut() is explicitly called.
constructor(private router: Router) {
  const session = sessionStorage.getItem('bodegax');
  if (session) {
    this.isLogged.next(true);
    this.role.next(JSON.parse(session).role);
  } else {
    this.isLogged.next(false);
  }
}

Session Object Structure

The object stored under sessionStorage['bodegax'] matches the JSON response returned by POST /admin/login on the Spring Boot backend.
{
  "uuid":      "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "nombre":    "Admin User",
  "role":      "admin",
  "id":        1,
  "direccion": "Calle Principal 123"
}
FieldTypeDescription
uuidstringUnique identifier for the authenticated session
nombrestringUser’s display name, rendered in the sidebar header
rolestring"admin" or "user" — drives all role-based UI logic
idnumberPrimary key of the user record in the PostgreSQL database
direccionstringUser’s registered address

Login and Logout Flow

The LoginComponent posts credentials to http://localhost:8080/admin/login. On a successful response, it delegates to AppService.logIn(user):
logIn(user: any) {
  sessionStorage.setItem('bodegax', JSON.stringify(user));
  this.isLogged.next(true);
  this.role.next(user.role);
  this.router.navigate(['/']);
}
All subscribers to isLogged$ and role$ receive the new values instantly — the sidebar becomes visible, role-conditional buttons render, and the router navigates to the home dashboard.

Role-Based UI Rendering

The role$ observable drives all role-conditional elements in the Angular templates. Components subscribe to this stream and use Angular’s *ngIf directive (or the async pipe) to show or hide UI elements based on the active role value.

Admin UI Elements

  • Despachar Caja button — dispatches approved crate orders
  • Terminar Jornada button — triggers end-of-day PDF report generation
  • Full inventory view in Mi Bodega
  • All users’ orders in Pedidos
  • Full transaction history in Historial
  • Settings module for user management

Client UI Elements

  • Solicitar Caja button — submits a new crate request
  • Own orders only in Pedidos
  • Own transaction history only in Historial
  • No access to inventory figures, Settings, or Terminar Jornada

Angular Module Architecture

BodegaX’s root AppModule is deliberately lean. It declares only the top-level AppComponent and a shared CheckboxComponent, and imports BrowserModule, AppRoutingModule, and MaterialModule. All feature-specific code lives in the lazy-loaded modules listed below.

Lazy-Loaded Feature Modules

Contains LoginComponent, which renders the username/password form and posts to POST /admin/login. Handles both the successful login flow (delegating to AppService.logIn) and error dialogs for empty fields or invalid credentials via Angular Material’s MatDialog.
The primary operational view after login. Admin users see the Despachar Caja (Sales Dispatch) interface; non-admin users see Solicitar Caja (Request Crate). AppService.logIn() navigates to the root route '/', which CheckLoginGuard permits and resolves to this module.
Inventory management (Mi Bodega). Displays current stock levels by beer brand and quantity, and allows admins to record new inventory entries.
Order tracking (Pedidos). Shows pending and processed orders. Admins see all users’ orders; clients see only their own.
Transaction history (Historial). A read-only log of all completed sales within the relevant scope for the active user role.
User management. Admin-only module for creating, editing, and deleting user accounts and managing role assignments.
Detail view for individual inventory or order records. Used for drill-down navigation from list views.
Historical sale detail view. Renders the line-item breakdown for a specific completed sale transaction.
New user registration flow. Collects user details and submits them to the backend to create a new account in the database.

Angular Material in AppModule

The root AppModule imports a consolidated MaterialModule that re-exports every Angular Material component module used across the application. This single-import pattern keeps individual feature modules clean while ensuring Material components (buttons, dialogs, tables, form fields, and more) are available application-wide.
// app.module.ts (simplified)
@NgModule({
  declarations: [CheckboxComponent, AppComponent],
  imports: [BrowserModule, AppRoutingModule, MaterialModule],
  providers: [provideAnimationsAsync(), AppService],
  bootstrap: [AppComponent, ErrorHandler],
})
export class AppModule {}
provideAnimationsAsync() is used instead of BrowserAnimationsModule — this is the Angular 17 preferred pattern for providing animations lazily, reducing the size of the initial JavaScript bundle delivered to the browser.

PDF Report Generation

The end-of-day report (Terminar Jornada) uses the jspdf (v2.5.x) and jspdf-autotable (v3.8.x) libraries, which are declared as runtime dependencies in package.json. These libraries run entirely in the browser — no server-side PDF rendering is required. When an admin triggers the report, the Angular component aggregates the day’s transaction data, builds a formatted table via jsPDF-AutoTable, and invokes doc.save() to download the PDF directly to the administrator’s machine.

Build docs developers (and LLMs) love