HostCasa · Conserjería

Convención de Naming & IDs

Naming & ID Convention
Hospitality, Elevated.
01Un prefijo por entidad — nada chocaOne prefix per entity — nothing collides
Entidad / EntityFormato / FormatEjemplo / ExampleRegla / Rule
PropiedadProperty CASA-### + nombre+ poetic name CASA-007 · Casa Marea Secuencial, 3 dígitosSequential, zero-padded
Cliente · MiembroClient · Member HC-XXXX·C HC-7K2Q·8 Código + dígito de controlCode + check digit
Equipo · PersonaTeam · Staff EQ-#### + rol+ role EQ-0142 · Juanita · Limpieza Rol es campo, no prefijoRole is a field, not a prefix
Solicitud · TicketTicket SOL-##### SOL-01042 Secuencial globalGlobal sequential
ReservaBooking RES-XXXX RES-9M4X Código cortoShort code
FacturaInvoice FAC-AAAA-### FAC-2026-014 Año + secuenciaYear + sequence
Por qué importa: un vistazo al prefijo te dice qué es. HC- jamás significa dos cosas; CASA- es siempre una propiedad. Why it matters: the prefix tells you the entity at a glance. HC- never means two things.
02Que no se repitan y que escalenNon-repeating & scalable

La clave: el código NO es aleatorio-y-rezar. Se deriva de un contador interzno con una permutación biyectiva (estilo Sqids/Hashids o Feistel). Cada número entero mapea a exactamente un código y viceversa. The trick: the code is not random-and-pray. It's derived from an internal counter via a bijective permutation (Sqids/Hashids or Feistel). Every integer maps to exactly one code.

Cero colisionesZero collisions

Biyección 1↔1: matemáticamente imposible repetir. Sin consultar la base, sin reintentos. 1↔1 bijection: mathematically impossible to repeat. No DB lookup, no retries.

Escala infinitaInfinite scale

4 chars = 810,000 · 5 chars = 24.3M. Crece de largo solo cuando hace falta. Grows length only when needed.

-- Alfabeto curado (30 símbolos): sin 0 1 I L O U / curated alphabet ALFABETO = "23456789ABCDEFGHJKMNPQRSTVWXYZ" -- id interno secuencial → código de display (biyectivo) codigo = sqids.encode(id_interno) -- 1042 → "7K2Q" display = "HC-" + codigo + "·" + checkChar(codigo) -- unicidad garantizada igual a nivel de base (cinturón + tirantes) ALTER TABLE hc_clientes ADD CONSTRAINT uq_codigo UNIQUE(codigo);
Contador interno = nunca expuesto
Código = no adivinable
UNIQUE en BD = red de seguridad
03Que no se confunda al leer o dictarNo confusion reading or dictating
  • Alfabeto sin gemelos. Fuera 0/O, 1/I/L, U. Nunca dudas si es cero o "o".No look-alike characters — never confuse zero and O.
  • Solo mayúsculas + guion separador. HC-7K2Q se lee en bloques.Uppercase only, hyphen-grouped for readability.
  • Dígito de control (Crockford / mod-37). Un carácter mal tecleado falla al validar al instante.A check digit catches any single mistyped character on the spot.
  • Normalización de entrada. Se quitan espacios, se pasa a mayúsculas; o→ se rechaza, no se adivina.Input is trimmed and uppercased; ambiguous input is rejected, not guessed.
04Cómo validamos el namingHow we validate the naming

El códigoThe code

Validación por regex + dígito de control.

/^HC-[2-9A-HJ-NP-Z]{4}·[0-9A-Z]$/ // + verifica checkChar()

El nombre poéticoThe poetic name

Solo desde un banco aprobado de palabras.

BANCO = [marea,faro,duna,palma, coral,brisa,cala,ola,sal, arena,bahia,roca,vela…]
  • Banco curado = siempre on-brand, pronunciable y sin sorpresas ofensivas.Curated bank = always on-brand, pronounceable, no offensive surprises.
  • Filtro anti-palabras sobre el código generado (descarta combinaciones embarazosas).Profanity filter over generated codes.
  • Unicidad del nombre de propiedad por host: índice único sobre el slug.Property name unique per host via a unique slug index.
  • Regex de forma + longitud 3–14, sin números, capitalizado.Shape regex + length 3–14, no digits, capitalized.
