Skip to content

Product Entity Relationships

Complete reference for how product entities relate to each other in the database.

erDiagram
    Market {
        int id PK
        string code "ES, DE, FR"
        string name
        json supported_locales
        json country_codes
        json currency_codes
    }

    ProductTemplate {
        int id PK
        string title
        string sku
        string source_locale
        json itinerary
        int duration
        json highlights
        json categories
    }

    ProductByMarket {
        int id PK
        int product_template_id FK
        int market_id FK
        string locale
        string sku
        string status
        date search_start_date
        date search_end_date
        json excluded_dates
    }

    ProductComponent {
        int id PK
        int product_template_id FK
        string component_name
        string component_type
        int sequence_order
        string inventory_type
        int inventory_id
    }

    ProductByMarketTranslation {
        int id PK
        int product_by_market_id FK
        string locale
        string title
        string url_slug
        json itinerary
    }

    ProductByMarketFlightConfig {
        int id PK
        int product_by_market_id FK
        int airport_id FK
        string type
        boolean is_active
    }

    ProductByMarketFlightLeg {
        int id PK
        int flight_config_id FK
        int leg_index
        int day_offset
        string flight_type
        int origin_airport_id FK
        int destination_airport_id FK
    }

    Market ||--o{ ProductByMarket : "has"
    ProductTemplate ||--o{ ProductByMarket : "has"
    ProductTemplate ||--o{ ProductComponent : "has"
    ProductByMarket ||--o{ ProductByMarketTranslation : "has"
    ProductByMarket ||--o{ ProductByMarketFlightConfig : "has"
    ProductByMarketFlightConfig ||--o{ ProductByMarketFlightLeg : "has"
ParentChildCardinalityForeign Key
ProductTemplateProductByMarket1:Nproduct_template_id
ProductTemplateProductComponent1:Nproduct_template_id
MarketProductByMarket1:Nmarket_id
ProductByMarketProductByMarketTranslation1:Nproduct_by_market_id
ProductByMarketProductByMarketFlightConfig1:Nproduct_by_market_id
ProductByMarketFlightConfigProductByMarketFlightLeg1:Nflight_config_id
AirportProductByMarketFlightConfig1:Nairport_id
AirportProductByMarketFlightLeg1:Norigin_airport_id, destination_airport_id

Master definition of a travel package. Defines what a trip IS.

  • Stores base content in source locale
  • Contains itinerary (cities, nights)
  • Auto-calculates duration
  • Has no airport/flight data

Market-specific configuration for selling a template.

  • Links template to a specific market + locale
  • Configures flight search date ranges
  • Unique per template + market + locale combination

Localized content for display.

  • One per ProductByMarket (primary locale)
  • Contains translated titles, descriptions, itinerary
  • Holds SEO metadata (url_slug, meta_*)

Departure airport configuration.

  • One per departure airport per ProductByMarket
  • Defines flight search type (multi_city, separate)
  • Contains all flight legs for that departure

Individual flight segments.

  • Ordered by leg_index
  • Stores origin/destination airports
  • Tracks day_offset from trip start
  • Classifies as international, domestic, or arnk

Components that make up a product template.

  • Links to inventory items (transfers, hotels)
  • Defines sequence and day placement
  • Supports mandatory/optional components
TableColumnsPurpose
products_by_marketproduct_template_id, market_id, localeOne product per template/market/locale
products_by_marketskuUnique market SKU
product_by_market_flight_configsproduct_by_market_id, airport_idOne config per departure airport
product_by_market_translationsproduct_by_market_id, localeOne translation per locale
product_by_market_translationslocale, url_slugUnique URL slugs per locale

All child entities cascade delete from their parents:

flowchart TD
    PT[ProductTemplate deleted] --> PBM[All ProductByMarket deleted]
    PBM --> PBMT[All ProductByMarketTranslation deleted]
    PBM --> PBMFC[All ProductByMarketFlightConfig deleted]
    PBMFC --> PBMFL[All ProductByMarketFlightLeg deleted]
ProductByMarket::with([
'productTemplate',
'market',
'translation',
'flightConfigs.legs',
'flightConfigs.airport',
])->find($id);
ProductByMarket::query()
->where('market_id', $marketId)
->where('status', 'active')
->with(['productTemplate', 'translation'])
->get();
$product->flightConfigs()
->active()
->with('airport')
->get()
->pluck('airport');
ModelLocation
ProductTemplatebackend/app/Models/ProductTemplate.php
ProductByMarketbackend/app/Models/ProductByMarket.php
ProductByMarketTranslationbackend/app/Models/ProductByMarketTranslation.php
ProductByMarketFlightConfigbackend/app/Models/ProductByMarketFlightConfig.php
ProductByMarketFlightLegbackend/app/Models/ProductByMarketFlightLeg.php
ProductComponentbackend/app/Models/ProductComponent.php
Marketbackend/app/Models/Market.php