JSPM

  • Created
  • Published
  • Downloads 52
  • Score
    100M100P100Q83814F
  • License UNLICENSED

PostgreSQL data persistence layer for RemPays platform with TypeORM, extensible seeders, and Lambda-ready architecture

Package Exports

  • @rempays/data-core
  • @rempays/data-core/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@rempays/data-core) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@rempays/data-core

PostgreSQL data layer for RemPays platform. Centralized data persistence with TypeORM, extensible seeders, and Lambda-ready architecture.

Table of Contents

Features

  • 🗄️ PostgreSQL with TypeORM: Full ESM support with TypeScript
  • 🔄 Migration System: Version-controlled schema changes
  • 🌱 Extensible Seeder System: Core seeders + Lambda-registrable seeders
  • 🐳 Docker Compose: Local development environment
  • 📦 NPM Package: Ready for Lambda consumption
  • 🔐 Cognito Integration: User authentication ready
  • 🤖 AI Agent Configuration: System prompts, validation rules, and dynamic tools
  • 🔌 Connection Pooling: Optimized for serverless environments
  • 🎯 TypeScript Strict Mode: Full type safety
  • 🔑 UUID Primary Keys: Using PostgreSQL uuid_generate_v4()
  • 🗑️ Soft Delete: All entities support soft deletion

Installation

For Lambda Projects

npm install @rempays/data-core

For Development

git clone <repository-url>
cd data-core
npm install

Quick Start

1. Environment Setup

Create a .env file:

# Local Development
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/rempays_dev
DB_HOST=localhost
DB_PORT=5433
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_NAME=rempays_dev
NODE_ENV=development

# Production (Neon)
# DATABASE_URL=postgresql://user:password@ep-xxx.neon.tech/rempays?sslmode=require
# NODE_ENV=production

2. Start Local Database

# Start PostgreSQL in Docker
npm run db:start

# Verify it's running
docker ps | grep rempays-postgres

3. Run Migrations

# Build and run migrations
npm run migration:run

4. Seed Initial Data

# Run all seeders (categories, validation rules, templates)
npm run seed:run

5. Verify Setup

# Check database tables
docker exec rempays-postgres psql -U postgres -d rempays_dev -c "\dt"

# Check seeded data
docker exec rempays-postgres psql -U postgres -d rempays_dev -c "SELECT code, name FROM categories;"

Development Setup

Prerequisites

  • Node.js >= 18.0.0
  • Docker and Docker Compose
  • PostgreSQL client (optional, for manual queries)

Initial Setup

# 1. Install dependencies
npm install

# 2. Start database
npm run db:start

# 3. Run migrations
npm run migration:run

# 4. Seed data
npm run seed:run

# 5. Build project
npm run build

Development Workflow

# Watch mode for TypeScript compilation
npm run build:watch

# In another terminal, make changes and test
npm run migration:generate MyNewFeature
npm run migration:run

Creating New Entities

Step 1: Create Entity File

Create src/modules/my-entity/my-entity.entity.ts:

import { Entity, Column, Index, ManyToOne, JoinColumn } from 'typeorm';
import { BaseEntity } from '../../abstract/base.entity';
import { Business } from '../business/business.entity';

@Entity('my_entities')
@Index(['businessId', 'code'], { unique: true })
export class MyEntity extends BaseEntity {
    @Column({ type: 'varchar', length: 100 })
    code: string;

    @Column({ type: 'varchar', length: 255 })
    name: string;

    @Column({ type: 'text', nullable: true })
    description?: string;

    // Relationship
    @Column({ type: 'uuid' })
    businessId: string;

    @ManyToOne(() => 'Business', { lazy: true })
    @JoinColumn({ name: 'business_id' })
    business: Promise<Business>;
}

Important:

  • Extend BaseEntity for automatic id, timestamps, and soft delete
  • Use camelCase for properties (TypeORM handles snake_case in DB)
  • Use lazy loading with string references to avoid circular dependencies
  • Add indexes for frequently queried fields

Step 2: Create Repository

Create src/modules/my-entity/my-entity.repository.ts:

