App Services

packages/app-services/README.md

@repo/app-services

Servicios de aplicación reutilizables que encapsulan la lógica de dominio y el acceso a datos para el monorepo Nidus.

Índice

  1. Función del package
  2. Instalación
  3. API — Surveys
  4. Constantes de dominio
  5. Tipos compartidos
  6. Lineamientos de desarrollo
  7. Contribución y validación

1. Función del package

  • Centraliza casos de uso compartidos entre apps.
  • Evita duplicar lógica de negocio en componentes o páginas.
  • Acepta dependencias externas (ej. Firestore) por parámetro para mantenerse desacoplado del proveedor.
  • Expone sus módulos como subpath exports independientes.
Subpath exportContenido
@repo/app-services/surveyssaveSurvey, getSurveys
@repo/app-services/constantsSURVEYS_COLLECTION

2. Instalación

json
{
  "dependencies": {
    "@repo/app-services": "workspace:*"
  }
}
bash
pnpm install

3. API — Surveys

Importar desde @repo/app-services/surveys (subpath export) o desde @repo/app-services.

saveSurvey(db, surveyData)

Persiste una nueva encuesta en Firestore.

ts
import { saveSurvey } from '@repo/app-services/surveys';
import type { CreateSurveyData, SurveyData } from '@repo/schemas';

const nueva: CreateSurveyData = {
  name: 'Martín García',
  email: 'martin@barrio.com',
  phone: '+541112345678',
  role: 'Administrador',
  control_methods: ['Sistema digital'],
  main_problem: 'No tenemos trazabilidad de las obras en curso.',
  neighborhood_size: '51-100',
  willingness_to_pay: 'Sí, si realmente funciona',
  willing_to_interview: 'Sí',
};

const guardada: SurveyData = await saveSurvey(db, nueva);
console.log(guardada.id); // ID generado por Firestore

Firma:

ts
function saveSurvey(db: Firestore, surveyData: CreateSurveyData): Promise<SurveyData>;
ParámetroTipoDescripción
dbFirestoreInstancia de Firestore (client o admin, según el contexto)
surveyDataCreateSurveyDataDatos de la encuesta sin metadatos (id, createdAt, updatedAt)

getSurveys(db, dateRange?)

Consulta encuestas desde Firestore con filtro opcional por rango de fechas.

ts
import { getSurveys } from '@repo/app-services/surveys';

// Todas las encuestas
const todas = await getSurveys(db);

// Solo encuestas de un rango específico
const recientes = await getSurveys(db, {
  from: new Date('2025-01-01'),
  to: new Date('2025-01-31'),
});

Firma:

ts
function getSurveys(db: Firestore, dateRange?: IDateRange): Promise<SurveysData>;
ParámetroTipoDescripción
dbFirestoreInstancia de Firestore
dateRangeIDateRange?Rango de fechas opcional. Filtra por createdAt.

4. Constantes de dominio

ts
import { SURVEYS_COLLECTION } from '@repo/app-services/constants';

console.log(SURVEYS_COLLECTION); // 'surveys'
ConstanteValorDescripción
SURVEYS_COLLECTION'surveys'Nombre de la colección Firestore

5. Tipos compartidos

ts
// src/types/types.ts
export interface IDateRange {
  from: Date;
  to: Date;
}

Los tipos de las entidades (SurveyData, CreateSurveyData, SurveysData) están definidos en @repo/schemas y reexportados desde ahí.


6. Lineamientos de desarrollo

  1. Separación de responsabilidades: lógica de dominio sin detalles de UI.
  2. Inyección de dependencias: Firestore se pasa como parámetro, nunca se importa directamente.
  3. Tipos explícitos: entrada y salida siempre tipados con interfaces de @repo/schemas.
  4. Sin errores silenciosos: propagar o mapear errores de forma explícita.
  5. Un módulo por contexto de negocio: no mezclar dominios en el mismo archivo.

Agregar un nuevo servicio

  1. Crear src/<dominio>/<dominio>-service.ts.
  2. Exportar desde src/index.ts o como subpath export nuevo en package.json.
  3. Definir los contratos en @repo/schemas.
  4. Documentar la API en este README.

7. Contribución y validación

bash
pnpm lint --filter @repo/app-services
pnpm build --filter @repo/app-services
pnpm check-types --filter @repo/app-services