metis-desk/docs/auditorias/workplace-dashboard/01-inventario-funcional.md

33 KiB
Raw Blame History

Inventario funcional del puesto de trabajo

Fecha: 22 de octubre de 2026. Auditoría estática del árbol de trabajo, incluidos sus cambios locales previos. Entrada a los entregables: resumen ejecutivo.

Alcance y evidencia

La entidad implementada es Workstation, en el módulo Assets; «Workplace» es el nombre de la carpeta solicitado para esta auditoría, no otro agregado. Companies compone su ficha. El objetivo de diseño asumido es ayudar al técnico a identificar el puesto, entender su composición y consultar sus entornos de usuario. Esta hipótesis no sustituye investigación con usuarios.

Etiquetas utilizadas en todos los documentos:

  • CONFIRMADO: inspeccionado en implementación; no implica ejecución ni comprobación de la BD instalada.
  • DERIVABLE: necesita el recorrido o cálculo descrito sobre fuentes existentes.
  • DOCUMENTADO: aparece en documentación, sin implementación confirmada para esa afirmación.
  • PROPUESTO: decisión de presentación o desarrollo futuro.
  • NO DISPONIBLE: no localizado en el ámbito y búsquedas declarados.

La implementación se ha mantenido en solo lectura. No se ha consultado una BD ni iniciado la API: su arranque ejecuta migraciones. No se han creado usuarios ni fixtures persistentes. El JSON entregado es exclusivamente un ejemplo de diseño. La sintaxis y los contratos de ese ejemplo se verifican sin acceso a red ni BD; véase el registro de validaciones en viabilidad.

Tecnologías verificadas

Fuente Declaración comprobada
package.json raíz Node >=24 <25; PNPM 11.25.0. Entorno ejecutado: Node 24.20.0, PNPM 11.25.0
apps/web/package.json React 19.2.5, Vite 8.3.0, TanStack Query 5.98.0, Tailwind 4.2.2, i18next 26.0.4
apps/server/package.json Express 4.22.1, Sequelize 6.37.8, driver MariaDB 3.5.4, Zod 4.3.6
apps/web/components.json base-vega, RSC desactivado, iconografía Tabler
packages/shadcn-ui/components.json Vendor base-vega, con su iconografía interna Lucide conservada
modules/assets/package.json, modules/companies/package.json React Hook Form 7.72.1, TanStack Table 8.21.3; APIs públicas ./client, ./common, ./module

Son versiones declaradas en manifests, no una certificación de ejecución de cada dependencia. TypeScript 6.0.2 está fijado en la raíz.

Atributos completos del puesto

Fuentes normativas de datos: WorkstationInputSchema, WorkstationSchema, WorkstationValues, Workstation y WorkstationPersistenceMapper (referencias E01–E06 al final).

Campo Tipo / obligatorio Origen Uso funcional Visible actualmente
id UUID; sí Identidad del agregado, columna workstations.id URL, comandos y referencias En URL; sin campo de lectura específico
companyId UUID; sí Columna y contexto de inventario Ámbito de compañía atendida Contexto del shell y URL
values.name String 1–100; sí Columna name; VO Name Identidad legible; nombre normalizado por VO Cabecera editable e historial
values.active Boolean; sí Columna active Estado del puesto y reserva de miembros Cabecera, edición e historial
values.siteId UUID o null; clave requerida FK company_sites Sede del puesto Cabecera enlazada al listado de sedes
values.personId UUID o null; clave requerida FK company_contacts Responsable del puesto Cabecera si existe y panel Personas
values.computerAssetId UUID, null o ausente FK assets; el VO omite la propiedad si no hay ordenador Ordenador principal; asociación de perfiles y software Equipamiento e historial
values.assetIds UUID[]; requerido, 0–200 workstation_members Composición exclusiva actual; sin duplicados Ordenador y demás activos
history Revisiones, mínimo 1 workstation_revisions y workstation_revision_members Instantáneas completas del puesto Pestaña Historial
history[].id UUID; sí Identidad de revisión Identificar revisión, no entidad relacionada nueva Clave interna de cronología
history[].values Mismo contrato de valores Columnas de revisión y sus miembros Estado en cada revisión Valores de la cronología
history[].actorId UUID; sí FK users Operador que registró la revisión No como campo independiente
history[].actorName String no vacío; sí en DTO Resuelto desde usuarios al construir respuesta Mostrar autor Cronología; no es snapshot histórico del nombre del usuario
history[].recordedAt ISO datetime; sí Columna de revisión Momento de registro Cronología localizada
position, activeKey, kind de miembros Internos de persistencia Tablas relacionales / proyección Orden, reserva exclusiva y coherencia No son campos de negocio del DTO

