Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/AndresLopezCorrales/Boletilandia/llms.txt

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

Boletilandia’s persistence layer is built on four MySQL tables — users, evento, seccion, and asiento — that form a clean hierarchy: a user account manages the platform, an event owns one or more sections, and each section holds individual seats. Every table is managed by Laravel 11 Eloquent models with explicit $fillable guards and model-level cascade deletes registered in boot() hooks.

Table Overview

users

Stores customer and admin accounts. The base Jetstream migration is extended by two additional migrations that add phone, address, usertype, and the two-factor authentication columns.

evento

Represents a ticketed event with a name, date/time, address, venue description, and a poster image path.

seccion

A labeled section inside an event (e.g., section “A”). Holds the ticket price and visibility information.

asiento

An individual seat inside a section, identified by a seat number and a boolean availability flag.

users Table

The users table is built up by three migrations. The base migration (0001_01_01_000000_create_users_table.php) creates the Jetstream scaffold. A second migration (2024_10_07_165606_add_two_factor_columns_to_users_table.php) adds the Fortify two-factor columns. A third migration (2024_10_10_032435_update_users_table.php) adds the three application-specific columns: phone, address, and usertype.
id
bigIncrements
required
Auto-incrementing unsigned big integer primary key.
name
string
The user’s full display name. Required; mass-assignable.
email
string (unique)
The user’s email address. Must be unique across all accounts. Required; mass-assignable.
email_verified_at
timestamp | null
Set when the user confirms their email address. null until verified.
password
string
Bcrypt-hashed password. Cast to hashed by the model; hidden from serialization.
remember_token
string(100) | null
Laravel’s standard “remember me” token. Hidden from serialization.
two_factor_secret
text | null
Encrypted TOTP secret used by Laravel Fortify’s two-factor authentication. Added by 2024_10_07_165606_add_two_factor_columns_to_users_table.php. Hidden from serialization.
two_factor_recovery_codes
text | null
Encrypted JSON array of one-time recovery codes. Added alongside two_factor_secret. Hidden from serialization.
two_factor_confirmed_at
timestamp | null
Timestamp of when the user confirmed their 2FA setup. Added conditionally when Fortify::confirmsTwoFactorAuthentication() returns true. null if 2FA is not yet confirmed. Not hidden from serialization.
current_team_id
foreignId | null
Reserved Jetstream team column. Nullable; not actively used in Boletilandia’s single-tenant setup.
profile_photo_path
string(2048) | null
Relative storage path to the user’s uploaded profile photo. Managed by the Jetstream HasProfilePhoto trait.
phone
string | null
Optional contact phone number. Added by the update migration; nullable. Mass-assignable.
address
string | null
Optional mailing or billing address. Added by the update migration; nullable. Mass-assignable.
usertype
string
default:"user"
Role discriminator. Only two values are used in the application: 'admin' and 'user'. Defaults to 'user' for every new registration.
created_at / updated_at
timestamps
Standard Laravel timestamp columns maintained automatically.

evento Table

Defined in 2024_10_10_065151_create_evento_table.php. The Eloquent model is App\Models\Evento.
id
bigIncrements
required
Auto-incrementing primary key.
NombreEvento
string
required
Human-readable name for the event (e.g., “Festival de Verano 2025”). Mass-assignable.
FechaEvento
dateTime
required
Full date and time the event takes place. Used throughout the app to filter past events. Mass-assignable.
DireccionEvento
text
required
Street address or location description for the event venue. Stored as text to accommodate long addresses. Mass-assignable.
LugarEvento
text
required
Descriptive name of the venue or place (e.g., “Estadio Nacional”). Stored as text. Mass-assignable.
imagen_path
string
required
Relative storage path to the event’s poster or banner image. Mass-assignable.
created_at / updated_at
timestamps
Standard Laravel timestamp columns.

seccion Table

Defined in 2024_10_10_065311_create_seccion_table.php. The Eloquent model is App\Models\Seccion.
id
bigIncrements
required
Auto-incrementing primary key.
evento_id
foreignId
required
Foreign key referencing evento.id. Constrained with ->constrained('evento'). Mass-assignable.
letra_seccion
string
required
A short label identifying this section within the event (e.g., "A", "B", "VIP"). Mass-assignable.
precio
decimal(10, 2)
required
Ticket price for all seats in this section, stored with two decimal places. Mass-assignable.
info-visibilidad
text
required
Descriptive text about the section’s view or visibility from that area of the venue. Note the hyphenated column name. Mass-assignable.
created_at / updated_at
timestamps
Standard Laravel timestamp columns.

asiento Table

Defined in 2024_10_10_065337_create_asiento_table.php. The Eloquent model is App\Models\Asiento.
id
bigIncrements
required
Auto-incrementing primary key.
seccion_id
foreignId
required
Foreign key referencing seccion.id. Constrained with ->constrained('seccion'). Mass-assignable.
numero_asiento
integer
required
The numeric identifier for this seat within its section (e.g., 1, 2, 42). Mass-assignable.
disponibilidad_asiento
boolean
required
Availability flag. 1 = available; 0 = occupied (already purchased). Mass-assignable.
created_at / updated_at
timestamps
Standard Laravel timestamp columns.

Eloquent Relationships

The three domain models form a strict parent → child → grandchild chain.
Evento  ──< Seccion  ──< Asiento

Cascade Delete Behavior

Cascade deletes are implemented at the Eloquent model level via boot() hooks rather than at the database foreign-key level. This ensures that each model’s own deleting lifecycle events fire correctly during deletion.
Because cascades are handled in PHP (not in the database), bypassing the Eloquent model — e.g., with raw DB::delete() queries — will not trigger cascade deletions. Always delete Evento and Seccion records through their Eloquent model instances.

Evento deletes its Secciones

When an Evento is deleted, its boot() hook iterates over each related Seccion and calls $seccion->delete() individually. This in turn fires the Seccion model’s own deleting hook, ensuring Asientos are also cleaned up:
protected static function boot()
{
    parent::boot();

    static::deleting(function ($evento) {
        $evento->secciones()->each(function ($seccion) {
            $seccion->delete(); // Triggers Seccion's own cascade to Asientos
        });
    });
}

Seccion deletes its Asientos

When a Seccion is deleted, its boot() hook removes all associated Asiento rows in a single bulk query:
protected static function boot()
{
    parent::boot();

    static::deleting(function ($seccion) {
        $seccion->asientos()->delete(); // Bulk-deletes all seats for this section
    });
}

Full Delete Chain

DELETE Evento
  └─ triggers Seccion::delete() for each child section
       └─ triggers Asiento bulk delete for each section's seats

Entity-Relationship Summary

users
  id, name, email, email_verified_at, password, remember_token,
  two_factor_secret (nullable), two_factor_recovery_codes (nullable),
  two_factor_confirmed_at (nullable), current_team_id (nullable),
  profile_photo_path (nullable), phone (nullable), address (nullable),
  usertype (default 'user'), created_at, updated_at

evento
  id, NombreEvento, FechaEvento, DireccionEvento, LugarEvento,
  imagen_path, created_at, updated_at

seccion
  id, evento_id → evento.id, letra_seccion, precio,
  info-visibilidad, created_at, updated_at

asiento
  id, seccion_id → seccion.id, numero_asiento,
  disponibilidad_asiento, created_at, updated_at
The users table has no direct foreign-key relationship to evento, seccion, or asiento at the database level. The link between an admin user and the events they manage is enforced through the usertype role check in middleware, not via a relational constraint.

Build docs developers (and LLMs) love