Cada article anterior d'aguesta seria supausaue quauquarren que ja non pòdi supausar: que contrarolam tot eth sistèma. Er article sus eth motor de resèrvas tractaue de resèrvar ua plaça sense competir damb tu madeish. Er article sus era disponibilitat en temps reau tractaue de mantier es numèros consistents en cada ecran qu'un client posquesse èster guardant. Er article sus era multi-tenança tractaue d'aïllar escòles que compartissen infrastructura. Tot açò víu laguens des limits pròpis de Lueira — era nòsta basa de dats, era nòsta API, es nòstes règles.
Es gestors de canal non an aguest luxe. Lueira permet qu'ua escòla connècte es sues activitats a "marketplaces" d'activitats de tresens "de forma rápida y eficiente" — coma ditz literaument era descripcion dera foncion en site — de manèra qu'er inventari d'ua escòla d'esquí aparesque en venda en ua plataforma extèrna, non solament en sòn pròpi "storefront" de Lueira. Aguesta frasa ei simpla. Çò qu'implique dejós, non ac ei.
1. Çò que promet de vertat un gestor de canal
Eth discors entà ua escòla ei dirècte: connècta ua sola viatge e vén pertot. Es tues cinc plaças de classa d'esquí deth dimars ath maitin son es madeishes cinc plaças, que sigue qu'un client reserve per mejan dera tua pròpia pagina o per mejan d'un "marketplace" qu'agrège activitats d'ua dotzea d'operadors dera val. Entà que aguesta promesa se mantengue, Lueira a de parlar damb er API de cada "marketplace", traduir eth nòste modèl intèrn d'activitats, plaças e prètzi ena forma qu'espère aqueth "marketplace", e mantier es dues bandes onèstes sus guairi plaças demoren de vertat. Aquerò ei eth 20% facil dera foncionalitat — un adaptador per "marketplace". Eth 80% dificil ei çò que se passe dempús dera prumèra sincronizacion, en cada cambi a compdar d'alavetz.
2. Disponibilitat que non contròles
Eth problèma de disponibilitat en temps reau que auem resolvut abans supausaue ua soleta font de vertat: era nòsta pròpia basa de dats, es nòstes pròpies escritures, es nòsti pròpis "locks". Un gestor de canal trinque aguesta supausicion a plaser. Ara, es fonts de vertat qu'importen entara resèrva d'un client includen sistèmas que non gerim de cap manèra.
Cada "marketplace" ei diferent. Quauqui envien "webhooks" en madeish moment que quauquarren cambie de sòn costat; d'auti demoren que hascam "polling", limitat pes sòns "rate limits". Quauqui actualizen quasi ar instant; d'auti encoèn cambis pendent es pics de carga. E cadun falhe d'ua manèra diferenta: un API que simplament ei tombada per ua ora, ua soscripcion de "webhook" que dèishe de liurar en silenci, un "marketplace" que confirme ua peticion e dempús jamès arribe a aplicar-la.
3. Gestionar era dobla resèrva que contunhe passant
Ua resèrva heta en un "marketplace" extèrn a de reduïr era disponibilitat en toti es auti lòcs — eth pròpi "storefront" de Lueira e quinsevolh aute "marketplace" connectat — quasi ar instant. Non podem simplament consultar eth nòste pròpi estat en viu, pr'amor qu'er estat que ven de cambiar víu enes servidors d'un aute. I a ua fenèstra en qué es nòsti numèros son vielhs pertot, exceptat en "marketplace" que ven de vénder era plaça.
func handleMarketplaceBooking(w http.ResponseWriter, r *http.Request) {
var evt MarketplaceBookingEvent
if err := json.NewDecoder(r.Body).Decode(&evt); err != nil {
http.Error(w, "bad payload", http.StatusBadRequest)
return
}
// Cada resèrva de "marketplace" pòrte un ID extèrn. Aquerò ei era
// nòsta clau de dedupe — es "webhooks" pòden arribar duplicadi,
// desordenadi, o dempús que ja aguem recuelhut era madeisha resèrva per "polling".
if existing, _ := store.FindByExternalRef(evt.MarketplaceID, evt.ExternalBookingID); existing != nil {
w.WriteHeader(http.StatusOK) // ja tractat, confirmam e contunham
return
}
slot, err := availability.Reserve(evt.ActivityID, evt.SlotID, evt.Spots)
if err != nil {
// Quauquarrés mès ja s'a quedat era plaça. Aguest ei eth flux de desencusa.
notifyOversell(evt)
w.WriteHeader(http.StatusConflict)
return
}
store.RecordExternalBooking(evt.MarketplaceID, evt.ExternalBookingID, slot)
channels.PushAvailabilityUpdate(evt.ActivityID, slot) // propague entà cada aute canal
w.WriteHeader(http.StatusOK)
}
Quan aguesta branca de conflicte se dèishe anar de vertat, eth client de quauquarrés recep un messatge de desencusa, un remborsament e, s'ei possible, ua plaça alternativa. Non auem trobat era manèra de hèr aguesta branca impossibla — solament manèras de hèr-la rara e de gerir-la damb elegància en sòrta de en silenci.
4. Mantier era font de vertat en un solet lòc
Era decision de disenh que evite que açò se convertisque en un caòs ei negar-se a tractar es "marketplaces" extèrns coma igualament autoritatius. Eth pròpi motor de disponibilitat de Lueira contunhe estant era soleta font de vertat. Cada integracion de canal ei ua capa de sincronizacion per dessús, non un egau.
Per dessús d'açò mos calie tanben ua capa de reconciliacion, pr'amor qu'es "webhooks" non son un mecanisme de liurament fisable — arriben duplicadi, desordenadi, o non arriben jamès. Cada notificacion de resèrva entranta a besonh d'un ID extèrn estable damb eth quau hèr dedupe, mès trabalhs de reconciliacion periodics que comparen era nòsta vision damb era deth "marketplace".
Auem estat onèsti damb nosati madeishi en qué açò non barre era distància deth tot. Ua dobla resèrva contunhe passant de quan en quan. Çò qu'auem construït non ei ua garantia que non posque passar — ei ua politica de çò que se passe quan passe. Es gestors de canal son, dejós eth lengatge de marketing, un problèma de sistèmas distribuïts vestit d'industria de viatges.