NO DISPONIBLE en el agregado: descripción, notas propias, tipología propia del puesto, departamento propio, coordenadas, fecha contractual de ocupación, createdAt y updatedAt como campos raíz, métricas de salud o disponibilidad online. Se inspeccionaron E01–E06 y la persistencia. Las notas y características pertenecen a activos/perfiles/recursos, no al puesto.

DERIVABLE: fecha de registro inicial = primera revisión; última modificación registrada = última revisión. No equivalen a antigüedad del equipo, alta laboral ni fecha efectiva de asignación. El orden de assetIds se conserva al persistir, pero su igualdad de dominio ignora reordenaciones; no prometer una función de ordenación persistente sin revisar ese contrato.

Reglas funcionales

Regla CONFIRMADA Fuente / consecuencia
El ordenador principal, si se indica, debe estar en assetIds WorkstationValues.create; no es un miembro adicional
Miembros únicos y máximo 200 Schema y VO; vacío válido, incluso en puesto activo
Sede y persona deben existir en contexto de compañía mapWorkstationInput; se puede conservar una referencia inactiva previamente existente
Nuevo miembro de puesto activo debe ser operativo memberError; permite conservar un miembro de un puesto antes activo aunque deje de ser operativo
Un activo no puede estar en dos puestos activos Validación de aplicación y workstation_assets.activeKey único
Puesto inactivo no reserva activos Mapper; las referencias históricas no equivalen a composición actual
Desmantelar desactiva, vacía miembros, ordenador y responsable; conserva sede y nombre Workstation.decommission; crea revisión solo si hay cambio
Actualización semánticamente idéntica no crea revisión Workstation.update; no es garantía universal de idempotencia de creación
Fechas de revisión válidas y no decrecientes Agregado y mapper; última instantánea debe coincidir con valores actuales
Borrar elimina el puesto y sus revisiones, no los activos Repositorio, transacción; referencias externas pueden impedirlo con WORKSTATION_IN_USE

No se encontró una exigencia de categoría «ordenador» sobre computerAssetId en el mapper del puesto. La aptitud como host se valida al activar perfiles (isProfileHost en profileReferencesAvailable); no confundir la selección del editor con una invariante backend adicional.

Datos de entidades relacionadas

Entidad Datos que pueden aportar contexto; fuente
Compañía id, nombre, estado, logo opcional; personas, contactos, sedes, departamentos, asignaciones en CompanySchema
Sede Nombre, estado, dirección, teléfono; SiteSchema
Persona Nombre, cargo textual position, email, teléfono, estado, isContact, foto opcional; PersonSchema
Asignación departamental Persona, departamento, cargo, fechas, principal y revisiones; DepartmentAssignmentSchema
Activo Nombre, plantilla/especificación, sede, marca opcional, registeredOn opcional, estado técnico, notas, características tipadas, assigned, displayStatus, revisiones; AssetSchema
Perfil Persona, activo host, cuenta opcional, nombre, activo, notas, needsReview, revisiones; WorkProfileSchema
Software instalado Activo, recurso aplicación/OS, licencia opcional, versión, estado, notas, revisión y needsReview; SoftwareInstallationSchema
Configuraciones Carpetas, correo, impresoras, aplicaciones y certificados referidos por profileId; tienen estados y revisiones propios
Recursos/accesos Catálogo de recursos, recursos SMB, publicaciones, cuentas, necesidades, concesiones y coberturas; detalle en mapa
Conectividad Soporte de activo; conexiones remotas y autorización de teletrabajo de persona; no hay modalidad presencial/remota propia del puesto
Infraestructura Roles de activo, interfaces ethernet/wifi/other, MAC, direcciones IPv4/IPv6, notas e historial; InfrastructureSchema (E35). Son datos registrados, no telemetría
Buzones y usos MailboxSchema, MailboxUseSchema: dirección, tipo, contexto, cuenta opcional y asignaciones temporales de uso por persona (E36)
Procesos Altas/cambios/bajas de persona con tareas y referencias tipadas; no son tickets ni FK directa al puesto