import { DataSource, Repository } from 'typeorm';
import { MyEntity } from './my-entity.entity';

export class MyEntityRepository extends Repository<MyEntity> {
    constructor(dataSource: DataSource) {
        super(MyEntity, dataSource.createEntityManager());
    }

    /**
     * Find by code
     */
    async findByCode(code: string): Promise<MyEntity | null> {
        return this.findOne({ where: { code } });
    }

    /**
     * Find all by business
     */
    async findByBusiness(businessId: string): Promise<MyEntity[]> {
        return this.find({
            where: { businessId },
            order: { createdAt: 'DESC' },
        });
    }

    /**
     * Find active entities
     */
    async findActive(): Promise<MyEntity[]> {
        return this.createQueryBuilder('entity')
            .where('entity.deletedAt IS NULL')
            .orderBy('entity.name', 'ASC')
            .getMany();
    }
}

Step 3: Create Index File

Create src/modules/my-entity/index.ts:

export * from './my-entity.entity';
export * from './my-entity.repository';

Step 4: Export from Main Index

Add to src/index.ts:

// My Entity module
export * from './modules/my-entity';

Step 5: Generate Migration

# Build first
npm run build

# Generate migration
npm run migration:generate MyEntityTable

# Review the generated migration in migrations/
# Then run it
npm run migration:run

Step 6: Create Seeder (Optional)

# Generate seeder template
npm run seeder:generate my-entity

# Edit src/seeders/004-my-entity.seeder.ts

Example seeder:

import { DataSource } from 'typeorm';
import { MyEntityRepository } from '../modules/my-entity';

export async function seedMyEntity(dataSource: DataSource): Promise<void> {
    const repo = new MyEntityRepository(dataSource);

    const entities = [
        {
            code: 'ENTITY_1',
            name: 'Entity One',
            description: 'First entity',
            businessId: null, // or specific business ID
        },
        {
            code: 'ENTITY_2',
            name: 'Entity Two',
            description: 'Second entity',
            businessId: null,
        },
    ];

    for (const data of entities) {
        const existing = await repo.findByCode(data.code);
        if (!existing) {
            const entity = repo.create(data);
            await repo.save(entity);
            console.log(`✅ Entity created: ${data.name}`);
        } else {
            console.log(`⏭️  Entity already exists: ${data.name}`);
        }
    }
}

Step 7: Test Locally

# Rebuild
npm run build

# Run new seeder
npm run seed:run

# Verify in database
docker exec rempays-postgres psql -U postgres -d rempays_dev -c "SELECT * FROM my_entities;"

Migrations

Generate Migration

# After creating/modifying entities
npm run build
npm run migration:generate MyFeatureName

This creates a timestamped migration file in src/migrations/ which will be compiled to dist/migrations/ during build.

Run Migrations

# Run all pending migrations
npm run migration:run

Revert Migration

# Revert the last migration
npm run migration:revert

Migration Best Practices

  1. Always review generated migrations before running
  2. Test migrations locally with Docker before production
  3. Never edit migrations after they've been run in production
  4. Use descriptive names: AddUserEmailIndex, not Migration1
  5. One feature per migration: Don't mix unrelated changes

Manual Migration Example

If you need to create a migration manually:

import { MigrationInterface, QueryRunner } from "typeorm";

export class AddMyEntityTable1234567890 implements MigrationInterface {
    name = 'AddMyEntityTable1234567890'

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`
            CREATE TABLE "my_entities" (
                "id" uuid NOT NULL DEFAULT uuid_generate_v4(),
                "created_at" TIMESTAMP NOT NULL DEFAULT now(),
                "updated_at" TIMESTAMP NOT NULL DEFAULT now(),
                "deleted_at" TIMESTAMP,
                "code" character varying(100) NOT NULL,
                "name" character varying(255) NOT NULL,
                "description" text,
                "business_id" uuid,
                CONSTRAINT "PK_my_entities" PRIMARY KEY ("id")
            )
        `);

        await queryRunner.query(`
            CREATE UNIQUE INDEX "IDX_my_entities_code" 
            ON "my_entities" ("business_id", "code")
        `);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`DROP INDEX "IDX_my_entities_code"`);
        await queryRunner.query(`DROP TABLE "my_entities"`);
    }
}

