ICC Rule Engine with JSON-based rules management, deployed on Render with Supabase PostgreSQL.
-
Set Environment Variable
export DATABASE_URL="your-supabase-postgres-connection-string"
-
Install Dependencies
pip install -r requirements.txt
-
Apply Database Migrations
alembic upgrade head
-
Seed Sample Rules (Optional)
python seed_rules.py
-
Seed Commercial Demo Data (Optional)
python scripts/seed_commercial_data.py
-
Run Locally
uvicorn app.main:app --reload --port 8000
A lightweight React-based admin dashboard is available for system management and monitoring.
-
Navigate to admin directory
cd admin -
Install dependencies
npm install
-
Configure environment
cp .env.local.example .env.local # Edit .env.local with your backend URL and admin API key -
Start admin dashboard
npm run dev
Dashboard available at: http://localhost:3001
- Dashboard: System health, metrics, and activity monitoring
- Rules Management: CRUD operations with JSON editor and bulk upload
- Validation Logs: Search and view validation history (coming soon)
- System Settings: Feature flags and configuration (coming soon)
For detailed setup and deployment instructions, see admin/README.md.
- Hash Chaining: Each validation log entry includes a SHA-256 hash computed from log content and previous hash
- Integrity Verification:
/admin/logs/verify-integrityendpoint validates hash chain - Forensic Ready: Complete audit trail suitable for regulatory examination
- Configurable Retention:
LOG_RETENTION_DAYSenvironment variable (default: 90 days) - Automated Purging:
scripts/purge_old_logs.pyfor scheduled cleanup - Compliance Export: Automatic backup before purging for regulatory requirements
- Per-API-Key Limits:
RATE_LIMIT_REQUESTSperRATE_LIMIT_WINDOW(default: 100/minute) - Sliding Window: Efficient in-memory rate limiting with automatic cleanup
- Security Headers: Response includes rate limit status headers
- Seed Data:
scripts/seed_staging.pyloads comprehensive ICC rule set - Test Rules: 20+ UCP600 and ISBP 745 rules for validation testing
- Mixed Types: Both deterministic and LLM-assisted rules included
GET /admin/logs/{id} # Get tamper-evident log entry
GET /admin/logs/verify-integrity # Verify hash chain integrity
GET /admin/audit-report # Generate compliance report
GET /admin/rate-limiting/status # Rate limiting statisticspython scripts/export_docs.py # Generate pilot release PDF
python scripts/export_docs.py --all # Export all documentationGET /health- Returns{"status": "ok"}
GET /rules- List all rules (with filters: source, article, severity, tag)GET /rules/{rule_id}- Get a specific rulePOST /rules- Create a new rulePUT /rules/{rule_id}- Update a ruleDELETE /rules/{rule_id}- Delete a rule
POST /validate- Validate a document against ICC rules
POST /jobs/validate- Create async validation jobGET /jobs/{job_id}- Get job status and resultsDELETE /jobs/{job_id}- Cancel pending jobGET /jobs/- List jobs for current tenantGET /jobs/queue/stats- Get queue statistics
GET /usage/summary- Usage summary for current tenantGET /usage/billing- Detailed billing data with cost calculationGET /usage/tenants- All tenants usage (admin only)
GET /metrics/- Metrics summaryGET /metrics/prometheus- Prometheus format metricsGET /metrics/health- Metrics health check
Create a new rule:
curl -X POST "http://localhost:8000/rules" \
-H "Content-Type: application/json" \
-d '{
"source": "UCP600",
"rule_id": "UCP600_TEST",
"article": "14",
"title": "Test Rule",
"text": "This is a test rule for validation.",
"condition": {
"document_type": "letter_of_credit",
"test_field": "test_value"
},
"expected_outcome": {
"action": "validate",
"result": "compliant"
},
"tags": ["test", "validation"],
"severity": "medium"
}'List rules:
curl "http://localhost:8000/rules"
curl "http://localhost:8000/rules?source=UCP600&severity=critical"Validate a document:
curl -X POST "http://localhost:8000/validate" \
-H "Content-Type: application/json" \
-d '{
"document": {
"id": "LC-001",
"document_type": "letter_of_credit",
"examination_criteria": "documents_alone",
"compliance_check": "face_value_compliance",
"presentation_status": "complying",
"bank_role": "issuing_bank"
},
"ruleset": {
"source": "UCP600"
}
}'Example validation response:
{
"ok": false,
"score": 0.67,
"can_proceed": false,
"violations": [
{
"rule_id": "UCP600_16D",
"condition_type": "equality_match",
"details": {
"left_path": "presentation_status",
"actual_value": "complying",
"right_value": "non_complying",
"matches": false
}
}
],
"applied_rules": ["UCP600_14A", "UCP600_16A", "UCP600_16D"],
"logs_id": "12345678-1234-1234-1234-123456789abc"
}The validation engine supports deterministic JSON-based condition evaluators with 8 condition types:
- field_presence - Check if a field exists in the document
- equality_match - Compare field value to expected value
- numeric_range - Validate numeric values within min/max range
- date_order - Ensure proper chronological order between dates
- enum_value - Validate field value against allowed options
- time_constraint - Check deadline constraints with buffer days
- doc_required - Verify required documents are present
- consistency_check - Ensure matching values between fields
{
"type": "numeric_range",
"path": "credit_amount",
"min": 10000,
"max": 1000000
}{
"type": "doc_required",
"doc_name": "commercial_invoice",
"documents_path": "documents"
}The validation system supports both deterministic and LLM-assisted rule evaluation:
To enable LLM-assisted validation:
-
Set Environment Variable
export OPENAI_API_KEY="your-openai-api-key"
-
Rule Configuration Rules with
requires_llm: truewill use GPT-based evaluation:{ "source": "UCP600", "rule_id": "UCP600-17-appearance", "article": "17", "title": "Document Appearance", "text": "Documents must not be inconsistent on their face.", "requires_llm": true, "deterministic": false, "severity": "medium" }
Example response showing both deterministic and LLM-based violations:
{
"ok": false,
"score": 0.85,
"can_proceed": true,
"violations": [
{
"rule_id": "UCP600-17-appearance",
"condition_type": "llm_check",
"details": {
"reason": "Documents contained inconsistent dates",
"model": "gpt-3.5-turbo"
},
"llm_based": true
},
{
"rule_id": "UCP600_14A",
"condition_type": "equality_match",
"details": {
"left_path": "document_type",
"actual_value": null,
"right_value": "letter_of_credit",
"matches": false
},
"llm_based": false
}
],
"applied_rules": ["UCP600-17-appearance", "UCP600_14A"],
"logs_id": "uuid-here"
}- Graceful Degradation: System works without
OPENAI_API_KEY- LLM rules are skipped - Deterministic Priority: Deterministic rules always take priority for consistent validation
- Probabilistic Results: LLM results are probabilistic and should be reviewed
- Cost Consideration: LLM calls have API costs - use judiciously
- FastAPI - Web framework with async support for LLM calls
- SQLAlchemy - Database ORM with PostgreSQL-specific features
- Supabase - PostgreSQL database with UUID, JSONB, arrays
- Alembic - Database migrations
- OpenAI API - GPT-based rule evaluation for interpretive checks
- Render - Deployment platform
The rules table supports:
- UUID primary keys
- JSONB for flexible condition/outcome storage
- PostgreSQL arrays for tags
- Full-text search capabilities
- Optimized indexes
The system includes comprehensive monitoring capabilities:
# Get metrics summary
curl "http://localhost:8000/metrics/"
# Get Prometheus format metrics
curl "http://localhost:8000/metrics/prometheus"
# Check metrics health
curl "http://localhost:8000/metrics/health"- validation_count_total - Total validations by result and source
- webhook_count_total - Webhook delivery attempts by status
- rule_cache_count_total - Cache operations by type (hit/miss/invalidation)
- validation_duration_seconds - Validation processing time histogram
# Enable/disable metrics (default: true)
export METRICS_ENABLED="true"
# Enable/disable structured logging (default: true)
export LOGGING_ENABLED="true"JSON-formatted logs with request tracking:
{
"timestamp": "2024-01-15T10:30:00Z",
"level": "INFO",
"message": "Validation completed",
"request_id": "12345678-1234-1234-1234-123456789abc",
"latency": 0.245,
"method": "POST",
"path": "/validate",
"status_code": 200,
"validation": {
"result": "failed",
"score": 0.67,
"violations_count": 2,
"applied_rules_count": 3
}
}# Install test dependencies
pip install pytest pytest-cov pytest-asyncio httpx
# Run all tests
pytest
# Run tests with coverage
pytest --cov=app --cov-report=html --cov-fail-under=80
# Run specific test categories
pytest tests/test_validation.py
pytest tests/test_cache.pyAutomated pipeline includes:
- Testing: pytest with 80% coverage requirement
- Type Checking: mypy static analysis (optional)
- Security: Bandit security scanning + Safety vulnerability checks
- PostgreSQL: Full database integration testing
Configure secrets in GitHub:
CODECOV_TOKEN- For coverage reporting
Generate comprehensive API documentation:
# Generate OpenAPI JSON/YAML and Swagger UI
python scripts/generate_openapi.py
# Files created:
# - docs/api/openapi.json
# - docs/api/openapi.yaml
# - docs/api/index.html (Swagger UI)Export ready-to-use Postman collection:
# Generate Postman collection with examples
python scripts/export_postman.py
# Files created:
# - docs/api/postman_collection.json
# - docs/api/postman_environment.json# Install from PyPI
pip install icc-rule-engine-sdk
# Usage
from icc_rule_engine import ICCRuleEngineClient
client = ICCRuleEngineClient(
base_url="https://your-api.onrender.com",
api_key="your-api-key"
)
# Validate document
result = client.validate_document(
document={"id": "LC_001", "document_type": "letter_of_credit"},
ruleset={"source": "UCP600"}
)
print(f"Validation: {result.ok}, Score: {result.score}")Features:
- Full type safety with Pydantic models
- Async support with
AsyncICCRuleEngineClient - Automatic retries with exponential backoff
- Comprehensive error handling
- Rate limit handling
# Install from npm
npm install icc-rule-engine-sdkimport { ICCRuleEngineClient } from 'icc-rule-engine-sdk';
const client = new ICCRuleEngineClient({
baseURL: 'https://your-api.onrender.com',
apiKey: 'your-api-key'
});
// Type-safe validation
const result = await client.validateDocument(
{ id: 'LC_001', document_type: 'letter_of_credit' },
{ source: 'UCP600' }
);
console.log(`Validation: ${result.ok}, Score: ${result.score}`);Features:
- Full TypeScript support
- Promise-based async API
- Automatic retries and error handling
- Browser and Node.js compatibility
- Comprehensive error types
- Python SDK: sdks/python/README.md
- JavaScript SDK: sdks/js/README.md
- FastAPI - Web framework with async support for LLM calls
- SQLAlchemy - Database ORM with PostgreSQL-specific features
- Supabase - PostgreSQL database with UUID, JSONB, arrays
- Alembic - Database migrations
- Redis - Caching layer with fallback to database
- Prometheus - Metrics collection and monitoring
- OpenAI API - GPT-based rule evaluation for interpretive checks
- Render - Deployment platform
- Structured Logging - JSON logs with request correlation
- Prometheus Metrics - Performance and business metrics
- Health Checks - Service and dependency monitoring
- Error Tracking - Comprehensive error logging
- GitHub Actions - CI/CD pipeline with testing and security
- pytest - Testing framework with coverage reporting
- mypy - Static type checking
- Bandit/Safety - Security and vulnerability scanning
The rules table supports:
- UUID primary keys
- JSONB for flexible condition/outcome storage
- PostgreSQL arrays for tags
- Full-text search capabilities
- Optimized indexes
The system includes API key authentication:
# Set API key header
curl -H "X-API-Key: your-api-key" "http://localhost:8000/rules"Configure authentication:
export API_KEYS="key1,key2,key3" # Comma-separated listThe ICC Rule Engine supports secure multi-tenant architecture with complete data isolation:
Enable multi-tenant mode:
export MULTI_TENANT_ENABLED="true"
export DATABASE_URL="your-supabase-postgres-connection-string"Each tenant has:
- Unique tenant ID and API keys
- Isolated data (rules, validation logs, usage data)
- Billing plan configuration (basic, professional, enterprise)
- Usage quotas and rate limiting
In multi-tenant mode, API keys are associated with specific tenants:
# Use tenant-specific API key
curl -H "X-API-Key: global_bank_ltd_key_1_2024" \
"http://localhost:8000/rules"All data is automatically isolated by tenant:
- Rules are scoped to tenant
- Validation logs are tenant-specific
- Usage analytics are per-tenant
- No cross-tenant data access possible
Comprehensive usage tracking for SaaS billing and analytics:
Enable usage logging:
export USAGE_LOGGING_ENABLED="true"
export MULTI_TENANT_ENABLED="true" # Required for tenant attributionThe system automatically tracks:
- API Calls: Request count by endpoint and method
- Data Transfer: Request/response payload sizes
- Execution Time: Processing duration per request
- Token Usage: LLM token consumption for AI-assisted validation
- Rules Executed: Number of rules processed per validation
- Error Rates: Success/failure rates by tenant and endpoint
Access billing data via REST APIs:
# Usage summary for current tenant
curl -H "X-API-Key: your-tenant-api-key" \
"http://localhost:8000/usage/summary?days=30"
# Detailed billing data
curl -H "X-API-Key: your-tenant-api-key" \
"http://localhost:8000/usage/billing?start_date=2024-01-01&end_date=2024-01-31"
# Admin: All tenants usage (requires admin key)
curl -H "X-API-Key: admin-api-key" \
"http://localhost:8000/usage/tenants"{
"tenant_id": "global-bank-ltd",
"period": {
"start_date": "2024-01-01",
"end_date": "2024-01-31"
},
"usage": {
"total_requests": 15420,
"total_data_transfer_mb": 125.8,
"total_execution_time_hours": 2.45,
"total_tokens_used": 45230,
"total_rules_executed": 78650
},
"billing_by_endpoint": {
"/validate": {
"requests": 12400,
"avg_execution_time": 0.8,
"data_transfer_mb": 98.2,
"tokens_used": 42100
},
"/validate/batch": {
"requests": 120,
"avg_execution_time": 4.2,
"data_transfer_mb": 18.4,
"tokens_used": 3130
}
},
"cost_calculation": {
"api_calls_cost": 154.20,
"data_transfer_cost": 12.58,
"token_usage_cost": 45.23,
"total_cost": 212.01
}
}Background job processing for high-throughput validation:
Enable async validation:
export ASYNC_VALIDATION_ENABLED="true"
export REDIS_URL="redis://localhost:6379" # Optional: Redis for productionSubmit validation jobs for background processing:
# Create async validation job
curl -X POST "http://localhost:8000/jobs/validate" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"document": {
"id": "LC-001",
"document_type": "letter_of_credit",
"large_field": "very-large-document-content..."
},
"ruleset": {"source": "UCP600"}
}'
# Response: {"job_id": "uuid-here", "status": "queued"}Monitor job progress and retrieve results:
# Check job status
curl -H "X-API-Key: your-api-key" \
"http://localhost:8000/jobs/{job_id}"
# Cancel pending job
curl -X DELETE -H "X-API-Key: your-api-key" \
"http://localhost:8000/jobs/{job_id}"
# Queue statistics
curl -H "X-API-Key: your-api-key" \
"http://localhost:8000/jobs/queue/stats"Pending Job:
{
"job_id": "uuid-here",
"status": "pending",
"created_at": "2024-01-15T10:30:00Z"
}Completed Job:
{
"job_id": "uuid-here",
"status": "completed",
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:05Z",
"completed_at": "2024-01-15T10:32:15Z",
"processing_time_seconds": 130.5,
"result": {
"ok": true,
"score": 0.95,
"violations": [],
"applied_rules": ["UCP600_14A", "UCP600_16A"]
}
}- Redis + RQ: Production-ready distributed queue
- In-Memory: Development fallback with threading
- Worker Scaling: Horizontal scaling with multiple worker processes
- Job Persistence: Reliable job storage and recovery
Generate realistic demo data for showcasing commercial features:
# Seed commercial demo data
python scripts/seed_commercial_data.pyThis creates:
- 4 demo tenants (Global Bank, Regional Credit Union, Fintech Solutions, Demo Sandbox)
- 8-12 API keys across tenants
- 90 days of realistic usage logs for billing demonstration
After seeding, test with demo keys:
global_bank_ltd_key_1_2024- Enterprise tenantregional_credit_union_key_1_2024- Professional tenantfintech_solutions_inc_key_1_2024- Basic tenantdemo_bank_(sandbox)_key_1_2024- Sandbox tenant
Complete configuration for commercial deployment:
# Core Features
export DATABASE_URL="your-supabase-postgres-connection-string"
export OPENAI_API_KEY="your-openai-api-key"
# Commercial Features
export MULTI_TENANT_ENABLED="true"
export USAGE_LOGGING_ENABLED="true"
export ASYNC_VALIDATION_ENABLED="true"
# Infrastructure
export REDIS_URL="redis://localhost:6379"
export PORT="8000"
# Monitoring
export METRICS_ENABLED="true"
export LOGGING_ENABLED="true"-
Database Setup
- Apply migrations:
alembic upgrade head - Seed demo data:
python scripts/seed_commercial_data.py
- Apply migrations:
-
Infrastructure
- Deploy Redis for job queue
- Configure environment variables
- Set up worker processes for background jobs
-
Monitoring
- Configure Prometheus metrics collection
- Set up log aggregation
- Monitor usage analytics and billing data
-
Security
- Generate secure tenant API keys
- Configure rate limiting per tenant plan
- Set up backup and disaster recovery
The system supports usage-based billing with the following metrics:
- API Calls: $0.01 per validation request
- Data Transfer: $0.10 per MB transferred
- Token Usage: $0.001 per LLM token consumed
- Storage: $0.05 per GB of rules and logs stored per month
Plans include quotas and rate limits:
- Basic: 1,000 calls/month, 100 MB transfer, 10,000 tokens
- Professional: 10,000 calls/month, 1 GB transfer, 100,000 tokens
- Enterprise: Unlimited with custom pricing