Localización de implementación y responsabilidades

Las rutas de esta tabla son relativas a la raíz. En los conjuntos con varios ficheros se enumeran las unidades relevantes, sin implicar que exista un modelo ORM por cada agregado.

Elemento Ruta exacta / responsabilidad
Valores y agregado modules/assets/src/api/domain/workstation-values.ts, value-objects/workstation-values.vo.ts, workstation.aggregate.ts, workstation-revision.entity.ts
Puerto de repositorio modules/assets/src/api/application/asset.repository.ts: IAssetRepository, contexto de inventario y comandos de puesto
Casos de uso y mapper modules/assets/src/api/application/workstation.use-cases.ts, workstation-input.mapper.ts, workstation-response.builder.ts
HTTP modules/assets/src/api/infrastructure/http/workstation.routes.ts: alta, actualización, desmantelamiento y borrado
Persistencia modules/assets/src/api/infrastructure/persistence/sequelize-asset.repository.ts, workstation-persistence.mapper.ts, load-workstations.ts, workstation-relational.ts
Modelo/migración modules/assets/src/api/infrastructure/persistence/workstation.model.ts: WorkstationAssetModel, migrateWorkstations; raíces leídas/escritas mediante SQL parametrizado, no WorkstationModel
Retirada de miembros compartidos modules/assets/src/api/infrastructure/persistence/remove-shared-workstation-assets.ts
Contratos modules/assets/src/common/workstations.ts, inventory.ts
Composición servidor modules/assets/src/api/module.ts, modules/companies/src/api/module.ts, apps/server/src/index.ts
Ficha modules/companies/src/web/workstations/detail/ui/workstation-detail-page.tsx, workstation-detail-content.tsx, workstation-assets.tsx, workstation-people.tsx, workstation-profiles.tsx
Coordinación modules/companies/src/web/workstations/detail/controllers/use-workstation-detail-controller.ts
Cálculo de relaciones e inversa modules/companies/src/web/workstations/detail/helpers/workstation-relations.ts, person-workstations.ts
Entrada de compañía modules/companies/src/web/companies/detail/ui/company-inventory.tsx
Listado y controlador modules/assets/src/web/workstations/list/ui/workstations-page.tsx, list/controllers/use-workstations-page-controller.ts
Editor modules/assets/src/web/workstations/shared/ui/workstation-editor-dialog.tsx, workstation-form.tsx, workstation-identity-fields.tsx, workstation-association-fields.tsx, workstation-computer-field.tsx, workstation-asset-fields.tsx, workstation-form-actions.tsx
Estado y creación modules/assets/src/web/workstations/shared/controllers/use-workstation-form-controller.ts, shared/helpers/workstation-creation.ts, shared/workstation-name.ts
Acciones modules/assets/src/web/workstations/shared/ui/workstation-actions.tsx, workstation-lifecycle-dialog.tsx
Renombrado modules/assets/src/web/workstations/rename/ui/workstation-name-editor.tsx, rename/api/rename-workstation.api.ts
Historial modules/assets/src/web/workstations/history/ui/workstation-history.tsx, workstation-history-dialog.tsx
Cliente HTTP y claves modules/assets/src/web/workstations/shared/api/save-workstation.api.ts, modules/assets/src/web/shared/api/inventory-request.ts, modules/assets/src/web/shared/queries/index.ts
Rutas de compañía modules/companies/src/web/workspace/shared/helpers/workspace-routes.ts; selección de ficha por UUID
Traducciones modules/assets/src/common/locales/es.json, en.json; claves workstationDetail, workstationLifecycle, workstationComputer, workstationPerson. Perfiles/configuraciones usan modules/companies/src/common/locales/es.json, en.json
Tests de dominio/UI modules/assets/src/api/domain/workstation.test.ts; modules/companies/src/web/workstations/detail/helpers/workstation-relations.test.ts; detail/ui/workstation-detail.test.tsx
Tests de edición/alta modules/assets/src/web/workstations/shared/helpers/workstation-creation.test.ts, shared/workstation-name.test.ts, rename/api/rename-workstation.test.ts
Integración apps/server/src/workstations.integration.ts, workstation-lifecycle.integration.ts; no se ejecutan aquí porque requieren persistencia