Seeders

Core Seeders (Included in Package)

The package includes 3 core seeders:

  1. 001-categories.seeder.ts - Business categories (restaurant, hardware-store, etc.)
  2. 002-validation-rules.seeder.ts - 17 AI validation rules
  3. 003-system-prompt-templates.seeder.ts - AI prompt templates per category

Generate New Seeder

npm run seeder:generate my-feature

This creates src/seeders/00X-my-feature.seeder.ts with the next available number.

Seeder Template

import { DataSource } from 'typeorm';
import { MyEntityRepository } from '../modules/my-entity';

export async function seedMyFeature(dataSource: DataSource): Promise<void> {
    const repo = new MyEntityRepository(dataSource);

    // Your seeding logic here
    const data = [
        { code: 'ITEM_1', name: 'Item One' },
        { code: 'ITEM_2', name: 'Item Two' },
    ];

    for (const item of data) {
        const existing = await repo.findByCode(item.code);
        if (!existing) {
            const entity = repo.create(item);
            await repo.save(entity);
            console.log(`✅ Created: ${item.name}`);
        } else {
            console.log(`⏭️  Already exists: ${item.name}`);
        }
    }
}

Run Seeders

# Run all seeders
npm run seed:run

# Run specific seeder
npm run seed:specific categories

Seeder Priority System

Seeders run in order based on their numeric prefix:

  • 001-099: Core package seeders
  • 100-199: Lambda-specific seeders (recommended)
  • 200+: Custom/optional seeders

Extensible Seeders for Lambdas

Lambdas can register their own seeders:

import { registerSeeder, runAllSeeders } from '@rempays/data-core';

// Register custom seeder
registerSeeder({
    name: 'lambda-custom-tools',
    priority: 100,
    fn: async (dataSource) => {
        // Your seeding logic
    }
});

// Run all seeders (core + custom)
await runAllSeeders(dataSource);

See Usage in Lambdas for more details.

Usage in Lambdas

Basic Repository Usage

import { 
    ConnectionManager, 
    UserRepository, 
    BusinessRepository 
} from '@rempays/data-core';

export const handler = async (event) => {
    // Get database connection
    const connectionManager = ConnectionManager.getInstance();
    const dataSource = await connectionManager.getDataSource();
    
    // Use repositories
    const userRepo = new UserRepository(dataSource);
    const user = await userRepo.findByEmail(event.email);
    
    if (!user) {
        return { statusCode: 404, body: 'User not found' };
    }
    
    return { 
        statusCode: 200, 
        body: JSON.stringify(user) 
    };
};

Registering Custom Seeders from Lambdas

import { 
    registerSeeder, 
    runAllSeeders,
    ConnectionManager,
    DynamicToolRepository 
} from '@rempays/data-core';

// Register a custom seeder for your lambda
registerSeeder({
    name: 'lambda-custom-tools',
    priority: 100, // Higher priority = runs after core seeders (0-99)
    fn: async (dataSource) => {
        const toolRepo = new DynamicToolRepository(dataSource);
        
        // Check if tool already exists
        const existing = await toolRepo.findByFunctionName('get_menu');
        if (existing) {
            console.log('✅ Tool already exists: get_menu');
            return;
        }
        
        // Create your custom tool
        const tool = toolRepo.create({
            functionName: 'get_menu',
            businessId: null, // null = global tool
            schemaJson: {
                name: 'get_menu',
                description: 'Get restaurant menu items',
                parameters: {
                    type: 'object',
                    properties: {
                        category: { type: 'string' }
                    }
                }
            },
            actionType: 'TYPEORM_SAVE',
            actionConfig: {
                entity: 'CatalogItem',
                operation: 'find'
            },
            isActive: true
        });
        
        await toolRepo.save(tool);
        console.log('✅ Tool created: get_menu');
    }
});

