Multi-restaurant de debò: com modelem cadenes i franquícies
Una de les primeres coses que vam veure a les entrevistes va ser que moltes operacions tenen més d'un local. No parlem només de cadenes grans; parlem d'un grup familiar amb dos restaurants de carn i una cerveseria, o d'una franquícia petita amb tres locals a la mateixa ciutat. Si el programari t'obliga a crear un compte per lloc i reescriure les dades cada vegada, te'l pots arribar a odiar gratuïtament.
Per això, a l'octubre, vam dedicar un parell de setmanes a un tema que sembla intern i avorrit però que defineix el sostre del producte: com modelem les dades.
Workspace, restaurant, membres
El nucli del model gira al voltant de tres entitats:
- Workspace. És el contenidor d'una organització. Un grup hostaler, una franquícia, o simplement un restaurant independent que es queda amb un sol workspace.
- Restaurant. Cada local físic. Un workspace en pot tenir un o diversos.
- Membres. Persones amb accés. Un encarregat pot tenir visibilitat dels tres restaurants del grup; un cambrer, només del seu.
La gràcia és que la relació és real: si afegeixes un client des del local A i després visita el local B del mateix grup, l'equip del B sap que és habitual de la casa. La fitxa de client viu a nivell de workspace, no de restaurant. Això obre portes per a fidelització creuada que veurem més endavant.
RLS: la xarxa de seguretat
Aquí és on entra el Row Level Security de Postgres. En lloc de filtrar "WHERE workspace_id = X" a cada consulta del backend (i resar perquè cap becari no se n'oblidi), les mateixes polítiques de la base de dades impedeixen que un usuari llegeixi dades que no són seves. Encara que el codi d'aplicació tingui un bug, la base de dades no li tornarà res.
Configurar-ho bé va costar. Vam fer:
- Una política per taula, restrictiva per defecte.
- Un script d'auditoria (
npm run audit:cross-restaurant) que recorre les taules i verifica que cap no s'hagi quedat sense polítiques. - Migracions explícites amb tests manuals: crear dos workspaces, mirar de llegir dades de l'altre, comprovar que torna zero files.
El que costa aquesta decisió
No surt gratis. Multi-tenant des del dia 1 implica:
- Tota consulta porta un workspace_id. Oblidar-lo és un bug de seguretat, no un bug funcional.
- Els índexs de la base de dades s'han de dissenyar pensant en aquest filtre extra.
- El canvi de restaurant a la interfície ha de ser instantani i no perdre estat.
Però a canvi, evitem el que vam veure passar a competidors: començar mono-tenant i, quan arriba el primer client amb tres locals, reescriure mig producte.
Com es veu per a l'usuari
Tota aquesta complexitat acaba en un detall molt petit a la interfície: un selector de restaurant a dalt a l'esquerra. El prems, canvies de local, i tot el que veus s'hi ajusta. La part difícil queda amagada; que és com ha de ser.