APIs y acciones existentes

Operación Contrato Efecto / exposición actual
Consultar puesto GET /api/assets/:companyId Devuelve inventario completo con workstations, activos y relaciones. El controller selecciona el UUID; no se encontró GET individual del puesto
Crear POST /api/assets/:companyId/workstations con {values} 201, revisión inicial; se inicia en listado
Editar / renombrar / cambiar composición POST /api/assets/:companyId/workstations/:id/update con {values} 200; cabecera y modal; renombrado reutiliza comando de guardado
Desmantelar POST /api/assets/:companyId/workstations/:id/decommission, body {} Menú con confirmación; libera reserva, no desactiva perfiles automáticamente
Borrar POST /api/assets/:companyId/workstations/:id/delete, body {} Confirmación; retorno al listado tras éxito; puede fallar por referencias
Crear perfil POST /api/work-profiles/:companyId Modal separado; la ficha requiere puesto activo, ordenador presente y no retirado; aplicación valida además host, persona y cuenta
Software GET/POST /api/software-installations/:companyId, POST /:id/update, POST /:id/delete bajo esa base Panel filtra por ordenador principal, permite alta, edición, historial, borrado
Navegar /companies/:companyId/workstations/:id, /people/:id, /assets/:id, /work-profiles/:id, /resources/:id Enlaces reales; sede apunta a /sites, sin ficha individual de sede

Errores HTTP de comandos de puesto: 400 para INVALID_REQUEST, 404 para códigos terminados en NOT_FOUND, 409 para otros fallos de negocio; excepciones se propagan al middleware. Autenticación y límites del aislamiento: viabilidad.

Skills y normativa aplicadas

Se inspeccionaron las 15 carpetas de .agents/skills/ y las 15 entradas de skills-lock.json. Los hashes del lock no equivalen a releases ni se verificó upstream.

Skill leída Criterio aplicado
ux-dashboard — principal Empezar por preguntas operativas; priorizar y justificar cada indicador; evitar gráficos decorativos
ux-tables Elegir tabla para comparación y lista para lectura; formatos, volumen, búsqueda y acciones accesibles; prevalece el patrón Metis de acciones visibles
ux-design-review Unificar hallazgos por prioridad y separar evidencia estática, reproducción y pendientes
shadcn y referencias de composición/Base vs Radix Comprobar APIs instaladas y wrappers antes de proponer componentes; render de Base UI, títulos y estructura semántica
vercel-composition-patterns, regla architecture-avoid-boolean-props Bloques por responsabilidad y composición explícita; sin componente universal de dashboard
vercel-react-best-practices, reglas async-parallel, rerender-derived-state-no-effect Consultas independientes, cálculo derivado sin efectos y caché remota única

Las otras nueve skills están inventariadas, no se declara su aplicación. Faltan las skills auditoras ux-*-audit que referencia el orquestador y su política docs/orchestration-policy.md; la revisión es manual apoyada en las guías disponibles, sin auditor especializado de accesibilidad. No se instaló nada. DESIGN.md gobierna color, tipografía y espaciado; no se diseña otra identidad.

Normativa consultada: AGENTS.md, DESIGN.md, docs/skills-frontend-ui-ux.md, capas/composición de servidor, estructura web, rutas del cliente, componentes de interfaz, patrones de listados/diálogos, procedimiento Playwright y funcionalidades archivadas. Las referencias enlazadas en los demás documentos distinguen norma e implementación.

Referencias de evidencia

El catálogo de fuentes con enlaces a símbolos y líneas figura a continuación. Las referencias E se utilizan en los ocho entregables; las líneas corresponden al árbol auditado y pueden cambiar con ediciones posteriores.