05Naming convention de cada propiedadPer-property naming convention

El nombre poético "Casa [Nombre]" pertenece a la propiedad (el activo físico), no al cliente. Así el cliente HC-7K2Q simplemente "se hospeda en Casa Marea" — coherente y sin choques. The poetic "Casa [Name]" belongs to the property, not the client. Client HC-7K2Q simply "stays at Casa Marea" — coherent, no clashes.

Propiedad / Property nombre : "Casa Marea" // del banco aprobado codigo : "CASA-007" // secuencial slug : "casa-marea" // único por host · para URLs unidad : "CASA-007-U2" // si hay varias suites // colisión de nombre → calificador, nunca número crudo "Casa Marea" → "Casa Marea Norte" / "Casa Marea II"

PropiedadProperty

Casa Marea

CASA-007 · /casa-marea

Cliente en esa propiedadClient at that property

HC-7K2Q·8

Se hospeda en Casa MareaStays at Casa Marea

Decisión a confirmar: ¿el nombre poético es de la propiedad (recomendado) o también quieres un alias cálido por cliente? Decision to confirm: poetic name belongs to the property (recommended) — or do you also want a warm per-client alias?
5bIdentificar a Juanita de la limpiezaIdentifying the team — e.g. housekeeping

Juanita es Equipo, no parte de una casa. Tiene un código estable, un rol (campo, no prefijo — puede cambiar) y asignaciones a una o varias propiedades. Las solicitudes de limpieza se le asignan por su código. Juanita is Team, not part of a single house. She has a stable code, a role (a field, not a prefix — it can change), and assignments to one or more properties. Cleaning tickets route to her by code.

Equipo / Team member nombre : "Juanita Pérez" codigo : "EQ-0142" // estable, neutral rol : "limpieza" // limpieza·mantenimiento·conserje·jardín… asignada_a : ["CASA-007", "CASA-012"] // muchas-a-muchas estado : "activa" // RLS: Juanita solo ve tickets de SUS casas asignadas // display: "Juanita · Limpieza · Casa Marea"

Cómo se veHow it reads

Juanita · Limpieza

EQ-0142 · Casa Marea, Casa Duna

Por qué rol = campoWhy role = field

Si Juanita pasa a conserje, cambia el campo, no el ID. El código nunca miente sobre el pasado.If she becomes a concierge, the field changes — not the ID. The code never lies about history.

Roles: limpieza · mantenimiento · conserje · jardín · anfitrión
Asignación muchas-a-muchas
RLS por casa asignada
5cCómo se ven en el chatHow they appear in chat

Marina es el centro: nadie chatea con todos en un hilo caótico — cada quien habla con Marina y ella enruta. La identifica por teléfono → EQ-0142 y muestra solo "Juanita · Limpieza". En la conversación nadie ve códigos: cada participante aparece con nombre + chip de rol. Hay dos hilos — público (huésped) e interno (equipo) — para que Juanita coordine con Marina sin filtrar nada al huésped. Marina is the hub: everyone talks with Marina and she routes. She identifies people by phone → code and shows only "Juanita · Housekeeping". Nobody sees codes; each participant appears as name + role chip. Two threads — public (guest) and internal (team) — so Juanita coordinates with Marina without leaking to the guest.

Hilo públicoPublic thread · guest sees

Valeria · Huésped Francisco · Anfitrión Marina · Conserje IA

Hilo internoInternal thread · team only

Francisco · Anfitrión Juanita · Limpieza Marina

El huésped nunca ve este hilo.The guest never sees this thread.

