Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/scooller/Leben-site/llms.txt

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

iLeben is organised as three cooperating layers that share a single MySQL database but have clearly separated responsibilities. The Laravel 12 backend owns all business logic, queued jobs, and API contracts. The Filament 5 admin panel is a server-driven UI (SDUI) layer built on top of Laravel that gives operators full control over content, settings, and synchronisation without writing code. The React 19 frontend is a completely standalone Vite application that lives in frontend/ and communicates with Laravel exclusively through the versioned REST API — it is compiled separately and has its own dependency tree. Salesforce acts as the commercial master record, and two dedicated payment services (Transbank and Mercado Pago) integrate through a common driver interface.

Directory Structure

.
├── app/
│   ├── Console/Commands/       # Artisan commands (sync, normalise, expire)
│   ├── Contracts/              # Interfaces (PaymentGatewayInterface, etc.)
│   ├── Enums/                  # Enums: PaymentGateway, PaymentStatus, ReservationStatus
│   ├── Filament/
│   │   ├── Actions/            # Table / record actions
│   │   ├── Pages/              # Custom admin pages (UserActivitiesPage, etc.)
│   │   ├── Resources/          # CRUD resources (Proyecto, Plant, Payment, …)
│   │   └── Widgets/            # Dashboard widgets
│   ├── Http/
│   │   ├── Controllers/        # API controllers + OAuth callback
│   │   ├── Middleware/         # Custom middleware (token.origin, preview, maintenance)
│   │   └── Requests/           # Form Request validation classes
│   ├── Jobs/                   # Queued jobs (sync, email, production sync)
│   ├── Mail/                   # Mailable classes
│   ├── Models/                 # Eloquent models
│   ├── Observers/              # Model observers (audit, sync triggers)
│   └── Services/
│       ├── FinMail/            # Transactional email management
│       ├── Payment/            # PaymentGatewayManager + drivers
│       ├── Salesforce/         # SalesforceService, SalesforceCaseMapper
│       └── ShortLink/          # Short link generation and tracking

├── database/
│   ├── factories/              # Model factories for testing
│   ├── migrations/             # Database migrations
│   └── seeders/                # Database seeders

├── frontend/                   # Standalone React 19 app (Vite)
│   └── src/
│       ├── components/         # Reusable React components
│       ├── contexts/           # React Context (SiteConfig, etc.)
│       ├── hooks/              # Custom hooks
│       ├── pages/              # Page-level layouts
│       ├── services/           # API service modules
│       ├── styles/             # SCSS modules
│       └── utils/              # Utility functions

├── resources/
│   ├── css/                    # Filament + Tailwind styles
│   └── js/                     # Legacy JS (deprecated)

├── routes/
│   ├── api.php                 # /api/v1 routes
│   ├── console.php             # Artisan scheduled tasks
│   └── web.php                 # Web routes (OAuth callback, payment result, etc.)

└── tests/
    ├── Feature/                # Feature tests (PHPUnit)
    └── Unit/                   # Unit tests

Backend — Laravel 12

The Laravel backend is the authoritative source for all data mutations, queue processing, and business rules. Key structural conventions to know:
  • Models live in app/Models/ and follow Eloquent conventions (singular PascalCase names, plural snake_case table names). Every model that participates in Salesforce sync or payment flows has a corresponding Observer in app/Observers/ that triggers async jobs on model events.
  • Services encapsulate integration logic. Nothing in a controller or job communicates directly with Salesforce or a payment gateway — it always goes through a service class.
  • Jobs (app/Jobs/) handle all time-consuming operations: Salesforce sync runs, Lead creation retries, production data sync, and email notifications. The queue connection defaults to database; two separate cron entries are required on cPanel — one for schedule:run and one for queue:work.
  • Artisan commands (app/Console/Commands/) cover operational tasks such as contact:normalize-rango-renta-key, salesforce:refresh-token, salesforce:test-auth, and reservations:expire. All scheduled jobs and commands are registered in routes/console.php.
# Run the full scheduler (every minute via cron)
php artisan schedule:run

# Key operational commands
php artisan sync:plants
php artisan salesforce:test-auth
php artisan salesforce:refresh-token
php artisan reservations:expire

Admin Panel — Filament 5

The Filament panel is mounted at /admin and provides operators with a complete management interface. It is built as a Server-Driven UI (SDUI), meaning all forms, tables, and actions are defined in PHP and rendered by Livewire without a separate JavaScript build step. Resources (app/Filament/Resources/) cover every major entity: projects (Proyecto), units (Plant), payments, contact submissions, advisors, short links, and contact channels. Each resource includes full CRUD, column filters, and Filament ExportAction integration for queue-backed CSV exports with persistent notifications. Custom Pages (app/Filament/Pages/) extend the panel beyond CRUD. The most notable is UserActivitiesPage, which provides a detailed audit trail for each user. Widgets (app/Filament/Widgets/) populate the dashboard with operational metrics. SiteSettings is a single-record settings page with 11+ tabs covering everything from branding (logo light/dark, favicon, colours, typography) to Salesforce OAuth connection, payment gateway configuration, maintenance mode, GTM/Facebook Pixel integration, and header/footer script injection — all manageable without code changes.
// Access settings anywhere in PHP
SiteSetting::get('maintenance_mode');
SiteSetting::set('maintenance_mode', true);

REST API — /api/v1