Evidencia Archivo y símbolo / línea
E01 modules/assets/src/api/domain/workstation-values.ts:3 — WorkstationInputSchema
E01 modules/assets/src/common/workstations.ts:19 — WorkstationSchema
E02 modules/assets/src/api/domain/value-objects/workstation-values.vo.ts:20 — static create
E03 modules/assets/src/api/domain/workstation.aggregate.ts:56 — decommission(
E04 modules/assets/src/api/application/workstation-input.mapper.ts:11 — mapWorkstationInput
E05 modules/assets/src/api/infrastructure/persistence/workstation.model.ts:18 — migrateWorkstations
E06 modules/assets/src/api/infrastructure/persistence/workstation-persistence.mapper.ts:79 — toPersistence(
E06 modules/assets/src/api/application/workstation-response.builder.ts:4 — export function
E07 modules/assets/src/api/infrastructure/persistence/workstation-relational.ts:66 — readWorkstations
E07 modules/assets/src/api/infrastructure/persistence/remove-shared-workstation-assets.ts:4 — removeSharedWorkstationAssets
E07 modules/assets/src/api/infrastructure/persistence/load-workstations.ts:10 — loadWorkstations
E08 modules/companies/src/web/workstations/detail/ui/workstation-detail-page.tsx:19 — export function
E08 modules/companies/src/web/workstations/detail/controllers/use-workstation-detail-controller.ts:9 — export function
E09 modules/companies/src/web/workstations/detail/helpers/workstation-relations.ts:6 — export function
E10 modules/companies/src/web/workstations/detail/helpers/person-workstations.ts:5 — export function
E11 modules/companies/src/web/workstations/detail/ui/workstation-assets.tsx:10 — export function
E12 modules/companies/src/web/workstations/detail/ui/workstation-profiles.tsx:12 — export function
E12 modules/companies/src/web/workstations/detail/ui/workstation-people.tsx:9 — export function
E13 modules/companies/src/common/dto/shared/company.dto.ts:47 — CompanySchema
E13 modules/companies/src/common/dto/shared/people.dto.ts:55 — DepartmentAssignmentSchema
E14 modules/assets/src/api/domain/asset-values.ts:19 — AssetInputSchema
E14 modules/assets/src/common/inventory.ts:33 — AssetSchema
E14 modules/assets/src/api/domain/asset-state.ts:7 — assetDisplayStatus
E15 modules/companies/src/api/domain/work-profile-values.ts:3 — WorkProfileInputSchema
E15 modules/companies/src/api/application/work-profile-input.mapper.ts:10 — profileReferencesAvailable
E15 modules/companies/src/api/application/work-profile-response.builder.ts:7 — buildWorkProfileResponse
E15 modules/companies/src/api/infrastructure/persistence/work-profile-migration.ts:6 — migrateWorkProfiles
E15 modules/companies/src/api/infrastructure/persistence/sequelize-work-profile.repository.ts:17 — class SequelizeWorkProfileRepository
E16 modules/companies/src/api/domain/access/access-definition.ts:103 — AccessDefinitionSchema
E16 modules/companies/src/api/domain/access/access-workspace.aggregate.ts:25 — class AccessWorkspace
E16 modules/companies/src/api/infrastructure/persistence/access-persistence.ts:70 — migrateAccess
E17 modules/companies/src/api/domain/folder-mapping-values.ts:5 — FolderMappingInputSchema
E17 modules/companies/src/common/folder-mappings.ts:16 — FolderMappingSchema
E18 modules/companies/src/api/application/folder-mapping-policy.ts:39 — folderAvailable
E18 modules/companies/src/api/application/folder-mapping-account-policy.ts:50 — folderAccountCoverage
E18 modules/companies/src/api/domain/access/access-policy.ts:165 — checkCoverage
E18 modules/companies/src/api/domain/access/access-projection.ts:302 — projectAccess
E19 modules/resources/src/api/domain/resource-values.ts:21 — ResourceIntegrationSchema
E19 modules/resources/src/common/inventory.ts:35 — ResourceSchema
E19 modules/companies/src/api/infrastructure/persistence/resource-access-writer.ts:85 — async project
E20 modules/assets/src/common/network-share-publications.ts:10 — NETWORK_SHARE_PUBLICATION_DEFINITION
E20 modules/assets/src/api/infrastructure/persistence/network-share-publication-migration.ts:4 — CREATE TABLE
E20 modules/assets/src/api/infrastructure/http/network-share-publication.routes.ts:24 — registerNetworkSharePublicationRoutes
E21 modules/companies/src/api/infrastructure/persistence/configuration-snapshots.ts:12 — profileSnapshot
E21 modules/companies/src/api/infrastructure/persistence/mail-remote-snapshots.ts:42 — mailSnapshot
E21 modules/companies/src/api/domain/application-configuration-values.ts:5 — ApplicationConfigurationInputSchema
E21 modules/companies/src/api/domain/printer-configuration-values.ts:5 — PrinterConfigurationInputSchema
E21 modules/companies/src/api/domain/certificate-configuration-values.ts:5 — CertificateConfigurationInputSchema
E22 modules/companies/src/api/domain/remote-connection-values.ts:5 — RemoteConnectionInputSchema
E22 modules/companies/src/api/application/remote-connection-policy.ts:31 — remoteNeedsReview
E23 modules/companies/src/api/domain/telework-authorization-values.ts:3 — TeleworkAuthorizationInputSchema
E23 modules/companies/src/api/application/telework-authorization-policy.ts:6 — teleworkAuthorizationState
E24 modules/assets/src/common/support.ts:15 — SupportConnectionSchema
E24 modules/assets/src/api/domain/support-values.ts:3 — SupportValuesSchema
E24 modules/assets/src/api/infrastructure/http/support.routes.ts:18 — registerSupportRoutes
E25 modules/companies/src/common/local-identity-environments.ts:18 — LocalIdentityEnvironmentSchema
E25 modules/companies/src/api/infrastructure/persistence/local-identity-migration.ts:6 — CREATE TABLE
E26 modules/assets/src/common/directory-memberships.ts:54 — DirectoryMembershipSchema
E26 modules/assets/src/api/infrastructure/http/directory-membership.routes.ts:21 — registerDirectoryMembershipRoutes
E27 modules/companies/src/api/domain/process-values.ts:27 — ProcessReferenceSchema
E27 modules/companies/src/api/infrastructure/http/process.routes.ts:27 — registerProcessRoutes
E27 docs/funcionalidades-archivadas.md:28 — ## Aplicación activa
E27 modules/companies/src/api/infrastructure/persistence/remove-archived-support-tables.ts:5 — const
E28 modules/companies/src/web/workstations/detail/ui/workstation-detail-content.tsx:17 — export function
E28 modules/companies/src/web/software-installations/list/ui/software-installations-panel.tsx:26 — export function
E29 modules/assets/src/web/workstations/history/ui/workstation-history.tsx:15 — export function
E30 modules/companies/src/web/work-environments/detail/hooks/use-environment-queries.ts:20 — export function
E30 modules/companies/src/web/work-environments/shared/helpers/work-environment.model.ts:60 — export function buildEnvironment
E30 modules/companies/src/web/work-environments/detail/ui/environment-content.tsx:19 — export function
E31 packages/rdx-ui/src/components/detail-panel.tsx:6 — export function
E31 packages/rdx-ui/src/components/detail-field.tsx:4 — export function
E31 packages/rdx-ui/src/components/statistic-card.tsx:19 — export function
E32 apps/web/components.json:3 — base-vega
E32 packages/rdx-ui/src/components/entity-list.tsx:17 — export
E32 packages/shadcn-ui/src/components/tabs.tsx:7 — function Tabs
E32 packages/shadcn-ui/src/components/button.tsx:42 — function Button
E33 modules/identity/src/api/infrastructure/http/require-authenticated.ts:6 — export function
E33 modules/assets/src/api/infrastructure/http/workstation.routes.ts:16 — registerWorkstationRoutes
E33 modules/assets/src/api/infrastructure/persistence/sequelize-asset.repository.ts:157 — saveWorkstation(
E34 apps/server/src/infrastructure/http/relationship-read-access.ts:7 — class SessionRelationshipReadAccess
E35 modules/assets/src/api/domain/infrastructure-values.ts:33 — InfrastructureInputSchema
E35 modules/assets/src/api/infrastructure/persistence/infrastructure-migration.ts:4 — migrateInfrastructure
E35 modules/assets/src/api/infrastructure/persistence/sequelize-infrastructure.repository.ts:21 — class SequelizeInfrastructureRepository
E36 modules/companies/src/common/mailboxes.ts:34 — MailboxesResponseSchema
E36 modules/companies/src/api/application/mail-configuration-policy.ts:5 — mailAuthorized
E36 modules/companies/src/api/infrastructure/persistence/mailbox-migration.ts:6 — migrateMailboxes
E37 apps/server/src/infrastructure/http/identity-runtime.ts:17 — createIdentityRuntime
E37 modules/assets/src/api/module.ts:67 — createAssetModule
E37 modules/companies/src/api/module.ts:99 — createCompanyModule