// Run all seeders (core + custom)
export const seedHandler = async () => {
    const connectionManager = ConnectionManager.getInstance();
    const dataSource = await connectionManager.getDataSource();
    
    await runAllSeeders(dataSource);
    
    return { statusCode: 200, body: 'Seeders completed' };
};

Seeder Priority System

  • 0-99: Reserved for core data-core seeders (categories, validation rules, templates)
  • 100-199: Lambda-specific seeders (recommended range)
  • 200+: Custom/optional seeders
// Example: Multiple seeders with different priorities
registerSeeder({
    name: 'lambda-base-tools',
    priority: 100, // Runs first among lambda seeders
    fn: async (dataSource) => {
        // Seed base tools
    }
});

registerSeeder({
    name: 'lambda-business-specific',
    priority: 150, // Runs after base tools
    fn: async (dataSource) => {
        // Seed business-specific data
    }
});

Advanced Seeder Options

import { runAllSeeders, listSeeders } from '@rempays/data-core';

// Run only external (lambda) seeders
await runAllSeeders(dataSource, { onlyExternal: true });

// Run only internal (core) seeders
await runAllSeeders(dataSource, { onlyInternal: true });

// Silent mode (no console output)
await runAllSeeders(dataSource, { silent: true });

// List all registered seeders
const seeders = await listSeeders();
console.log(seeders);
// [
//   { name: '001-categories.seeder', priority: 1, type: 'internal' },
//   { name: 'lambda-custom-tools', priority: 100, type: 'external' }
// ]

Connection Management

import { ConnectionManager } from '@rempays/data-core';

// Singleton pattern - reuses connection
const connectionManager = ConnectionManager.getInstance();
const dataSource = await connectionManager.getDataSource();

// Connection is automatically managed
// No need to close in Lambda (reused across invocations)

Environment Variables for Lambdas

# Set in Lambda environment variables
DATABASE_URL=postgresql://user:password@ep-xxx.neon.tech/rempays?sslmode=require
NODE_ENV=production

Database Schema

Core Tables

users

User profiles linked to AWS Cognito

Column Type Description
id uuid Primary key
cognito_sub varchar Cognito user ID (unique)
email varchar Email (unique)
phone_number varchar Phone (unique)
first_name varchar First name
last_name varchar Last name
document_number varchar ID document
business_id uuid Associated business (nullable)
created_at timestamp Creation time
updated_at timestamp Last update
deleted_at timestamp Soft delete

businesses

Business entities with DIAN integration

Column Type Description
id uuid Primary key
legal_name varchar Legal business name
commercial_name varchar Commercial name
nit varchar Tax ID (unique)
category_id uuid Business category
owner_user_id uuid Owner user
email_contact varchar Contact email
phone_contact varchar Contact phone
address text Physical address
city varchar City
country varchar Country
logo_url text Logo URL
description text Description
dian_document_url text DIAN document
dian_extracted_data jsonb Extracted DIAN data
is_active boolean Active status

categories

Business categories with AI templates

Column Type Description
id uuid Primary key
code varchar Category code (unique)
name varchar Category name
description text Description
ai_template_prompt text AI template

business_configs

AI agent configurations per business

Column Type Description
id uuid Primary key
business_id uuid Business reference
config_name varchar Config name
system_prompt text AI system prompt
context text Business context
questions jsonb FAQ structure
is_active boolean Active status

business_channels

Communication channels (WhatsApp, Web, etc.)

Column Type Description
id uuid Primary key
business_config_id uuid Config reference
channel_type enum WHATSAPP, WEB, INSTAGRAM, FACEBOOK
purpose enum ORDERS, SUPPORT, GENERAL, SALES, APPOINTMENTS
identifier varchar Phone/Page ID
provider_meta jsonb Provider metadata

AI & Tools Tables

system_prompt_templates

Reusable AI prompt templates

Column Type Description
id uuid Primary key
template_name varchar Template name
template_code varchar Unique code
content text Prompt content
version integer Version number
category_code varchar Category reference
required_variables jsonb Required variables
is_active boolean Active status
is_default boolean Default for category

validation_rules

Global security and validation rules