The public API is versioned under /api/v1 and defined in routes/api.php. Authentication uses Laravel Sanctum bearer tokens. A custom token.origin middleware validates tokens using PersonalAccessToken::findToken() without relying on session state, making it safe for stateless API clients.
MethodEndpointAuth Required
GET/api/v1No
GET/api/v1/site-configNo (sensitive payment config hidden)
GET/api/v1/proyectosNo
GET/api/v1/plantasNo
GET/api/v1/plantas/{id}No
POST/api/v1/contact-submissionsNo
POST/api/v1/checkoutToken
GET/api/v1/paymentsToken
POST/api/v1/payments/{id}/manual-proofToken
Responses are shaped by Eloquent API Resources defined inline within the API controllers. Rate limiting is applied to the contact submission endpoint (throttle:10,1). Webhook endpoints for Transbank and Mercado Pago sit outside /api/v1 — see the Payments section for those routes.

React Frontend

The frontend is a fully independent React 19 application with its own package.json, Vite config, and build pipeline located in frontend/. It does not share Laravel’s Blade templating system and communicates with the backend entirely through the REST API. Key structural pieces:
  • src/pages/ — top-level page components (Home, Catalogue, Contact, Payment Result, Maintenance)
  • src/components/ — reusable UI components (hero, filters, plant cards, dialogs)
  • src/contexts/SiteConfig context, populated from GET /api/v1/site-config on boot, distributes logo, theme, SEO settings, and feature flags across the entire component tree
  • src/hooks/ — custom hooks for data fetching, reservation state, and analytics events
  • src/styles/ — SCSS modules per component
Web Awesome Pro 3.7.0 provides the design system (@web.awesome.me/webawesome-pro). Use short size values (s, m, l) — the long forms (small, medium, large) are deprecated in 3.x. The maintenance page uses a <wa-dialog> component with close-prevention to block navigation. GSAP 3.15 drives hero animations and scroll-triggered effects. Cloudflare Turnstile is integrated into the contact form with server-side validation. GTM and Facebook Pixel are injected dynamically from SiteConfig with event deduplication.
# Development (Vite HMR on port 5173)
cd frontend && npm run dev

# Production build (Vite + pre-render + SEO validation)
cd frontend && npm run build

Salesforce Integration

Salesforce is the commercial master record. The integration is powered by omniphx/forrest and lives in app/Services/Salesforce/. SalesforceService is the central class. It runs SOQL queries with result caching (Cache::remember with configurable TTL) to reduce API load. It maps Salesforce objects to local Laravel models and handles field filtering to avoid overwriting locally managed attributes during sync. OAuth uses the WebServer flow. After the initial interactive login at /admin/site-settings, tokens are persisted encrypted in SiteSetting.extra_settings (token_cache_backup, refresh_token_cache_backup). The tryAutoReconnect() method restores both tokens to the cache and calls Forrest::refresh() silently — no manual re-login required after a cache:clear or Redis restart. Scheduled sync jobs:
Job / CommandSchedule
reservations:expireEvery minute
SyncPlantsJobEvery minute (conditional via SalesforcePlantSyncSchedule)
salesforce:refresh-tokenEvery 20 minutes
model:prune (FrontendPreviewLink)Daily
Lead creation from the contact form goes through CreateSalesforceCaseJob with automatic retries and full UTM field mapping. The job checks OAuth connection state before attempting Salesforce calls and skips retries when the connection is marked disconnected, preventing log flood until a human reconnects via the panel.

Payment Services

Payments are managed through a PaymentGatewayManager driver pattern in app/Services/Payment/. Each gateway implements PaymentGatewayInterface, making it straightforward to add new providers.
DriverClassKey Features
transbankTransbankServiceMall mode, multiple commerce codes per project via TRANSBANK_STORE_CODES
mercadopagoMercadoPagoServiceWebhook HMAC signature verification, idempotent processing
manualManualPaymentServiceFree-text reference, no gateway call
Payment records link directly to both a Proyecto and a Plant. The checkout flow includes billing fields pre-filled from the authenticated user. A public payment result page (/payment/result) requires no authentication. All payment service logs sanitise tokens and raw payloads to prevent sensitive data exposure. The FlowLogMatrix class standardises log severity levels across all payment flows.

Database Tables

iLeben’s primary tables and their roles:
TableDescription
usersPlatform users (admin and marketing roles)
site_settingsGlobal configuration — single row (ID = 1) with JSON extra_settings
curatorCentralised media file metadata (Filament Curator)
paymentsPayment transaction records with gateway, status, and billing fields
proyectosReal estate projects with normalised etapa, Transbank commerce code
plantsIndividual units/apartments within projects
exportsQueue-backed Filament export jobs with notification state
contact_submissionsContact form submissions with channel, UTM, and Salesforce sync state
contact_channelsContact channel types synced from Salesforce with colour badges
asesoresSales advisors with avatar, WhatsApp redirect, and QR short link
short_linksShort URLs with UTM tracking and visit counts
plant_reservationsTemporary unit reservations with expiry
frontend_preview_linksTime-limited preview tokens for pre-publication catalogue access

Model Relationships

User          →  has many  Payments
Payment       →  belongs to User
Payment       →  belongs to Proyecto
Payment       →  belongs to Plant
Plant         →  has many  PlantReservations
Plant         →  has many  Payments
Proyecto      →  has many  Plants
Proyecto      →  belongs to many  Asesores  (via asesor_proyecto pivot)
SiteSetting   →  belongs to Media  (1:1 via logo_id, favicon_id, etc.)
Proyecto      →  has Transbank commerce code (via TRANSBANK_STORE_CODES)
ContactSubmission → belongs to ContactChannel
ShortLink     →  belongs to User  (as creator)
The SiteSetting model uses a key-value store pattern with a single database row (ID = 1). Read and write values with SiteSetting::get('key') and SiteSetting::set('key', $value) rather than querying the table directly.
For detailed API request/response shapes and authentication examples, see the API Reference. For full payment gateway configuration, webhook routing, and Transbank Mall setup, see Payments & Gateways.

Build docs developers (and LLMs) love