115 lines
5.3 KiB
Markdown
115 lines
5.3 KiB
Markdown
# 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
|