Column Type Description
id uuid Primary key
rule_name varchar Rule name (unique)
description text Description
rule_content text Rule content
priority integer Priority (1 = highest)
is_active boolean Active status
applies_to_all_businesses boolean Global rule

dynamic_tools

AI function calling definitions

Column Type Description
id uuid Primary key
function_name varchar Function name
business_id uuid Business (null = global)
schema_json jsonb Function schema
action_type enum MONGO_AGGREGATE, TYPEORM_SAVE, API_CALL, CUSTOM
action_config jsonb Action configuration
is_active boolean Active status
metadata jsonb Additional metadata

chats

Conversation history

Column Type Description
id uuid Primary key
contact_id varchar Customer ID
business_id uuid Business reference
channel enum whatsapp, web, api
last_incoming_message text Last message
message_count integer Message count
last_message_timestamp timestamptz Last message time
messages jsonb Message history

API Reference

ConnectionManager

Singleton for managing database connections.

const connectionManager = ConnectionManager.getInstance();
const dataSource = await connectionManager.getDataSource();

Repositories

All repositories extend TypeORM's Repository class.

UserRepository

const userRepo = new UserRepository(dataSource);

// Find by email
const user = await userRepo.findByEmail('user@example.com');

// Find by Cognito sub
const user = await userRepo.findByCognitoSub('cognito-sub-id');

// Find by phone
const user = await userRepo.findByPhoneNumber('+1234567890');

// Find by business
const users = await userRepo.findByBusiness('business-uuid');

BusinessRepository

const businessRepo = new BusinessRepository(dataSource);

// Find by NIT
const business = await businessRepo.findByNit('900123456-7');

// Find by owner
const businesses = await businessRepo.findByOwner('user-uuid');

// Find active businesses
const active = await businessRepo.findActive();

// Find by category
const restaurants = await businessRepo.findByCategory('category-uuid');

CategoryRepository

const categoryRepo = new CategoryRepository(dataSource);

// Find by code
const category = await categoryRepo.findByCode('restaurant');

// Find all active
const categories = await categoryRepo.findAllActive();

Seeder Functions

import { 
    registerSeeder, 
    runAllSeeders, 
    runSeeder,
    listSeeders,
    clearExternalSeeders 
} from '@rempays/data-core';

// Register seeder
registerSeeder({
    name: 'my-seeder',
    priority: 100,
    fn: async (dataSource) => { /* ... */ }
});

// Run all seeders
await runAllSeeders(dataSource);

// Run specific seeder
await runSeeder(dataSource, 'categories');

// List seeders
const seeders = await listSeeders();

// Clear external seeders (testing)
clearExternalSeeders();

Scripts

Database Management

# Start PostgreSQL in Docker
npm run db:start

# Stop database
npm run db:stop

# Stop and remove data (fresh start)
npm run db:reset

# View logs
npm run db:logs

Build

# Build once
npm run build

# Watch mode
npm run build:watch

# Pre-publish build (automatic)
npm run prepublishOnly

Migrations

# Generate migration
npm run migration:generate MigrationName

# Run migrations
npm run migration:run

# Revert last migration
npm run migration:revert

# Sync schema (dev only - dangerous!)
npm run schema:sync

Seeders

# Generate seeder
npm run seeder:generate seeder-name

# Run all seeders
npm run seed:run

# Run specific seeder
npm run seed:specific categories

# Test seeder system
npm run test:seeders

Testing

# Full local test (db + migrations + seeders)
npm run test:local

# Test seeder system
npm run test:seeders

Environment Variables

Local Development

DATABASE_URL=postgresql://postgres:postgres@localhost:5433/rempays_dev
DB_HOST=localhost
DB_PORT=5433
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_NAME=rempays_dev
NODE_ENV=development

Production (Neon)

DATABASE_URL=postgresql://user:password@ep-xxx.neon.tech/rempays?sslmode=require
NODE_ENV=production

Lambda Environment

Set these in AWS Lambda environment variables:

DATABASE_URL=<neon-connection-string>
NODE_ENV=production

Publishing

The package uses automated CI/CD with GitHub Actions for publishing to NPM.

Automated Publishing

