Apariencia
Catálogos
Los catálogos son las tablas de referencia que alimentan los dropdowns, filtros y selectores de toda la plataforma. Un admin los gestiona desde /admin/catalogos.
Catálogos disponibles
| Catálogo | Tabla DB | Uso principal | Cantidad típica |
|---|---|---|---|
| Países | countries | Ubicación candidatos/empresas/vacantes | 1–30 |
| Estados/Provincias | states | Jerarquía bajo países | 32 (MX) + más |
| Ciudades | cities | Jerarquía bajo estados | 500+ |
| Áreas funcionales | functional_areas | Filtro directorio + áreas de interés candidato + clasificación de vacantes | 21 (default) |
| Niveles de carrera | career_levels | Junior, Mid, Senior, Lead, Director | 7 |
| Posiciones | positions | Puestos específicos | 200+ |
| Industrias | industries | Clasificación de empresas | 20 |
| Tamaños de empresa | company_sizes | 1-10, 11-50, 51-200, etc. | 6 |
| Tipo de propiedad | ownership_types | Privada, pública, ONG, gobierno | 4 |
| Niveles educativos | degree_levels | Bachillerato, Lic, Maestría, Doc | 6 |
| Habilidades | skills | Pool para candidatos y vacantes | 150+ |
| Idiomas | languages | Pool con niveles MCER | 20 |
| Monedas | salary_currencies | MXN, USD, EUR, ... | 5 |
| Categorías de vacantes | vacancy_categories | Full-stack, Diseño, QA, etc. | 15 |
| Tipos de vacante | vacancy_types | Full-time, part-time, freelance, prácticas | 5 |
| Turnos | vacancy_shifts | Diurno, nocturno, mixto | 4 |
Operaciones CRUD
Todos los catálogos exponen las mismas operaciones:
| Operación | Método | Ruta |
|---|---|---|
| Listar | GET | /admin/catalogos/{resource} |
| Crear | POST | /admin/catalogos/{resource} |
| Actualizar | PATCH | /admin/catalogos/{resource}/{id} |
| Desactivar | DELETE | /admin/catalogos/{resource}/{id} (soft delete; is_active = false) |
| Reactivar | POST | /admin/catalogos/{resource}/{id}/restore |
Áreas funcionales
Las áreas son el catálogo más visible del sistema porque alimentan tres lugares a la vez:
- Áreas de interés del perfil del candidato (multi-select con principal).
- Filtro del directorio del recruiter (
functional_area_ids[]yprimary_functional_area_id). - Clasificación de la vacante (
functional_area_id) y la lógica de matching.
Default seed (21 áreas, las 15 del PDF + 6 auxiliares):
| Code | Name | Origen |
|---|---|---|
manufacturing | Producción | |
quality | Calidad | |
maintenance | Mantenimiento | |
logistics | Logística | |
hr | Recursos Humanos | |
admin | Administración | |
industrial_safety | Seguridad Industrial | |
warehouse | Almacén | |
sales | Ventas | |
engineering | Ingeniería | |
purchasing | Compras | |
it_systems | Sistemas | |
customer | Atención al cliente | |
operations | Operación | |
finance | Finanzas | |
product | Producto | auxiliar |
design | Diseño | auxiliar |
data | Datos / Analítica | auxiliar |
marketing | Marketing | auxiliar |
legal | Legal / Compliance | auxiliar |
other | Otra | auxiliar |
Si el cliente pide ajustes (renombrar, agregar áreas específicas de su industria, ocultar las auxiliares), el admin lo resuelve en runtime sin tocar código.
Endpoints CRUD (público de lectura + admin protegido):
| Método | Ruta | Quién |
|---|---|---|
| GET | /api/v1/catalogs/functional-areas | Cualquier user autenticado (lectura activos) |
| GET | /api/v1/admin/catalogs/functional-areas?q=Calidad | admin (incluye inactivos, búsqueda por nombre/code) |
| POST | /api/v1/admin/catalogs/functional-areas | admin |
| PATCH | /api/v1/admin/catalogs/functional-areas/{id} | admin |
| DELETE | /api/v1/admin/catalogs/functional-areas/{id} | admin (FK nullOnDelete, seguro borrar) |
Tab en el panel admin (/admin/catalogos → "Áreas funcionales"):
[ Habilidades ] [ Idiomas ] [ Niveles académicos ] [ Áreas funcionales ]
Áreas funcionales
21 totales · 21 activos · 0 desactivados [ + Agregar ]
🔍 Buscar por nombre o código…
┌──────────────────────────────────────────────────────────┐
│ Producción [manufacturing] ✏ 🗑 │
│ Calidad [quality] ✏ 🗑 │
│ Mantenimiento [maintenance] ✏ 🗑 │
│ ... │
└──────────────────────────────────────────────────────────┘Validación al crear/editar (FunctionalAreaRequest):
coderequerido, único, regex^[a-z0-9_-]+$, máx 60.namerequerido, máx 120.descriptionopcional, máx 500.sort_orderint ≥ 0.is_activeboolean (default true).
Caso de uso: agregar "Comercio Exterior" porque un cliente lo pidió
- Admin entra a
/admin/catalogos→ tab "Áreas funcionales" → botón "Agregar". - Llena
code = comercio_exterior,name = Comercio Exterior,description = Importaciones, exportaciones, aduanas. - Guardar → toast
Área creada. - Inmediatamente disponible para candidatos al guardar su perfil y para el form de vacantes (TanStack Query invalida ambos
catalogs.functional-areasy el cache admin).
Caso de uso: ocultar áreas que el cliente no usa
- Buscar el área (ej.
marketing) → click ✏ Editar. - Desmarcar "Activo (visible a candidatos)" → guardar.
- El área desaparece de los selectores nuevos pero los perfiles que ya la tenían siguen mostrándola en su histórico (no se borra el pivote).
Ejemplos
Agregar una skill nueva
Escenario: un candidato usó "Rust" y no existía en el catálogo.
POST /admin/catalogos/skills
{
"name": "Rust",
"slug": "rust",
"category": "language",
"description": "Lenguaje de programación de sistemas"
}slugse genera concocur/slugifysi no se envía.- Unique constraint:
slug. - Los candidatos ya existentes no se ven afectados.
Jerarquía de ubicación
Country (México)
├── State (Ciudad de México)
│ ├── City (Cuauhtémoc)
│ ├── City (Álvaro Obregón)
│ └── City (Coyoacán)
├── State (Jalisco)
│ └── City (Guadalajara)- Al crear
State, se requierecountry_id. - Al crear
City, se requierestate_id. - Borrar una
Countryestá prohibido si tiene estados hijos con datos asociados (FK constraint).
Desactivar vs borrar
- Desactivar (
is_active = false): el catálogo deja de aparecer en selectores nuevos pero los registros existentes se mantienen. Recomendado. - Borrar hard: solo permitido si no tiene referencias (FK cascade configurado para forbid).
Reglas globales
- Todos los catálogos tienen campos comunes:
id,name,slug,is_active,sort_order,created_at,updated_at. - Los slugs se usan en URLs (
/directorio?skill=react). sort_orderdefine el orden en los dropdowns (menor primero).- Los nombres deben estar en español (HUMAE es MX-primero; i18n a fase 2).
Seeders de inicio
Al correr php artisan db:seed, se cargan catálogos mínimos:
CountriesSeeder— México y 10 países latinoamericanos.StatesSeeder— 32 estados de México.MajorCitiesSeeder— top 50 ciudades de México.SkillsSeeder— 150 skills populares.LanguagesSeeder— 20 idiomas con niveles A1-C2.JobTaxonomySeeder— career levels, degree levels, functional areas (21), vacancy categories/types/shifts/tags, posiciones.RolesAndPermissionsSeeder— 45 permisos + 4 roles (Spatie).MembershipPlanSeeder— plancandidate_6m499 MXN.PsychometricBigFiveSeeder— Big Five en español.PdfDemoSeeder(solo dev/staging) — 5 candidatos demo (mix empleado/practicante en distintas áreas) + 5 vacantes demo + 1 empresa para probar matching de inmediato. Ver Setup backend.
Importación masiva (Fase 2)
Desde el panel admin se subirá un CSV:
- Formato:
name, slug, sort_order, is_active. - Validación de duplicados por slug.
- Preview antes de ejecutar.
UI del panel admin
/admin/catalogos es una navegación con tabs por tipo de catálogo. Cada tab:
- Tabla con columnas: nombre, slug, activo, orden, creado.
- Búsqueda + paginación.
- Botón "Agregar".
- Edición inline o modal.
- Confirmación antes de desactivar.
Permisos
- Solo
admintiene acceso a/admin/*. Un recruiter intentando acceder ve 403. CatalogPolicysin bypass implícito.
Siguiente
Monitoreo: Reportes →

