# Ormkit Production Guide
This guide covers production considerations: migrations, schema validation, performance features, and operational concerns.
## Table of Contents
1. [Feature Flags](#feature-flags)
2. [Migrations](#migrations)
3. [Schema Validation](#schema-validation)
4. [Performance Features](#performance-features)
5. [Error Handling](#error-handling)
6. [Platform Requirements](#platform-requirements)
7. [Operational Guidelines](#operational-guidelines)
---
## Feature Flags
Ormkit uses feature flags to minimize dependencies:
```toml
# Core ORM (minimal)
ormkit = { version = "0.2", features = ["orm"] }
# Core + migrations (recommended)
ormkit = { version = "0.2", features = ["orm", "migrations"] }
# Core + production features
ormkit = { version = "0.2", features = ["orm", "migrations", "validate", "performance"] }
# All features (default)
ormkit = { version = "0.2", features = ["full"] }
```
### Feature Matrix
| Entity derive | `orm` | sqlx | All projects |
| Migrations | `migrations` | sha2 | Schema management |
| Schema validation | `validate` | - | Runtime validation |
| Query caching | `cache` | bincode, futures | Read-heavy workloads |
| Parallel execution | `parallel` | futures | Bulk operations |
| Smart pooling | `smart-pool` | once_cell | Connection optimization |
---
## Migrations
### Setup
Enable the migrations feature:
```toml
ormkit = { version = "0.2", features = ["migrations"] }
```
### Creating Migrations
```bash
# Create a new migration
cargo run --bin ormkit-cli migration create create_users_table
# Creates: migrations/TIMESTAMP_create_users_table/up.sql
# migrations/TIMESTAMP_create_users_table/down.sql
```
### Migration Files
**up.sql** (applied when migrating up):
```sql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);
```
**down.sql** (applied when rolling back):
```sql
DROP INDEX idx_users_email;
DROP TABLE users;
```
### Running Migrations
```rust
use ormkit::migrations::{Migrator, MigrationError};
let migrator = Migrator::new(&pool).await?;
// Run pending migrations
migrator.migrate_up().await?;
// Rollback last migration
migrator.migrate_down().await?;
// Get migration status
let status = migrator.status().await?;
println!("Current version: {}", status.current_version);
```
### Best Practices
1. **Review generated SQL** before committing
2. **Use transactions** in migrations (automatic)
3. **Test rollback** procedures
4. **Backward compatibility**: Design rollbacks carefully
5. **Index creation**: Create indexes after data load for large tables
---
## Schema Validation
Validate that your entity definitions match the database schema:
```rust
use ormkit::validate::{SchemaValidator, ValidationError};
let validator = SchemaValidator::new(&pool);
// Validate all entities
validator.validate_entity::<User>().await?;
validator.validate_entity::<Post>().await?;
// Validate all registered entities
validator.validate_all().await?;
```
### What Gets Validated
- Table exists
- Columns exist with correct types
- Primary key exists
- Not null constraints match
- Default values (optional)
### Error Handling
```rust
match validator.validate_entity::<User>().await {
Ok(_) => println!("Schema valid"),
Err(ValidationError::ColumnNotFound { column, .. }) => {
eprintln!("Column {} not found in database", column);
}
Err(ValidationError::TypeMismatch { column, expected, actual }) => {
eprintln!("Type mismatch for {}: expected {:?}, got {:?}", column, expected, actual);
}
Err(e) => eprintln!("Validation error: {}", e),
}
```
---
## Performance Features
Enable performance features:
```toml
ormkit = { version = "0.2", features = ["performance"] }
```
### Query Caching
Cache prepared statements for repeated queries:
```rust
use ormkit::performance::cache::QueryCache;
let cache = QueryCache::new(100); // 100 cached queries
// Use cached repository
let repo = CachedRepository::new(&pool, cache);
let user = repo.find_by_id(user_id).await?;
```
**Cache Invalidation:**
- UPDATE: Invalidates by primary key
- DELETE: Invalidates by primary key
- INSERT: Optional write-through
- Manual: `cache.invalidate(&key)`
### Entity Caching
Cache query results with TTL:
```rust
use ormkit::performance::cache::EntityCache;
use std::time::Duration;
let cache = EntityCache::new(1000, Duration::from_secs(60));
// First call hits database
let user1 = cache.get(&pool, user_id).await?;
// Subsequent calls hit cache (within TTL)
let user2 = cache.get(&pool, user_id).await?;
```
**Cache Consistency:**
```rust
use ormkit::performance::cache::{CacheConsistency, InvalidationStrategy};
// Strong consistency (default) - zero stale reads
let strategy = InvalidationStrategy::strong();
// Eventual consistency - stale within TTL (analytics)
let strategy = InvalidationStrategy::eventual(Duration::from_secs(60));
```
### Parallel Execution
Execute bulk operations concurrently:
```rust
use ormkit::performance::parallel::ParallelExecutor;
let executor = ParallelExecutor::new(&pool, 10); // max 10 parallel
// Bulk fetch by IDs
let users = executor.bulk_fetch_by_id(ids, "users").await?;
// Parallel insert
let result = executor.bulk_insert(entities).await?;
```
### Smart Pooling
Optimized connection pool settings:
```rust
use ormkit::performance::pool::create_smart_pool;
let pool = create_smart_pool(&database_url).await?;
```
**Default Settings:**
- Max connections: 50
- Min connections: 10
- Connection timeout: 30s
- No connection tests (performance)
---
## Error Handling
### Centralized Error Type
```rust
use ormkit::OrmkitError;
match error {
OrmkitError::Database(sqlx::Error) => {
// Database connection or query error
}
OrmkitError::EntityNotFound => {
// No entity found for given ID
}
OrmkitError::Migration(MigrationError) => {
// Migration failed
}
OrmkitError::Validation(SchemaValidationError) => {
// Schema validation failed
}
OrmkitError::Transaction(TransactionError) => {
// Transaction failed
}
_ => {}
}
```
### Retryable Errors
Check if an error is transient:
```rust
if error.is_retryable() {
// Retry with backoff
}
```
**Retryable errors:**
- Connection failures
- Serialization failures (with retry logic)
- Timeout errors
### Error Categories
```rust
let category = error.category(); // "database", "validation", "migration", etc.
// Use for logging/metrics
```
---
## Platform Requirements
### Database
- **PostgreSQL**: 12, 13, 14, 15, 16
- **Extensions**: None required (uuid-gen for UUID defaults)
### Rust
- **Minimum Supported Rust Version (MSRV)**: 1.70
- **Edition**: 2021
### Runtime
- **Tokio**: 1.x with `multi-thread` scheduler
- **TLS**: rustls (default) or native-tls
---
## Operational Guidelines
### Connection Pooling
```rust
use sqlx::postgres::PgPoolOptions;
let pool = PgPoolOptions::new()
.max_connections(50)
.min_connections(10)
.connect(&database_url)
.await?;
```
**Guidelines:**
- Start with 10-20 connections
- Increase based on workload
- Monitor connection wait times
- Use connection pooling in production
### Monitoring
Key metrics to track:
1. **Query latency**: p50, p95, p99
2. **Connection pool utilization**
3. **Cache hit rates** (if using caching)
4. **Transaction retry rates** (serializable isolation)
5. **Migration execution time**
### Backup Strategy
1. **Database dumps**: Use `pg_dump` for backups
2. **Migration tracking**: Ormkit tracks applied migrations
3. **Rollback planning**: Test rollback procedures
### Deployment Checklist
- [ ] Enable appropriate feature flags
- [ ] Set connection pool size
- [ ] Configure cache settings (if using)
- [ ] Run migrations in deployment script
- [ ] Enable schema validation in staging
- [ ] Monitor query performance
- [ ] Set up error tracking
- [ ] Test rollback procedures
---
## Performance Tuning
### When to Use Caching
**Use caching for:**
- Read-heavy workloads
- Repeated queries with same parameters
- User session lookups
- Configuration data
**Avoid caching for:**
- Write-heavy workloads
- Real-time data
- Frequently changing data
- Large result sets
### When to Use Parallel Execution
**Use parallel for:**
- Bulk imports
- Batch reporting
- Background jobs
**Avoid parallel for:**
- User-facing requests (latency)
- Small batches (< 10 items)
- Already-fast queries
### Query Optimization
1. **Use indexes**: Ensure filtered columns are indexed
2. **Avoid N+1**: Use eager loading for relationships
3. **Limit result sets**: Use pagination
4. **Select specific columns**: Avoid `SELECT *`
5. **Use explain**: Analyze query plans
---
## Next Steps
- **Core ORM**: See [CORE_GUIDE.md](CORE_GUIDE.md)
- **Performance**: See [PERFORMANCE_OPTIMIZATIONS.md](PERFORMANCE_OPTIMIZATIONS.md)
- **Error Handling**: See [ERROR_HANDLING.md](ERROR_HANDLING.md)
---
**Need help?**
- Check [Platform Requirements](#platform-requirements)
- Review [Operational Guidelines](#operational-guidelines)