@urbiport/core-contract
v1.0.0-alpha.1
Published
[](https://github.com/quickbot-io/core-contract) [](https://www.typescriptlang.org/) [ de request/response
- Esquemas de validación con Zod
- Definiciones de API consistentes
✨ Características Principales
- 🏗️ Contratos Tipados: Interfaces TypeScript para todas las operaciones
- 🔄 Compatibilidad Total: Integración perfecta con
@quickbot.io/core - 📝 Documentación JSDoc: Documentación completa en cada contrato
- 🎯 Type Safety: Tipado fuerte para prevenir errores
- 🧪 Validación Zod: Esquemas de validación integrados
- 📦 Modular: Exportaciones específicas por módulo
- 🔒 Versionado Semántico: Control de cambios breaking
🏗️ Arquitectura
Patrón de Contratos
El proyecto sigue el patrón Contract-First Design donde:
┌─────────────────────────────────────────────┐
│ Client Applications │
├─────────────────────────────────────────────┤
│ @quickbot.io/core-contract │ ← Contratos
├─────────────────────────────────────────────┤
│ @quickbot.io/core │ ← Implementación
├─────────────────────────────────────────────┤
│ Database │
└─────────────────────────────────────────────┘Estructura de Contratos
Cada contrato sigue esta estructura estándar:
/**
* [Module] contract
* @description Descripción del contrato
* @author Quickbot.io
* @version 1.0.0
* @since 2025-06-29
*/
export interface I[Module]Contract {
/**
* Método del contrato
* @param request - Objeto de request
* @returns Promise con response tipado
*/
methodName(request: Request): Promise<Response>;
}
export type { IModuleRequest, IModuleResponse };Principios de Diseño
- Inmutabilidad: Los contratos no cambian sin versionado
- Composición: Reutilización de tipos entre contratos
- Claridad: Documentación JSDoc detallada
- Consistencia: Patrones uniformes en todos los módulos
📦 Instalación
Prerrequisitos
- Node.js >= 22.0.0
- TypeScript >= 5.7.0
- @quickbot.io/core (peer dependency)
Instalación del Paquete
# Con npm
npm install @quickbot.io/core-contract
# Con bun (recomendado)
bun add @quickbot.io/core-contract
# Con yarn
yarn add @quickbot.io/core-contractConfiguración TypeScript
Asegúrate de tener estas configuraciones en tu tsconfig.json:
{
"compilerOptions": {
"strict": true,
"declaration": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}📁 Estructura del Proyecto
contract/
├── src/ # Código fuente
│ ├── auth/ # Contratos de autenticación
│ │ ├── auth.contract.ts # Contrato principal de auth
│ │ └── apitoken.auth.contract.ts # Contrato de API tokens
│ ├── users/ # Contratos de usuarios
│ │ ├── user.contract.ts # Contrato de usuarios
│ │ └── profile.contract.ts # Contrato de perfiles
│ ├── workspaces/ # Contratos de workspaces
│ │ ├── workspaces.contract.ts # Contrato principal
│ │ ├── member.workspaces.contract.ts # Gestión de miembros
│ │ ├── billing.workspaces.contract.ts # Facturación
│ │ ├── invitation.workspaces.contract.ts # Invitaciones
│ │ ├── domain.workspaces.contract.ts # Dominios
│ │ └── settings.workspaces.contract.ts # Configuración
│ ├── core/ # Tipos compartidos
│ │ └── index.ts # Exportaciones core
│ └── index.ts # Exportaciones principales
├── dist/ # Código compilado
├── package.json # Configuración del paquete
├── tsconfig.json # Configuración TypeScript
├── biome.json # Configuración Biome
└── README.md # Documentación🔌 Contratos Disponibles
🔐 Módulo Auth
IAuthContract
Operaciones principales de autenticación:
import { IAuthContract } from '@quickbot.io/core-contract';
interface IAuthContract {
login(request: IAuthRequest.ILoginDTO): Promise<IAuthResponse.ITokenDTO>;
logout(request: IAuthRequest.ILogoutDTO): Promise<IAuthResponse.ILogoutDTO>;
register(request: IAuthRequest.IRegisterDTO): Promise<IAuthResponse.ITokenDTO>;
}IApiTokenAuthContract
Gestión de tokens de API:
import { IApiTokenAuthContract } from '@quickbot.io/core-contract';
interface IApiTokenAuthContract {
create(request: IApiTokenRequest.ICreateDTO): Promise<IApiTokenResponse.ITokenDTO>;
findAll(request: IApiTokenRequest.IFindAllDTO): Promise<IPaginationResponse<IApiTokenResponse.ITokenDTO>>;
delete(request: IApiTokenRequest.IDeleteDTO): Promise<IApiTokenResponse.IDeleteDTO>;
// ... más métodos
}👥 Módulo Users
IUserContract
Gestión completa de usuarios:
import { IUserContract } from '@quickbot.io/core-contract';
interface IUserContract {
findById(request: IUserRequest.IFindByIdDTO): Promise<IUserResponse.IUserDTO>;
findAll(request: IUserRequest.IFindAllDTO): Promise<IPaginationResponse<IUserResponse.IUserDTO>>;
update(request: IUserRequest.IUpdateDTO): Promise<IUserResponse.IUserDTO>;
delete(request: IUserRequest.IDeleteDTO): Promise<IUserResponse.IDeleteDTO>;
}IProfileContract
Gestión de perfiles de usuario:
import { IProfileContract } from '@quickbot.io/core-contract';
interface IProfileContract {
getProfile(request: IProfileRequest.IGetDTO): Promise<IProfileResponse.IProfileDTO>;
updateProfile(request: IProfileRequest.IUpdateDTO): Promise<IProfileResponse.IProfileDTO>;
uploadAvatar(request: IProfileRequest.IUploadAvatarDTO): Promise<IProfileResponse.IAvatarDTO>;
}🏢 Módulo Workspaces
IWorkspacesContract
Gestión principal de workspaces:
import { IWorkspacesContract } from '@quickbot.io/core-contract';
interface IWorkspacesContract {
create(request: IWorkspacesRequest.ICreateDTO): Promise<IWorkspacesResponse.IWorkspaceDTO>;
findAll(request: IWorkspacesRequest.IFindAllDTO): Promise<IPaginationResponse<IWorkspacesResponse.IWorkspaceDTO>>;
findById(request: IWorkspacesRequest.IFindByIdDTO): Promise<IWorkspacesResponse.IWorkspaceDTO>;
update(request: IWorkspacesRequest.IUpdateDTO): Promise<IWorkspacesResponse.IWorkspaceDTO>;
delete(request: IWorkspacesRequest.IDeleteDTO): Promise<IWorkspacesResponse.IDeleteDTO>;
}Otros contratos de Workspaces:
IMemberWorkspacesContract: Gestión de miembrosIBillingWorkspacesContract: Facturación y suscripcionesIInvitationWorkspacesContract: Sistema de invitacionesIDomainWorkspacesContract: Dominios personalizadosISettingsWorkspacesContract: Configuración del workspace
💻 Uso y Ejemplos
Importación Básica
// Importar todos los contratos
import * as Contracts from '@quickbot.io/core-contract';
// Importar contratos específicos
import {
IAuthContract,
IUserContract,
IWorkspacesContract
} from '@quickbot.io/core-contract';
// Importar tipos específicos
import type {
IAuthRequest,
IAuthResponse
} from '@quickbot.io/core-contract';Implementación de un Servicio
import { IUserContract, IUserRequest, IUserResponse } from '@quickbot.io/core-contract';
import { IPaginationResponse } from '@quickbot.io/core-contract';
class UserService implements IUserContract {
async findById(request: IUserRequest.IFindByIdDTO): Promise<IUserResponse.IUserDTO> {
// Implementación del método
return {
id: request.id,
name: "Usuario",
email: "[email protected]",
// ... otros campos
};
}
async findAll(
request: IUserRequest.IFindAllDTO
): Promise<IPaginationResponse<IUserResponse.IUserDTO>> {
// Implementación con paginación
return {
data: [/* usuarios */],
meta: {
total: 100,
page: request.page || 1,
limit: request.limit || 10,
totalPages: 10
}
};
}
// ... más implementaciones
}Cliente HTTP con Contratos
import { IAuthContract, IAuthRequest, IAuthResponse } from '@quickbot.io/core-contract';
class AuthClient implements IAuthContract {
private baseUrl: string;
constructor(baseUrl: string) {
this.baseUrl = baseUrl;
}
async login(request: IAuthRequest.ILoginDTO): Promise<IAuthResponse.ITokenDTO> {
const response = await fetch(`${this.baseUrl}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request)
});
if (!response.ok) {
throw new Error('Login failed');
}
return response.json();
}
async logout(request: IAuthRequest.ILogoutDTO): Promise<IAuthResponse.ILogoutDTO> {
// Implementación de logout
}
async register(request: IAuthRequest.IRegisterDTO): Promise<IAuthResponse.ITokenDTO> {
// Implementación de registro
}
}Validación con Zod
import { z } from 'zod';
import { IUserRequest } from '@quickbot.io/core-contract';
// Esquema de validación para crear usuario
const CreateUserSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
password: z.string().min(8)
}) satisfies z.ZodType<IUserRequest.ICreateDTO>;
// Uso en endpoint
async function createUser(data: unknown) {
const validatedData = CreateUserSchema.parse(data);
// validatedData es de tipo IUserRequest.ICreateDTO
return userService.create(validatedData);
}🛠️ Desarrollo
Scripts Disponibles
# Formateo y linting
npm run format # Formatear código con Biome
npm run lint # Linter con Biome
npm run check # Verificación completa
# Construcción
npm run build # Compilar TypeScriptConfiguración del Entorno
Variables de Path
El proyecto utiliza path aliases para imports limpios:
// Aliases disponibles en tsconfig.json
"@auth/*": ["src/auth/*"]
"@users/*": ["src/users/*"]
"@workspaces/*": ["src/workspaces/*"]
"@core/*": ["src/core/*"]Configuración de IDE
Para VS Code, recomendamos estas extensiones:
{
"recommendations": [
"biomejs.biome",
"ms-vscode.vscode-typescript-next"
]
}Estándares de Código
Estilo de Código
// ✅ Correcto: Usar interfaces para contratos
export interface IUserContract {
findById(request: IUserRequest.IFindByIdDTO): Promise<IUserResponse.IUserDTO>;
}
// ✅ Correcto: Documentación JSDoc completa
/**
* Find user by id
* @param request - Request object containing user id
* @returns Promise that resolves to user data
*/
findById(request: IUserRequest.IFindByIdDTO): Promise<IUserResponse.IUserDTO>;
// ✅ Correcto: Exportar tipos junto con contratos
export type { IUserRequest, IUserResponse };Convenciones de Nomenclatura
- Contratos:
I[Module]Contract - Requests:
I[Module]Request.I[Action]DTO - Responses:
I[Module]Response.I[Entity]DTO - Archivos:
[module].contract.ts
Agregar Nuevos Contratos
- Crear el archivo de contrato:
// src/nuevomodulo/nuevo.contract.ts
import type { INuevoRequest, INuevoResponse } from "@quickbot.io/core/nuevo";
/**
* Nuevo contract
* @description Descripción del nuevo contrato
* @author Quickbot.io
* @version 1.0.0
* @since 2025-01-01
*/
export interface INuevoContract {
/**
* Método ejemplo
* @param request - Request object
* @returns Promise con response
*/
metodoEjemplo(request: INuevoRequest.IEjemploDTO): Promise<INuevoResponse.IEjemploDTO>;
}
export type { INuevoRequest, INuevoResponse };- Exportar en index.ts:
// src/index.ts
export * from "@nuevomodulo/nuevo.contract";🚀 Construcción y Despliegue
Proceso de Build
# 1. Compilar TypeScript con tipos
npm run build
# 2. Verificar output
ls -la dist/Estructura del Build
dist/
├── auth/
│ ├── auth.contract.js
│ ├── auth.contract.d.ts
│ ├── apitoken.auth.contract.js
│ └── apitoken.auth.contract.d.ts
├── users/
│ ├── user.contract.js
│ ├── user.contract.d.ts
│ ├── profile.contract.js
│ └── profile.contract.d.ts
├── workspaces/
│ └── [archivos compilados]
├── core/
│ ├── index.js
│ └── index.d.ts
├── index.js
└── index.d.tsPublicación
# 1. Versionar siguiendo semver
npm version patch|minor|major
# 2. Construir
npm run build
# 3. Publicar (configurado como público)
npm publishCompatibilidad de Versiones
| Version | @quickbot.io/core | Breaking Changes | |---------|-------------------|------------------| | 1.0.0-alpha.1 | ^0.1.0-alpha.1 | N/A (inicial) |
🤝 Contribución
Guía de Contribución
- Crea una rama para tu feature (
git checkout -b feature/nuevo-contrato) - Commit tus cambios (
git commit -am 'feat(contracts): add new contract') - Push a la rama (
git push origin feature/nuevo-contrato) - Crea un Pull Request
Convenciones de Commit
Seguimos Conventional Commits:
type(scope): description
feat(auth): add OAuth2 contract
fix(users): resolve user contract types
docs(readme): update contract examples
refactor(workspaces): improve workspace contracts
test(contracts): add contract validation testsTipos de Commit Específicos
feat(contracts): Nuevos contratos o métodosfix(types): Corrección de tipos TypeScriptdocs(examples): Documentación y ejemplosrefactor(structure): Reorganización de contratosbreaking: Cambios que rompen compatibilidad
Revisión de Contratos
Antes de hacer merge, verifica:
- ✅ Documentación JSDoc completa
- ✅ Tipos exportados correctamente
- ✅ Compatibilidad con @quickbot.io/core
- ✅ Convenciones de nomenclatura
- ✅ Compilación sin errores
- ✅ Versionado semántico adecuado
Testing de Contratos
// Ejemplo de test de tipos
import { IUserContract, IUserRequest, IUserResponse } from '../src';
// Test de compilación TypeScript
const testUserContract = (contract: IUserContract) => {
// Este código debe compilar sin errores
const request: IUserRequest.IFindByIdDTO = { id: '123' };
const response: Promise<IUserResponse.IUserDTO> = contract.findById(request);
return response;
};📚 Referencias
- Core Package: @quickbot.io/core
- TypeScript Handbook: typescriptlang.org
- Zod Documentation: zod.dev
- JSDoc Standards: jsdoc.app
Versión: 1.0.0-alpha.1
Última actualización: Julio 2025
Compatibilidad: @quickbot.io/core ^0.1.0-alpha.1
