Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
948 lines
22 KiB
YAML
948 lines
22 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: ERP Construccion API
|
|
description: |
|
|
API REST para sistema de administracion de obra e INFONAVIT.
|
|
|
|
## Autenticacion
|
|
|
|
La API utiliza JWT Bearer tokens. Incluir el header:
|
|
```
|
|
Authorization: Bearer <access_token>
|
|
```
|
|
|
|
## Multi-tenancy
|
|
|
|
Todas las operaciones estan aisladas por tenant_id.
|
|
El tenant se determina automaticamente desde el JWT.
|
|
|
|
## Paginacion
|
|
|
|
Los endpoints de listado soportan paginacion:
|
|
- `page`: Numero de pagina (default: 1)
|
|
- `limit`: Items por pagina (default: 20, max: 100)
|
|
|
|
version: 1.0.0
|
|
contact:
|
|
name: ERP Construccion Team
|
|
email: dev@construccion.local
|
|
|
|
servers:
|
|
- url: http://localhost:3000/api/v1
|
|
description: Development
|
|
- url: https://api.construccion.example.com/api/v1
|
|
description: Production
|
|
|
|
tags:
|
|
- name: Auth
|
|
description: Autenticacion y autorizacion
|
|
- name: Conceptos
|
|
description: Catalogo de conceptos de obra
|
|
- name: Presupuestos
|
|
description: Presupuestos de obra
|
|
- name: Avances
|
|
description: Control de avances fisicos
|
|
- name: Bitacora
|
|
description: Bitacora de obra
|
|
- name: Estimaciones
|
|
description: Estimaciones periodicas
|
|
|
|
paths:
|
|
/auth/login:
|
|
post:
|
|
tags: [Auth]
|
|
summary: Login de usuario
|
|
operationId: login
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LoginRequest'
|
|
responses:
|
|
'200':
|
|
description: Login exitoso
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AuthResponse'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
/auth/register:
|
|
post:
|
|
tags: [Auth]
|
|
summary: Registro de usuario
|
|
operationId: register
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RegisterRequest'
|
|
responses:
|
|
'201':
|
|
description: Usuario registrado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AuthResponse'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/auth/refresh:
|
|
post:
|
|
tags: [Auth]
|
|
summary: Renovar access token
|
|
operationId: refreshToken
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RefreshTokenRequest'
|
|
responses:
|
|
'200':
|
|
description: Tokens renovados
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AuthResponse'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
|
|
/auth/logout:
|
|
post:
|
|
tags: [Auth]
|
|
summary: Logout (revocar refresh token)
|
|
operationId: logout
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RefreshTokenRequest'
|
|
responses:
|
|
'204':
|
|
description: Logout exitoso
|
|
|
|
/conceptos:
|
|
get:
|
|
tags: [Conceptos]
|
|
summary: Listar conceptos
|
|
operationId: listConceptos
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/PageParam'
|
|
- $ref: '#/components/parameters/LimitParam'
|
|
responses:
|
|
'200':
|
|
description: Lista de conceptos
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ConceptoListResponse'
|
|
post:
|
|
tags: [Conceptos]
|
|
summary: Crear concepto
|
|
operationId: createConcepto
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateConceptoRequest'
|
|
responses:
|
|
'201':
|
|
description: Concepto creado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Concepto'
|
|
|
|
/conceptos/tree:
|
|
get:
|
|
tags: [Conceptos]
|
|
summary: Obtener arbol de conceptos
|
|
operationId: getConceptoTree
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: rootId
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: ID del concepto raiz (opcional)
|
|
responses:
|
|
'200':
|
|
description: Arbol de conceptos
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ConceptoTree'
|
|
|
|
/conceptos/{id}:
|
|
get:
|
|
tags: [Conceptos]
|
|
summary: Obtener concepto por ID
|
|
operationId: getConcepto
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
responses:
|
|
'200':
|
|
description: Concepto encontrado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Concepto'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/presupuestos:
|
|
get:
|
|
tags: [Presupuestos]
|
|
summary: Listar presupuestos
|
|
operationId: listPresupuestos
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/PageParam'
|
|
- $ref: '#/components/parameters/LimitParam'
|
|
- name: fraccionamientoId
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
responses:
|
|
'200':
|
|
description: Lista de presupuestos
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PresupuestoListResponse'
|
|
post:
|
|
tags: [Presupuestos]
|
|
summary: Crear presupuesto
|
|
operationId: createPresupuesto
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreatePresupuestoRequest'
|
|
responses:
|
|
'201':
|
|
description: Presupuesto creado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Presupuesto'
|
|
|
|
/presupuestos/{id}:
|
|
get:
|
|
tags: [Presupuestos]
|
|
summary: Obtener presupuesto con partidas
|
|
operationId: getPresupuesto
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
responses:
|
|
'200':
|
|
description: Presupuesto con partidas
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PresupuestoDetalle'
|
|
|
|
/presupuestos/{id}/partidas:
|
|
post:
|
|
tags: [Presupuestos]
|
|
summary: Agregar partida al presupuesto
|
|
operationId: addPartida
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AddPartidaRequest'
|
|
responses:
|
|
'201':
|
|
description: Partida agregada
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PresupuestoPartida'
|
|
|
|
/presupuestos/{id}/approve:
|
|
post:
|
|
tags: [Presupuestos]
|
|
summary: Aprobar presupuesto
|
|
operationId: approvePresupuesto
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
responses:
|
|
'200':
|
|
description: Presupuesto aprobado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Presupuesto'
|
|
|
|
/avances:
|
|
get:
|
|
tags: [Avances]
|
|
summary: Listar avances
|
|
operationId: listAvances
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/PageParam'
|
|
- $ref: '#/components/parameters/LimitParam'
|
|
- name: loteId
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
$ref: '#/components/schemas/AdvanceStatus'
|
|
responses:
|
|
'200':
|
|
description: Lista de avances
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AvanceListResponse'
|
|
post:
|
|
tags: [Avances]
|
|
summary: Crear avance
|
|
operationId: createAvance
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateAvanceRequest'
|
|
responses:
|
|
'201':
|
|
description: Avance creado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AvanceObra'
|
|
|
|
/avances/{id}/fotos:
|
|
post:
|
|
tags: [Avances]
|
|
summary: Agregar foto al avance
|
|
operationId: addFotoAvance
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AddFotoRequest'
|
|
responses:
|
|
'201':
|
|
description: Foto agregada
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/FotoAvance'
|
|
|
|
/avances/{id}/approve:
|
|
post:
|
|
tags: [Avances]
|
|
summary: Aprobar avance
|
|
operationId: approveAvance
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
responses:
|
|
'200':
|
|
description: Avance aprobado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AvanceObra'
|
|
|
|
/estimaciones:
|
|
get:
|
|
tags: [Estimaciones]
|
|
summary: Listar estimaciones
|
|
operationId: listEstimaciones
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/PageParam'
|
|
- $ref: '#/components/parameters/LimitParam'
|
|
- name: contratoId
|
|
in: query
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
$ref: '#/components/schemas/EstimateStatus'
|
|
responses:
|
|
'200':
|
|
description: Lista de estimaciones
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EstimacionListResponse'
|
|
post:
|
|
tags: [Estimaciones]
|
|
summary: Crear estimacion
|
|
operationId: createEstimacion
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateEstimacionRequest'
|
|
responses:
|
|
'201':
|
|
description: Estimacion creada
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Estimacion'
|
|
|
|
/estimaciones/{id}/submit:
|
|
post:
|
|
tags: [Estimaciones]
|
|
summary: Enviar estimacion para revision
|
|
operationId: submitEstimacion
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
responses:
|
|
'200':
|
|
description: Estimacion enviada
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Estimacion'
|
|
|
|
/estimaciones/{id}/approve:
|
|
post:
|
|
tags: [Estimaciones]
|
|
summary: Aprobar estimacion
|
|
operationId: approveEstimacion
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/IdParam'
|
|
responses:
|
|
'200':
|
|
description: Estimacion aprobada
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Estimacion'
|
|
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
|
|
parameters:
|
|
IdParam:
|
|
name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
PageParam:
|
|
name: page
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
default: 1
|
|
LimitParam:
|
|
name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 20
|
|
|
|
responses:
|
|
BadRequest:
|
|
description: Solicitud invalida
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
Unauthorized:
|
|
description: No autorizado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
NotFound:
|
|
description: Recurso no encontrado
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
|
|
schemas:
|
|
Error:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
message:
|
|
type: string
|
|
|
|
PaginationMeta:
|
|
type: object
|
|
properties:
|
|
total:
|
|
type: integer
|
|
page:
|
|
type: integer
|
|
limit:
|
|
type: integer
|
|
totalPages:
|
|
type: integer
|
|
|
|
LoginRequest:
|
|
type: object
|
|
required: [email, password]
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
password:
|
|
type: string
|
|
minLength: 8
|
|
tenantId:
|
|
type: string
|
|
format: uuid
|
|
|
|
RegisterRequest:
|
|
type: object
|
|
required: [email, password, firstName, lastName, tenantId]
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
password:
|
|
type: string
|
|
minLength: 8
|
|
firstName:
|
|
type: string
|
|
lastName:
|
|
type: string
|
|
tenantId:
|
|
type: string
|
|
format: uuid
|
|
|
|
RefreshTokenRequest:
|
|
type: object
|
|
required: [refreshToken]
|
|
properties:
|
|
refreshToken:
|
|
type: string
|
|
|
|
AuthResponse:
|
|
type: object
|
|
properties:
|
|
accessToken:
|
|
type: string
|
|
refreshToken:
|
|
type: string
|
|
expiresIn:
|
|
type: integer
|
|
user:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
email:
|
|
type: string
|
|
firstName:
|
|
type: string
|
|
lastName:
|
|
type: string
|
|
roles:
|
|
type: array
|
|
items:
|
|
type: string
|
|
tenant:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
name:
|
|
type: string
|
|
|
|
Concepto:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
code:
|
|
type: string
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
parentId:
|
|
type: string
|
|
format: uuid
|
|
level:
|
|
type: integer
|
|
path:
|
|
type: string
|
|
unitPrice:
|
|
type: number
|
|
isComposite:
|
|
type: boolean
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
ConceptoTree:
|
|
allOf:
|
|
- $ref: '#/components/schemas/Concepto'
|
|
- type: object
|
|
properties:
|
|
children:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ConceptoTree'
|
|
|
|
CreateConceptoRequest:
|
|
type: object
|
|
required: [code, name]
|
|
properties:
|
|
code:
|
|
type: string
|
|
maxLength: 50
|
|
name:
|
|
type: string
|
|
maxLength: 255
|
|
description:
|
|
type: string
|
|
parentId:
|
|
type: string
|
|
format: uuid
|
|
unitPrice:
|
|
type: number
|
|
isComposite:
|
|
type: boolean
|
|
|
|
ConceptoListResponse:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Concepto'
|
|
meta:
|
|
$ref: '#/components/schemas/PaginationMeta'
|
|
|
|
Presupuesto:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
code:
|
|
type: string
|
|
name:
|
|
type: string
|
|
version:
|
|
type: integer
|
|
isActive:
|
|
type: boolean
|
|
totalAmount:
|
|
type: number
|
|
approvedAt:
|
|
type: string
|
|
format: date-time
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
PresupuestoPartida:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
conceptoId:
|
|
type: string
|
|
format: uuid
|
|
quantity:
|
|
type: number
|
|
unitPrice:
|
|
type: number
|
|
totalAmount:
|
|
type: number
|
|
sequence:
|
|
type: integer
|
|
|
|
PresupuestoDetalle:
|
|
allOf:
|
|
- $ref: '#/components/schemas/Presupuesto'
|
|
- type: object
|
|
properties:
|
|
partidas:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/PresupuestoPartida'
|
|
|
|
CreatePresupuestoRequest:
|
|
type: object
|
|
required: [code, name]
|
|
properties:
|
|
code:
|
|
type: string
|
|
name:
|
|
type: string
|
|
description:
|
|
type: string
|
|
fraccionamientoId:
|
|
type: string
|
|
format: uuid
|
|
prototipoId:
|
|
type: string
|
|
format: uuid
|
|
|
|
AddPartidaRequest:
|
|
type: object
|
|
required: [conceptoId, quantity, unitPrice]
|
|
properties:
|
|
conceptoId:
|
|
type: string
|
|
format: uuid
|
|
quantity:
|
|
type: number
|
|
unitPrice:
|
|
type: number
|
|
sequence:
|
|
type: integer
|
|
|
|
PresupuestoListResponse:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Presupuesto'
|
|
meta:
|
|
$ref: '#/components/schemas/PaginationMeta'
|
|
|
|
AdvanceStatus:
|
|
type: string
|
|
enum: [pending, captured, reviewed, approved, rejected]
|
|
|
|
AvanceObra:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
loteId:
|
|
type: string
|
|
format: uuid
|
|
conceptoId:
|
|
type: string
|
|
format: uuid
|
|
captureDate:
|
|
type: string
|
|
format: date
|
|
quantityExecuted:
|
|
type: number
|
|
percentageExecuted:
|
|
type: number
|
|
status:
|
|
$ref: '#/components/schemas/AdvanceStatus'
|
|
notes:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
FotoAvance:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
fileUrl:
|
|
type: string
|
|
fileName:
|
|
type: string
|
|
description:
|
|
type: string
|
|
capturedAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
CreateAvanceRequest:
|
|
type: object
|
|
required: [conceptoId, captureDate, quantityExecuted]
|
|
properties:
|
|
loteId:
|
|
type: string
|
|
format: uuid
|
|
departamentoId:
|
|
type: string
|
|
format: uuid
|
|
conceptoId:
|
|
type: string
|
|
format: uuid
|
|
captureDate:
|
|
type: string
|
|
format: date
|
|
quantityExecuted:
|
|
type: number
|
|
percentageExecuted:
|
|
type: number
|
|
notes:
|
|
type: string
|
|
|
|
AddFotoRequest:
|
|
type: object
|
|
required: [fileUrl]
|
|
properties:
|
|
fileUrl:
|
|
type: string
|
|
fileName:
|
|
type: string
|
|
description:
|
|
type: string
|
|
location:
|
|
type: object
|
|
properties:
|
|
lat:
|
|
type: number
|
|
lng:
|
|
type: number
|
|
|
|
AvanceListResponse:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AvanceObra'
|
|
meta:
|
|
$ref: '#/components/schemas/PaginationMeta'
|
|
|
|
EstimateStatus:
|
|
type: string
|
|
enum: [draft, submitted, reviewed, approved, invoiced, paid, rejected, cancelled]
|
|
|
|
Estimacion:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
estimateNumber:
|
|
type: string
|
|
contratoId:
|
|
type: string
|
|
format: uuid
|
|
periodStart:
|
|
type: string
|
|
format: date
|
|
periodEnd:
|
|
type: string
|
|
format: date
|
|
sequenceNumber:
|
|
type: integer
|
|
status:
|
|
$ref: '#/components/schemas/EstimateStatus'
|
|
subtotal:
|
|
type: number
|
|
advanceAmount:
|
|
type: number
|
|
retentionAmount:
|
|
type: number
|
|
taxAmount:
|
|
type: number
|
|
totalAmount:
|
|
type: number
|
|
approvedAt:
|
|
type: string
|
|
format: date-time
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
|
|
CreateEstimacionRequest:
|
|
type: object
|
|
required: [contratoId, fraccionamientoId, periodStart, periodEnd]
|
|
properties:
|
|
contratoId:
|
|
type: string
|
|
format: uuid
|
|
fraccionamientoId:
|
|
type: string
|
|
format: uuid
|
|
periodStart:
|
|
type: string
|
|
format: date
|
|
periodEnd:
|
|
type: string
|
|
format: date
|
|
notes:
|
|
type: string
|
|
|
|
EstimacionListResponse:
|
|
type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Estimacion'
|
|
meta:
|
|
$ref: '#/components/schemas/PaginationMeta'
|