Mensaje / message autor_tipo : "equipo" // huesped·anfitrion·equipo·marina autor_id : "EQ-0142" // interno, nunca se muestra display : "Juanita · Limpieza" // + chip verde visibilidad : "interno" // publico | interno
Regla de oro: el código identifica, el nombre + rol comunica. La visibilidad del mensaje decide quién lo lee. Golden rule: the code identifies, the name + role communicates. Message visibility decides who reads it.
5dCada ticket es una Señal 🔦Every ticket is a Signal

Al subir una solicitud, Marina la bautiza con un apodo costero — una bengala al faro. El huésped la recuerda; tú la rastreas por el SOL-##### interno. El apodo es del banco aprobado + un dígito del folio para distinguir repetidos. On upload, Marina names it with a coastal codename — a flare to the lighthouse. The guest remembers it; you track it by the internal SOL-#####. Name = approved word bank + one folio digit to distinguish repeats.

Solicitud / Ticket folio : "SOL-01042" // canónico, único, ordenable senal : "Señal Faro·7" // apodo cool = banco + dígito del folio display : "🔦 Señal Faro·7" // Marina: "Recibí tu solicitud — es la Señal Faro·7 🔦" // banco: faro·marea·duna·coral·brisa·cala·ola·vela·sal·roca·bahía

Lo que ve el huéspedWhat the guest sees

🔦 Señal Faro·7

Memorable, con gancho.Memorable, with a hook.

Lo que rastreas túWhat you track

SOL-01042

Único y ordenable.Unique and sortable.

Un motivo distinto por tipo de soporte — el apodo mismo te dice la categoría. A distinct motif per support type — the codename itself signals the category.

Tipo / TypeMotivo / MotifEjemplo / Example
🌊 ReservaBookingOlawave ashoreOla Coral·2
🪙 PagoPaymentCofretreasureCofre Perla·1
🔑 AccesoAccessLlavekeyLlave Faro·3
⚓ TécnicoTechnicalAnclaanchorAncla Roca·5
🌬️ LimpiezaHousekeepingBrisafreshBrisa Sal·4
🛠️ MantenimientoMaintenanceTimónon courseTimón Duna·2
🔦 OtroOtherSeñalgeneric flareSeñal Faro·7

El apodo se localiza al idioma de la persona — y su idioma revela el locale (es/en). Marina responde y bautiza en esa lengua. The codename localizes to the person's language — and its language reveals the locale (es/en). Marina replies and names in that tongue.

Misma solicitud / same ticket → folio "SOL-01088" (tipo: limpieza) locale "es" (mexa) → display "🌬️ Brisa Sal·4" locale "en" (gringo) → display "🌬️ Breeze Salt·4" // locale es campo en persona/ticket = fuente de verdad // no se infiere etnia — solo idioma preferido para Marina

Host / huésped ESSpanish-speaking

🌬️ Brisa Sal·4

locale = es

Host / guest ENEnglish-speaking

🌬️ Breeze Salt·4

locale = en

Motivo = tipo de soporte / motif = type
Idioma del apodo = locale es/en
Canónico = SOL-#####
Marina contesta en su idioma
06La identidad no es una promociónIdentity is not a promotion

El identificador de una propiedad es permanente y neutral. Estatus, prestigio y campañas nunca viven en el ID — viven aparte, en Promos / membresías. Así nada se confunde con una oferta temporal. A property's identifier is permanent and neutral. Status, prestige and campaigns never live in the ID — they live separately in Promos / memberships. Nothing reads as a temporary offer.

Capa de identidadIdentity layer

Casa Marea

CASA-007 · /casa-marea

Para siempre. No cambia.Forever. Never changes.

Capa de promoción / estatusPromo / status layer

aparte

Vive en Promos y membresías, ligado por CASA-### — nunca dentro del nombre.Lives in Promos & memberships, linked by CASA-### — never inside the name.

Por qué: un sello tipo "fundador" o "premium" dentro del ID se leería como oferta y chocaría con tu módulo de Promos. Separar las capas mantiene la identidad limpia y atemporal. Why: a "founder" or "premium" mark inside the ID would read as an offer and clash with the Promos module. Separating layers keeps identity clean and timeless.