Branch/Tag Environment Version NPM Tag Action
develop Beta Auto-increment beta Auto-publish
main Production package.json latest Auto-publish
v*.*.* Release From tag latest Auto-publish + GitHub Release
Pull Request CI Testing - - Test only, no publish

Developer Workflow

Beta Release (develop):

git checkout develop
git add .
git commit -m "feat: new feature"
git push origin develop
# → Automatically publishes @rempays/data-core@beta

Production Release (main with tag):

git checkout main
git merge develop
npm version patch  # or minor, or major
git push origin main
git tag v1.0.1
git push origin v1.0.1
# → Automatically publishes @rempays/data-core@1.0.1

Manual Publishing (First Time Only)

For the initial package creation:

npm login
npm publish --access restricted

After this, CI/CD handles all updates automatically.

CI/CD & Automated Deployment

Overview

El proyecto usa GitHub Actions para automatizar testing, publicación a NPM, y deployment de migraciones/seeders a la base de datos.

Workflow Completo

Push to develop/main
       ↓
   Build Package
       ↓
   Publish to NPM
       ↓
   Deploy to Database (Migrations + Seeders)

Detección Automática de Entorno

Branch/Tag Environment NPM Tag Database Migrations Seeders
develop Beta beta Develop DB
main Production latest Production DB
v*.*.* Release latest Production DB
Pull Request CI Test - -

GitHub Environments Setup

El workflow usa GitHub Environments para gestionar credenciales de base de datos por entorno.

1. Crear Environments

Ve a SettingsEnvironments en tu repositorio GitHub.

2. Environment: develop

Nombre: develop
Secret: DATABASE_URL = postgresql://user:pass@ep-xxx.neon.tech/rempays_dev?sslmode=require
Deployment branches: develop

3. Environment: production

Nombre: production
Secret: DATABASE_URL = postgresql://user:pass@ep-yyy.neon.tech/rempays_prod?sslmode=require
Deployment branches: main, v*.*.*
Required reviewers: [Tu usuario] (recomendado para seguridad)

Agregar Secrets con GitHub CLI

# Agregar DATABASE_URL a develop
gh secret set DATABASE_URL --env develop

# Agregar DATABASE_URL a production
gh secret set DATABASE_URL --env production

Flujo de Deployment

Develop Branch (Beta + Develop DB)

git checkout develop
git add .
git commit -m "feat: nueva funcionalidad"
git push origin develop

GitHub Actions ejecutará:

  1. ✅ Build del paquete
  2. ✅ Publicación a NPM con tag beta
  3. Migraciones en base de datos develop
  4. Seeders en base de datos develop

Main Branch (Production + Production DB)

git checkout main
git merge develop
git push origin main

GitHub Actions ejecutará:

  1. ✅ Build del paquete
  2. ✅ Publicación a NPM con tag latest
  3. Migraciones en base de datos production
  4. Seeders en base de datos production

Release Tag (Production + Production DB)

git tag v1.0.0
git push origin v1.0.0

GitHub Actions ejecutará:

  1. ✅ Build del paquete
  2. ✅ Publicación a NPM con versión específica
  3. Migraciones en base de datos production
  4. Seeders en base de datos production
  5. ✅ GitHub Release creado

Verificar Deployment

En GitHub Actions:

  1. Ve a Actions tab
  2. Click en el workflow run
  3. Verás 2 jobs:
    • publish - Publicación a NPM
    • deploy-database - Migraciones y seeders

Logs del Job deploy-database:

Run migrations
✅ Migrations executed successfully

Run seeders
🌱 Starting seeders...
📦 Running: 001-categories.seeder (priority: 1)
✅ Category created: Restaurante
📦 Running: 002-validation-rules.seeder (priority: 2)
✅ Validation rule created: ser-inmune-a-trucos
📦 Running: 003-system-prompt-templates.seeder (priority: 3)
✅ Template created: Restaurante - Asistente Amigable v1
✅ All seeders completed successfully!

Seguridad

Protección de Production

