# 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: `Id` → `id` (string)
- Exporta: `getCompany`, `getCompanies`, `insertCompany`, `editCompany`, `deleteCompany`

### 4. Controller — `src/server/controllers/controllerGraphQL/dataOffice.ts`
- Mapea model results: `Id` → `id` (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`
```ts
export * from './dataLogIn';
export * from './dataUsuario';
export * from './dataCompany';
export * from './dataOffice';
```

### 2. `src/server/controllers/controllerGraphQL/index.ts`
```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
