adba
Version:
Any DataBase to API
895 lines (715 loc) • 25.5 kB
Markdown
# Development Guidelines for AI Agents
> Este documento establece los lineamientos de desarrollo que deben seguirse en **todos los proyectos**. Es un documento genérico y reutilizable que debe copiarse en cada proyecto nuevo para mantener consistencia en los estándares de desarrollo.
## 1. Testing Requirements
### Unit Testing Standards
- **Test Coverage**: Maintain a minimum of **85% code coverage** across the project
- **Mock Strategy**: All external dependencies must be mocked in unit tests to ensure isolated testing
- **Test Location**: Each source file in `src/` must have a corresponding test file in `__tests__/` at the project root
- **Folder Structure**: The `__tests__/` directory **must mirror exactly** the folder structure of `src/`
- **Test Execution**: Run tests using `yarn test` (package.json must include `jest --coverage` in the test script)
### Testing Best Practices
```typescript
/**
* Example test structure with proper mocking
*
* @example
* ```typescript
* import { ServiceClass } from '../src/services/service-class';
*
* jest.mock('../src/external/dependency', () => ({
* ExternalService: jest.fn().mockImplementation(() => ({
* connect: jest.fn().mockResolvedValue(true),
* disconnect: jest.fn().mockResolvedValue(true)
* }))
* }));
*
* describe('ServiceClass', () => {
* it('should perform operation successfully', async () => {
* const service = new ServiceClass(mockConfig);
* await expect(service.performOperation()).resolves.toBe(expectedResult);
* });
* });
* ```
*/
```
### Update Process
When updating any source file:
1. Review affected test files
2. Update mocks to reflect new dependencies or changes
3. Add tests for new functionality
4. Ensure coverage remains above 85%
5. Run `yarn test` before committing
**Important**: When creating new folders in `src/`, immediately create the corresponding folder structure in `__tests__/`. This keeps the project organized and ensures no test files are missed.
#### Example: Adding a new module
```bash
# 1. Create new source folder and file
mkdir -p src/services
touch src/services/new-service.ts
# 2. Immediately create corresponding test structure
mkdir -p __tests__/services
touch __tests__/services/new-service.test.ts
# 3. Implement source code
vim src/services/new-service.ts
# 4. Implement tests with proper mocks
vim __tests__/services/new-service.test.ts
```
## 2. File Structure and Organization
### File Mapping
The `__tests__/` directory structure **must replicate exactly** the `src/` directory structure:
```
src/
├── index.ts → __tests__/index.test.ts
├── server.ts → __tests__/server.test.ts
├── cli.ts → __tests__/cli.test.ts
├── responses.ts → __tests__/responses.test.ts
├── services/
│ ├── index.ts → __tests__/services/index.test.ts
│ ├── user-service.ts → __tests__/services/user-service.test.ts
│ └── data-service.ts → __tests__/services/data-service.test.ts
└── utils/
├── index.ts → __tests__/utils/index.test.ts
├── validators.ts → __tests__/utils/validators.test.ts
└── helpers.ts → __tests__/utils/helpers.test.ts
```
**Rule**: For every file `src/path/to/file.ts`, there must exist `__tests__/path/to/file.test.ts`
### Line Limit per File
- **Maximum lines per file**: 500-700 lines
- **Rationale**: Maintains readability and follows SOLID principles
- **Action**: If a file exceeds 700 lines, refactor into smaller, focused modules
- **Refactoring**: The refactoring process may include creating new files and folders. When doing so, **always create the corresponding test structure** in `__tests__/` to maintain the mirror structure.
### Modular Design Example
❌ **Bad**: Single 1500-line file
```typescript
// services.ts (1500 lines)
class UserService { /* 300 lines */ }
class ProductService { /* 400 lines */ }
class OrderService { /* 500 lines */ }
class NotificationService { /* 300 lines */ }
```
✅ **Good**: Separated into focused files
```
src/services/
├── index.ts (auto-generated exports)
├── user-service.ts (350 lines)
├── product-service.ts (450 lines)
├── order-service.ts (550 lines)
└── notification-service.ts (350 lines)
```
## 3. Documentation Standards
### TypeDoc Comments
All functions, classes, interfaces, and types must include comprehensive TypeDoc comments with:
- Description of purpose
- Parameter documentation
- Return value documentation
- **Usage examples** (mandatory)
### Documentation Example
```typescript
/**
* Establishes a connection to an external service using provided configuration.
* Handles connection pooling and automatic reconnection on failure.
*
* @param config - Service configuration object
* @param config.host - Service host address
* @param config.port - Service port number
* @param config.apiKey - Authentication API key
* @param options - Optional connection settings
* @param options.timeout - Connection timeout in milliseconds (default: 5000)
* @param options.retries - Maximum retry attempts (default: 3)
*
* @returns Promise that resolves to service connection instance
*
* @throws {ServiceConnectionError} If connection fails after retries
*
* @example
* ```typescript
* // Basic connection
* const service = await connectToService({
* host: 'api.example.com',
* port: 443,
* apiKey: 'your-api-key'
* });
* ```
*
* @example
* ```typescript
* // Connection with custom options
* const service = await connectToService(
* { host: 'api.example.com', port: 443, apiKey: 'key' },
* { timeout: 10000, retries: 5 }
* );
* ```
*/
export async function connectToService(
config: ServiceConfig,
options?: ConnectionOptions
): Promise<ServiceConnection> {
// Implementation
}
```
### README.md Maintenance
The README.md must include:
- Project description and purpose
- Installation instructions
- Configuration guide
- **Code examples** from TypeDoc comments
- How to run the application
- **How to generate and view documentation**
- Testing instructions
- Deployment guidelines
#### Documentation Generation
Include in README.md:
```markdown
## Documentation
Generate TypeDoc documentation:
\`\`\`bash
yarn docs
\`\`\`
View documentation:
- Open `docs/index.html` in your browser
- Or serve locally: `npx http-server docs -o`
Documentation includes:
- Full API reference
- Usage examples for all functions
- Type definitions
- Architecture diagrams
```
## 4. Build and Release Process
> **Note**: The release process is included here for reference and understanding only. **The user will execute the release process manually**. Agents should focus on ensuring code quality, tests, and documentation are ready for release, but should not execute release scripts.
### Automated Exports
**Index files and package.json exports are automatically generated** - do not manually edit them.
#### Auto-generated Files
- `src/index.ts` (main entry point)
- `src/services/index.ts` (service exports)
- Any other `index.ts` files in subdirectories
- `package.json` "exports" field
#### Build Scripts
```json
{
"scripts": {
"build": "webpack --mode production",
"generate:exports": "node generate-exports.js",
"test": "jest --coverage",
"docs": "typedoc",
"release": "./release.sh"
}
}
```
### Release Workflow
1. **Pre-release checks**:
```bash
yarn test # Ensure tests pass with >85% coverage
yarn lint # Code quality check (if configured)
yarn build # Verify build succeeds
```
2. **Generate exports** (usually automatic in build process):
```bash
node generate-exports.js
```
3. **Update version**:
```bash
node update-version.js
```
4. **Execute release**:
```bash
./release.sh
```
### Verification Checklist
Before each release:
- [ ] All tests pass with ≥85% coverage
- [ ] Documentation is up-to-date
- [ ] README.md includes latest examples
- [ ] Build completes without errors
- [ ] Auto-generated exports are current
- [ ] Version number is updated
## 5. SOLID Principles Compliance
### Single Responsibility Principle (SRP)
- Each class/function has one clear purpose
- If describing a file requires "and", it needs splitting
### Open/Closed Principle (OCP)
- Use interfaces and abstract classes for extensibility
- New features should extend, not modify existing code
### Liskov Substitution Principle (LSP)
- Derived classes must be substitutable for their base classes
- Maintain consistent behavior in inheritance hierarchies
### Interface Segregation Principle (ISP)
- Create small, focused interfaces
- Clients shouldn't depend on unused methods
### Dependency Inversion Principle (DIP)
- Depend on abstractions, not implementations
- Use dependency injection
### Example of SOLID Compliance
```typescript
/**
* Service adapter interface following ISP
*
* @example
* ```typescript
* class ApiAdapter implements IServiceAdapter {
* async connect(config: ServiceConfig): Promise<void> {
* // API-specific implementation
* }
* }
* ```
*/
export interface IServiceAdapter {
connect(config: ServiceConfig): Promise<void>;
disconnect(): Promise<void>;
request(endpoint: string, params?: any): Promise<ServiceResponse>;
}
/**
* Service manager following DIP - depends on abstraction
*/
export class ServiceManager {
constructor(private adapter: IServiceAdapter) {}
async makeRequest(endpoint: string): Promise<ServiceResponse> {
return this.adapter.request(endpoint);
}
}
```
## 6. Environment Variables and Configuration
### CLI.ts Responsibility
The `cli.ts` file is the **central point for all environment variable handling** and environment control.
#### Rules
1. **Only `cli.ts` reads environment variables** (except `process.env.ENV` and `process.env.NODE_ENV`)
2. **All other files receive configuration through parameters**
3. **No direct `process.env` usage** outside of cli.ts (except ENV and NODE_ENV)
4. **Must use yargs for CLI configuration** with:
- Commands (`.command()`) for different operations
- Options (`.option()`) for each command with proper descriptions
- Environment variable references in `defaultDescription`
- Examples (`.example()`) showing CLI params and env vars
- Comprehensive help documentation automatically generated by yargs
### Allowed Direct Usage
These two variables can be used anywhere:
- `process.env.ENV` - Environment name (dev, staging, production)
- `process.env.NODE_ENV` - Node environment (development, production, test)
```typescript
// Allowed in any file
if (process.env.NODE_ENV === 'development') {
console.log('Debug info');
}
if (process.env.ENV === 'production') {
// Production-specific logic
}
```
### Configuration Pattern
#### ❌ Bad: Direct environment access in modules
```typescript
// server.ts (BAD)
export function startServer() {
const port = process.env.PORT || 3000; // ❌ Don't do this
const host = process.env.HOST || 'localhost'; // ❌ Don't do this
// ...
}
```
#### ✅ Good: Configuration through parameters
```typescript
// cli.ts (GOOD) - Central configuration
import { startServer } from './server';
/**
* Main entry point - handles all environment configuration
*/
async function main() {
const config = {
port: parseInt(process.env.PORT || '3000', 10),
host: process.env.HOST || 'localhost',
apiKey: process.env.API_KEY,
database: {
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT || '5432', 10),
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
}
};
await startServer(config);
}
// server.ts (GOOD) - Receives configuration
/**
* Starts the HTTP server with provided configuration
*
* @param config - Server configuration
* @example
* ```typescript
* await startServer({
* port: 3000,
* host: 'localhost',
* apiKey: 'your-key',
* database: { ... }
* });
* ```
*/
export async function startServer(config: ServerConfig): Promise<void> {
// Use config parameter, not process.env
const server = express();
server.listen(config.port, config.host, () => {
console.log(`Server running on ${config.host}:${config.port}`);
});
}
```
### Environment Configuration Example
```typescript
#!/usr/bin/env node
// cli.ts
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
/**
* Application configuration interface
*/
export interface AppConfig {
server: {
port: number;
host: string;
};
service: {
apiKey: string;
endpoint: string;
};
}
/**
* Configures and parses CLI arguments using yargs with commands
* Note: cli.ts is the ONLY file that should have the shebang (#!/usr/bin/env node)
*
* @returns Parsed yargs instance
*
* @example
* ```typescript
* const cli = configureCLI();
* // Automatically handles --help and command routing
* ```
*/
function configureCLI() {
return yargs(hideBin(process.argv))
.scriptName('project-name')
.version('1.0.0')
.usage('$0 <command> [options]')
// Start server command
.command(
'start',
'Start the application server',
(yargs) => {
return yargs
.option('port', {
alias: 'p',
type: 'number',
description: 'Server port',
default: 3000,
defaultDescription: 'PORT environment variable or 3000'
})
.option('api-key', {
type: 'string',
description: 'API key for external services (required)',
defaultDescription: 'API_KEY environment variable (required)'
})
.example('$0 start --port 3000 --api-key your-key', 'Start with CLI params')
.example('PORT=3000 API_KEY=your-key $0 start', 'Start with env vars');
},
async (argv) => {
const config = loadConfiguration(argv);
await startServer(config);
}
)
.demandCommand(1, 'You must specify a command')
.epilogue('Environment variables take precedence over CLI arguments.')
.help()
.strict();
}
/**
* Loads and validates configuration from environment variables and CLI args
* Environment variables take precedence over CLI arguments
*
* @param argv - Parsed yargs arguments
* @returns Application configuration object
* @throws {Error} If required variables are missing
*/
export function loadConfiguration(argv: any): AppConfig {
const apiKey = process.env.API_KEY || argv.apiKey;
const endpoint = process.env.SERVICE_ENDPOINT || argv.endpoint;
// Validate required variables
if (!apiKey) {
throw new Error('Missing required API_KEY. Set via environment variable or --api-key argument.');
}
return {
server: {
port: parseInt(process.env.PORT || String(argv.port || 3000), 10),
host: process.env.HOST || argv.host || '0.0.0.0'
},
service: {
apiKey,
endpoint: endpoint || 'https://api.default.com'
}
};
}
/**
* Main CLI entry point
*/
async function main() {
try {
await configureCLI().parseAsync();
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
}
// Run if called directly
if (require.main === module) {
main();
}
```
### Environment Documentation (.env.example)
**Every project must maintain an up-to-date `.env.example` file** that documents all environment variables used by the application.
#### Requirements
1. **Complete documentation**: Every environment variable read in `cli.ts` must be documented
2. **Example values**: Provide realistic example values (never real secrets)
3. **Clear descriptions**: Each variable should have a comment explaining its purpose
4. **Categorization**: Group related variables together
5. **Required vs Optional**: Clearly mark which variables are required
#### .env.example Template
```bash
# =============================================================================
# PROJECT NAME - Environment Variables
# =============================================================================
# Copy this file to .env and update the values for your environment
# Never commit real secrets or production values to version control
# -----------------------------------------------------------------------------
# Server Configuration
# -----------------------------------------------------------------------------
# Server port (default: 3000)
PORT=3000
# Server host (default: 0.0.0.0)
HOST=0.0.0.0
# CORS origin for frontend (optional)
CORS_ORIGIN=http://localhost:3000
# -----------------------------------------------------------------------------
# Authentication & Security
# -----------------------------------------------------------------------------
# JWT secret for token signing (REQUIRED)
# Generate with: openssl rand -base64 32
JWT_SECRET=your-super-secret-jwt-signing-key-here
# API key for external services (REQUIRED)
API_KEY=your-external-api-key-here
# -----------------------------------------------------------------------------
# Database Configuration (Optional)
# -----------------------------------------------------------------------------
# Database host (default: localhost)
DB_HOST=localhost
# Database port (default: 5432 for PostgreSQL, 3306 for MySQL)
DB_PORT=5432
# Database name (REQUIRED if using database)
DB_NAME=your_database_name
# Database user (REQUIRED if using database)
DB_USER=your_db_user
# Database password (REQUIRED if using database)
DB_PASSWORD=your_db_password
# -----------------------------------------------------------------------------
# External Services
# -----------------------------------------------------------------------------
# Service endpoint URL (optional)
SERVICE_ENDPOINT=https://api.example.com
# Service timeout in milliseconds (default: 5000)
SERVICE_TIMEOUT=5000
# -----------------------------------------------------------------------------
# Environment & Logging
# -----------------------------------------------------------------------------
# Environment name: development, staging, production
ENV=development
# Node environment: development, production, test
NODE_ENV=development
# Log level: error, warn, info, debug (default: info)
LOG_LEVEL=info
# -----------------------------------------------------------------------------
# Feature Flags (Optional)
# -----------------------------------------------------------------------------
# Enable specific features (true/false)
ENABLE_FEATURE_X=false
ENABLE_METRICS=true
```
#### Maintenance Rules
1. **Update immediately**: When adding new environment variables to `cli.ts`, update `.env.example` in the same commit
2. **Security first**: Never include real secrets, API keys, or production values
3. **Validation**: Ensure all variables in `.env.example` are actually used in the code
4. **Documentation sync**: Keep comments in sync with actual usage in `cli.ts`
5. **CI/CD check**: Consider adding a check to ensure `.env.example` includes all variables from `cli.ts`
#### Example Integration in CLI
```typescript
// cli.ts - Reference .env.example in help text
function configureCLI() {
return yargs(hideBin(process.argv))
.scriptName('project-name')
.version('1.0.0')
.usage('$0 <command> [options]')
.epilogue([
'Environment variables take precedence over CLI arguments.',
'See .env.example for a complete list of supported variables.',
'Copy .env.example to .env and customize for your environment.'
].join('\n'))
// ... rest of CLI configuration
}
```
#### Project Setup Reminder
Include in README.md:
```markdown
## Quick Start
1. Copy environment template:
\`\`\`bash
cp .env.example .env
\`\`\`
2. Edit `.env` with your values:
\`\`\`bash
vim .env # Update JWT_SECRET, API_KEY, etc.
\`\`\`
3. Install and run:
\`\`\`bash
yarn install
yarn start
\`\`\`
```
## 7. Code Quality Checklist
Before committing any code, verify:
- [ ] **Testing**: All tests pass with ≥85% coverage
- [ ] **Documentation**: TypeDoc comments with examples added
- [ ] **File Size**: No file exceeds 700 lines
- [ ] **SOLID**: Code follows SOLID principles
- [ ] **Environment**: No direct `process.env` usage (except ENV/NODE_ENV)
- [ ] **Configuration**: Parameters used instead of environment variables
- [ ] **Environment Documentation**: `.env.example` updated with new variables
- [ ] **Test Files**: Corresponding test file exists in `__tests__/`
- [ ] **Mocks**: All dependencies properly mocked in tests
- [ ] **README**: Updated with new examples if needed
- [ ] **Exports**: Auto-generated (don't manually edit)
- [ ] **Build**: `yarn build` succeeds
## 8. Development Workflow
### Daily Development Cycle
```bash
# 1. Start development
git checkout -b feature/your-feature
# 2. Make changes to source files
vim src/services/new-service.ts
# 3. Create corresponding test file
vim __tests__/services/new-service.test.ts
# 4. Run tests frequently
yarn test
# 5. Check coverage
yarn test --coverage
# 6. Update .env.example if new environment variables added
vim .env.example
# 7. Generate documentation
yarn docs
# 8. Update README if needed
vim README.md
# 9. Verify build
yarn build
# 10. Commit changes
git add .
git commit -m "feat: add new service with tests and docs"
# 11. Push and create PR
git push origin feature/your-feature
```
### Pre-commit Verification
```bash
# Run all checks
yarn test && yarn build && echo "✅ Ready to commit"
```
## 9. Common Patterns and Anti-Patterns
### ✅ Recommended Patterns
```typescript
// Dependency injection
export class Service {
constructor(private deps: Dependencies) {}
}
// Parameter-based configuration
export function initialize(config: Config) {}
// Comprehensive documentation
/** @example usage here */
// Small, focused files
// 500-700 lines max
// Isolated unit tests with mocks
jest.mock('./dependency');
```
### ❌ Anti-Patterns to Avoid
```typescript
// Direct environment variable access (except ENV/NODE_ENV)
const apiKey = process.env.API_KEY; // ❌
// Missing test files
// src/services/user.ts exists
// __tests__/services/user.test.ts missing // ❌
// Large monolithic files
// 1500+ lines in a single file // ❌
// Missing documentation examples
/** Does something */ // ❌ No example
// Manual export management
// Editing auto-generated index.ts // ❌
```
## 10. Resources and Tools
### Essential Commands
```bash
# Testing
yarn test # Run tests with coverage
yarn test --watch # Run tests in watch mode
yarn test --coverage # Generate coverage report
# Building
yarn build # Production build
yarn build:dev # Development build
# Documentation
yarn docs # Generate TypeDoc documentation
# Release
./release.sh # Execute release process
node update-version.js # Update version number
```
### File Structure Reference
```
project-name/
├── src/ # Source files (500-700 lines each)
│ ├── cli.ts # Environment variable handling
│ ├── server.ts # Server configuration
│ ├── index.ts # Main entry point
│ ├── responses.ts # Response utilities
│ ├── services/ # Service implementations
│ │ ├── index.ts # Auto-generated exports
│ │ └── user-service.ts # User service
│ └── utils/ # Utility functions
│ ├── index.ts # Auto-generated exports
│ └── validators.ts # Validation utilities
├── __tests__/ # Test files (MIRRORS src structure exactly)
│ ├── cli.test.ts
│ ├── server.test.ts
│ ├── index.test.ts
│ ├── responses.test.ts
│ ├── services/
│ │ ├── index.test.ts
│ │ └── user-service.test.ts
│ └── utils/
│ ├── index.test.ts
│ └── validators.test.ts
├── docs/ # Generated TypeDoc documentation
├── coverage/ # Test coverage reports
├── package.json # Dependencies and scripts
├── jest.config.ts # Jest configuration
├── tsconfig.json # TypeScript configuration
├── webpack.config.js # Webpack configuration
├── release.sh # Release automation script
└── README.md # Project-specific documentation
```
## Summary
This document establishes the foundation for consistent, high-quality development across all projects. All AI agents and developers must adhere to these guidelines to maintain code quality, testability, and maintainability.
**Key Principles**:
1. **Test everything** with >85% coverage
2. **Document everything** with examples
3. **Keep files small** (500-700 lines)
4. **Follow SOLID** principles
5. **Centralize configuration** in cli.ts
6. **Automate exports** - never edit manually
7. **Maintain project-specific README** with current examples
For questions or clarifications, refer to existing project code or consult the development team.