Vues BI (bi.*) — contrat de données avec un partenaire externe
Ce que c'est
La base Horizon expose un schéma bi de 27 vues en lecture, consommées par un partenaire externe (outil de reporting / BI côté Buchard). C'est un contrat de données : toute modification d'une colonne exposée est un breaking change pour ce partenaire, qui doit être prévenu avant la mise en prod.
Les vues ne sont pas gérées par EF Core : elles vivent uniquement en base (pas de migration, pas de fichier dans le repo). Elles n'apparaissent donc dans aucun diff — d'où la règle de notification du CLAUDE.md (section « Vues BI »).
Points structurants
- Aucune vue n'utilise
SELECT *: toutes listent explicitement leurs colonnes.- Conséquence 1 : ajouter un champ à une table ne casse rien, mais le partenaire ne le voit pas. Si le champ l'intéresse, il faut modifier la vue (
ALTER VIEW) — décision à prendre avec lui. - Conséquence 2 : renommer ou supprimer une colonne listée casse la vue à l'exécution (
Invalid column name), silencieusement jusqu'à la première requête du partenaire.
- Conséquence 1 : ajouter un champ à une table ne casse rien, mais le partenaire ne le voit pas. Si le champ l'intéresse, il faut modifier la vue (
- Filtrage volontaire de données sensibles :
bi.BookingPassengerscommente explicitementIBANetMedicalCertificatedans sa définition. Ne jamais les réintroduire sans arbitrage. - Aucune vue ne filtre
IsDeleted: les soft-deletes sont exposés tels quels, avec la colonneIsDeletedquand elle existe. Le filtrage est à la charge du partenaire.
Correspondance vue → table(s) dbo
Le nom de la vue correspond à la table sous-jacente sauf dans ces 3 cas :
| Vue | Table(s) source |
|---|---|
bi.DriveOccurrence | dbo.OneDayTravelDriveOccurrences |
bi.Stops | dbo.DriveStops jointe à dbo.Stops (colonnes des deux) |
bi.CustomerSubscriptions | dbo.CustomerSubscriptions jointe à dbo.Subscriptions (pour Name) |
Les 24 autres sont un simple SELECT <colonnes> FROM dbo.<MêmeNom> : Accommodations, BookingPassengers, Bookings, Customers, Drives, InvoiceItems, Invoices, Lines, OccurrenceCosts, OccurrenceCostVariousCosts, Occurrences, OccurrenceVehicles, Passengers, TravelCategories, TravelDayAccommodations, TravelDays, TravelDayVehicles, TravelLines, TravelOccurrences, TravelRanges, Travels, TravelTravelRange, Vehicles, VehicleTypes.
Tables dbo sous surveillance
Toute modification de colonne sur l'une de ces tables déclenche la notification :
Accommodations, BookingPassengers, Bookings, Customers, CustomerSubscriptions, DriveStops, Drives, InvoiceItems, Invoices, Lines, OccurrenceCosts, OccurrenceCostVariousCosts, Occurrences, OccurrenceVehicles, OneDayTravelDriveOccurrences, Passengers, Stops, Subscriptions, TravelCategories, TravelDayAccommodations, TravelDays, TravelDayVehicles, TravelLines, TravelOccurrences, TravelRanges, Travels, TravelTravelRange, Vehicles, VehicleTypes.
Pièges connus
bi.TravelsexposeCapacity,CapacityMax,CapacityTotal,CapacityVehicle,CapacityAccommodationetLoadingLineId— champs dépréciés côté Horizon (cf. règles immuables 4 et 5 du CLAUDE.md). On ne les utilise plus, mais on ne peut pas les supprimer sans casser le partenaire.bi.Customersexpose les 5 colonnesClubMembership*/DoNotRenewMembership: les anomalies de données Club (dates epoch 1970, doubles facturations) sont donc visibles côté partenaire.bi.Occurrencesexpose[End]etStart— mots réservés, toujours entre crochets dans la vue.- Les colonnes listées plus bas sont un instantané au 31.08.2026. Pour l'état réel, interroger la base plutôt que de faire confiance à ce fichier.
Vérifier l'état réel des vues
# Colonnes exposées par vue
sqlcmd -S localhost,1433 -U sa -P 'Password12!' -d Horizon -C -y 0 -Y 0 -i requete.sql
# requete.sql :
# SET QUOTED_IDENTIFIER ON;
# SELECT v.name + ' | ' + STUFF((SELECT ', ' + c.name FROM sys.columns c
# WHERE c.object_id = v.object_id ORDER BY c.column_id FOR XML PATH(''), TYPE).value('.','nvarchar(max)'),1,2,'')
# FROM sys.views v JOIN sys.schemas s ON s.schema_id = v.schema_id WHERE s.name = 'bi' ORDER BY v.name;
# Définition SQL complète d'une vue
# SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('bi.Bookings');Colonnes exposées (instantané 31.08.2026)
| Vue | Colonnes exposées |
|---|---|
Accommodations | AdultMax, AdultMin, AllInclusive, AllInclusivePrice, Breakfast, BreakfastPrice, ChildMax, ChildMin, ContactId, CreatedAt, Currency, DeletedAt, Description, ExternalId, ExtraChargeAdult, ExtraChargeAdultType, ExtraChargeChild, ExtraChargeChildType, ExtraChargeJunior, ExtraChargeJuniorType, FullBoard, FullBoardPrice, GlobeId, HalfBoard, HalfBoardPrice, Id, Internal, IsDeleted, JuniorMax, JuniorMin, MealPlan, Name, ProgramBoard, ProgramBoardPrice, Ranking, SearchData, SupplierId, TouristTax, TourOperatorId, Type, UpdatedAt |
BookingPassengers | BookingId, CancellationDate, CancellationFees, CancellationInsuranceId, Cancelled, LoadingStopId, LoadingTimetableStopId, MealPlan, PassengerId, Price, TripType, UnloadingStopId, UnloadingTimetableStopId |
Bookings | Amount, BookingDate, CancellationAction, CancellationDate, ConfirmationDate, CreatedAt, CustomerId, CustomerIncludeInBooking, DeletedAt, FinalAmount, GlobeId, Id, IsDeleted, Legacy, Number, NumberOfPassengers, Origin, SellerId, Status, TravelOccurrenceId, UpdatedAt |
Customers | Address, BadPayer, Birthdate, City, Civility, Company, CreatedAt, Discount, DiscountType, EMail, Enabled, FirstName, FullName, Gender, GlobeId, Id, IsGroup, Name, NavNo, Newsletter, NoEMail, NoMobile, Phone, State, TravelBan, Type, UpdatedAt, Zip, ClubMembershipType, ClubMembershipCode, ClubMembershipStart, ClubMembershipEnd, DoNotRenewMembership |
CustomerSubscriptions | CustomerId, SubscriptionId, Name (← Subscriptions.Name), Enabled |
DriveOccurrence | Id, DriveId, OccurrenceId, Quota, IsDeleted |
Drives | CreatedAt, DeletedAt, Distance, Id, IsDeleted, IsOneShot, LineId, Name, RoundTrip, UpdatedAt |
InvoiceItems | Description, Id, InvoiceId, Price |
Invoices | BookingId, BusinessAxis, Category, CreatedAt, CustomerId, Date, DueDate, Enabled, GiftId, Id, NavNo, Number, Total, Type, UpdatedAt, UserId, VatGroup |
Lines | CreatedAt, DeletedAt, Id, IsDeleted, Name, UpdatedAt |
OccurrenceCosts | Id, FlightIncluded, Flight, FlightCurrency, FlightCostPerCustomer, CruiseIncluded, Cruise, CruiseCurrency, CruiseCostPerCustomer, TourOperatorMin, TourOperatorMax, TourOperatorCurrency, VatType |
OccurrenceCostVariousCosts | Id, OccurrenceCostId, Name, Amount, Currency, PerCustomer |
Occurrences | Billed, BreakEvenPoint, CreatedAt, DeletedAt, End, ExpectedPassengers, GlobeId, Id, IsDeleted, LoadingTableBackId, LoadingTableId, MinutesForADayOfWork, NavNo, OccurrenceCostId, SellingPrice, SellingPriceChild, SellingPriceJunior, SettingGeneralId, Start, Status, UpdatedAt |
OccurrenceVehicles | Id, OccurrenceId, VehicleId |
Passengers | Birthdate, CustomerId, Firstname, Id, Name |
Stops | Id (DriveStops.Id), DriveId, Place, Locality, Lat, Long (← Stops), Order, State, CreatedAt, DeletedAt, IsDeleted, UpdatedAt, OccurrenceId, Before, Transfer, StopId |
TravelCategories | CreatedAt, DeletedAt, Id, IsDeleted, Name, UpdatedAt |
TravelDayAccommodations | Id, TravelDayId, AccommodationId, Main |
TravelDays | Id, TravelId, TourOperator, Name, Description, Distance |
TravelDayVehicles | DisplayOnWebsite, Distance, EmptyReturn, FlightOrFerry, Id, JourneyEnd, JourneyStart, TourOperator, TravelDayId, VehicleId |
TravelLines | LineId, TravelId, IsUnloading |
TravelOccurrences | CreatedAt, DeletedAt, Id, IsDeleted, IsPriority, OccurrenceId, TravelId, UpdatedAt |
TravelRanges | CreatedAt, DeletedAt, Id, IsDeleted, Name, UpdatedAt |
Travels | AccommodationId, BusinessAxis, Capacity, CapacityAccommodation, CapacityMax, CapacityTotal, CapacityVehicle, CategoryId, CountryId, CreatedAt, DeletedAt, DistanceLoading, DistanceUnloading, Duration, EarlyBooking, EarlyBookingDate, EarlyBookingValue, FlightOnly, GlobeId, Id, IsDeleted, Legacy, LoadingLineId, MainTravelRangeId, Name, NoVehiclePlan, OccurrenceRelatedTravel, Progress, Slug, StageProgressValueId, Status, TravelParentId, Type, UnloadingLineId, UpdatedAt, VehicleId |
TravelTravelRange | TravelRangesId, TravelsId |
Vehicles | Capacity, CostByKm, CreatedAt, DeletedAt, DepreciationChargesPerDay, GlobeId, Id, Internal, IsDeleted, Name, NoCapacity, NumberOfDecker, NumberOfVehicle, TypeId, UpdatedAt, Vip |
VehicleTypes | Id, Name |