Recomendaciones:

  1. Required reviewers: Agregar al menos 1 reviewer para aprobar deployments a production
  2. Deployment branches: Restringir a main y tags v*
  3. Wait timer: Opcional, agregar delay antes de deployment

Configurar Required Reviewers:

  1. Ve a SettingsEnvironmentsproduction
  2. Marca Required reviewers
  3. Agrega usuarios/equipos que deben aprobar
  4. Save protection rules

Ahora cada deployment a production requerirá aprobación manual.

Neon Database Branching

Neon permite crear branches de tu base de datos:

  • develop branch: Para desarrollo/staging
  • main branch: Para producción

Cada branch tiene su propio connection string. Esto permite:

  • ✅ Probar migraciones en develop sin afectar producción
  • ✅ Rollback fácil si algo sale mal
  • ✅ Ambientes aislados

Rollback

Si necesitas revertir migraciones:

Opción 1: Revert Migration Localmente

# Conectar a la base de datos
export DATABASE_URL="postgresql://..."

# Revertir última migración
npm run migration:revert

Opción 2: Crear Migration de Rollback

# Generar nueva migración que revierte cambios
npm run migration:generate rollback-feature-x

# Editar la migración para revertir cambios
# Commit y push
git add migrations/
git commit -m "fix: rollback feature x"
git push origin develop

Project Structure

@rempays/data-core/
├── src/
│   ├── abstract/              # Base entities
│   │   └── base.entity.ts
│   ├── constants/             # Constants and types
│   │   ├── db-types.ts
│   │   └── validation-rules.constants.ts
│   ├── modules/               # Domain modules
│   │   ├── user/
│   │   │   ├── user.entity.ts
│   │   │   ├── user.repository.ts
│   │   │   └── index.ts
│   │   ├── business/
│   │   ├── category/
│   │   ├── business-config/
│   │   ├── business-channel/
│   │   ├── chat/
│   │   ├── dynamic-tool/
│   │   ├── system-prompt-template/
│   │   └── validation-rule/
│   ├── seeders/               # Data seeders
│   │   ├── index.ts
│   │   ├── 001-categories.seeder.ts
│   │   ├── 002-validation-rules.seeder.ts
│   │   └── 003-system-prompt-templates.seeder.ts
│   ├── connection-manager.ts  # Connection singleton
│   ├── data-core.module.ts    # NestJS module
│   ├── data-source.ts         # TypeORM config
│   └── index.ts               # Main exports
├── migrations/                # Database migrations
├── scripts/                   # Utility scripts
├── examples/                  # Usage examples
├── dist/                      # Compiled output
├── .env                       # Environment variables
├── .env.example               # Environment template
├── .npmignore                 # NPM ignore rules
├── docker-compose.yml         # Local PostgreSQL
├── init-db.sql                # Database initialization
├── tsconfig.json              # TypeScript config
├── package.json               # Package configuration
├── README.md                  # This file
├── CHANGELOG.md               # Version history
├── PUBLISHING.md              # Publishing guide
└── LICENSE                    # License file

Troubleshooting

Database Connection Issues

# Check if Docker is running
docker ps

# Check PostgreSQL logs
npm run db:logs

# Restart database
npm run db:reset

Migration Errors

# Revert last migration
npm run migration:revert

# Check migration status
docker exec rempays-postgres psql -U postgres -d rempays_dev -c "SELECT * FROM migrations;"

# Fresh start
npm run db:reset
npm run migration:run

Build Errors

# Clean build
rm -rf dist node_modules
npm install
npm run build

Seeder Issues

# Check seeder files
ls -la src/seeders/

# Run specific seeder
npm run seed:specific categories

# Check database
docker exec rempays-postgres psql -U postgres -d rempays_dev -c "SELECT * FROM categories;"

Contributing

  1. Create a feature branch
  2. Make your changes
  3. Generate migrations if schema changed
  4. Test locally with Docker
  5. Update CHANGELOG.md
  6. Submit PR

License

UNLICENSED - Proprietary software for RemPays platform.

Support

For issues and questions:

  • GitHub Issues: [repository-url]/issues
  • Team Contact: [contact-info]

Version: 1.0.0
Last Updated: 2024-02-14