Files
qwen3-6-lora/data/raw/sanitized/plans/quiero-que-comencemos-a-mighty-quill.md
T

5.3 KiB

Etapa 2 — Backend: Company y Office CRUD

Contexto

Ro-ut v2.1.5 tiene la arquitectura completa (SSR React + GraphQL embebido + PostgreSQL) pero solo implementa autenticación y un CRUD básico de usuarios. El schema SQL ya incluye las tablas Company y Office con todos los campos planeados (Etapa 1 completada). La Etapa 2 expone estas entidades vía GraphQL siguiendo el mismo patrón 4-archivos que User: model → controller → schema → resolver.

Patrón a seguir (basado en User)

Cada entidad necesita 4 archivos nuevos + actualización de 3 archivos de registro:

Capa Patrón User Company Office
Model dataUsuario.ts dataCompany.ts dataOffice.ts
Controller dataUsuario.ts dataCompany.ts dataOffice.ts
Schema user.schema.ts company.schema.ts office.schema.ts
Resolver user.resolver.ts company.resolver.ts office.resolver.ts

Archivos a crear

1. Model — src/server/models/apiPostgresModel/dataCompany.ts

  • getCompany(id) → SELECT por Id
  • getCompanies() → SELECT sin filtro
  • insertCompany(company) → INSERT RETURNING Id
  • editCompany(id, company) → UPDATE
  • deleteCompany(id) → DELETE

2. Model — src/server/models/apiPostgresModel/dataOffice.ts

  • getOffice(id) → SELECT por Id
  • getOffices() → SELECT sin filtro
  • getOfficesByCompany(companyId) → SELECT por FK_Company
  • insertOffice(office) → INSERT RETURNING Id
  • editOffice(id, office) → UPDATE
  • deleteOffice(id) → DELETE

3. Controller — src/server/controllers/controllerGraphQL/dataCompany.ts

  • Mapea model results: Idid (string)
  • Exporta: getCompany, getCompanies, insertCompany, editCompany, deleteCompany

4. Controller — src/server/controllers/controllerGraphQL/dataOffice.ts

  • Mapea model results: Idid (string)
  • Exporta: getOffice, getOffices, getOfficesByCompany, insertOffice, editOffice, deleteOffice

5. Schema — src/server/GraphQL/schema/company.schema.ts

  • @ObjectType('Company') — campos: id, name, businessName, type, country, phone
  • @InputType('InputCompany') — campos editables: name, businessName, type, country, phone
  • @ObjectType('CompaniesQuery') — fields: company(id), companies()
  • @ObjectType('CompanyMutation') — mutations: insertCompany, editCompany, deleteCompany
  • Cada field/mutation llama al controller correspondiente

6. Schema — src/server/GraphQL/schema/office.schema.ts

  • @ObjectType('Office') — campos: id, name, address, email, city, country, lat, lng, company (FK)
  • @InputType('InputOffice') — campos editables
  • @ObjectType('OfficesQuery') — fields: office(id), offices(), officesByCompany(companyId)
  • @ObjectType('OfficeMutation') — mutations: insertOffice, editOffice, deleteOffice

7. Resolver — src/server/GraphQL/resolvers/company.resolver.ts

  • @Resolver(() => CompanyMutation) — query companyMutation() → CompanyMutation
  • @Resolver(() => CompaniesQuery) — query companiesQuery() → CompaniesQuery

8. Resolver — src/server/GraphQL/resolvers/office.resolver.ts

  • @Resolver(() => OfficeMutation) — query officeMutation() → OfficeMutation
  • @Resolver(() => OfficesQuery) — query officesQuery() → OfficesQuery

9. Tests — src/server/tests/server/company/index.test.ts

  • Tests supertest para: insert, get, list, edit, delete (patrón exacto de user/index.test.ts)

10. Tests — src/server/tests/server/office/index.test.ts

  • Tests supertest para: insert, get, list, getByCompany, edit, delete

Archivos a modificar

1. src/server/models/apiPostgresModel/index.ts

export * from './dataLogIn';
export * from './dataUsuario';
export * from './dataCompany';
export * from './dataOffice';

2. src/server/controllers/controllerGraphQL/index.ts

export * from './dataUsuario';
export * from './dataLogin';
export * from './dataCompany';
export * from './dataOffice';

3. src/server/GraphQL/schema/index.ts

  • Import Company/InputCompany/CompaniesQuery/CompanyMutation de company.schema.ts
  • Import Office/InputOffice/OfficesQuery/OfficeMutation de office.schema.ts
  • Asegurar que se exporten (type-graphql necesita los imports para registrar los decoradores)

4. src/server/GraphQL/resolvers/index.ts

  • Import y export CompanyMutationResolver, CompaniesQueryResolver (o como se llamen)
  • Import y export OfficeMutationResolver, OfficesQueryResolver

5. src/server/GraphQL/server.ts

  • Agregar los 4 resolvers a buildSchemaSync({ resolvers: [...] })

Ejecución

Este plan será ejecutado por un agente en background usando la skill global background-orchestrator. El agente se encarga de:

  • Crear los 10 archivos nuevos siguiendo el patrón exacto de User
  • Modificar los 5 archivos de registro
  • Verificar con npm run lint, npm run build y npm run test:backend
  • Crear el PR correspondiente en Gitea

Verificación

  1. npm run lint — sin errores
  2. npm run build — compila sin errores (type-graphql registra todos los decoradores)
  3. npm run test:backend — tests de integración verdes (requiere PostgreSQL con schema completo)
  4. npm run test:frontend — tests frontend sin cambios