The CouchDB Rules Engine uses CouchDB's built-in validate_doc_update functions to create a configurable, document-driven rules/validation system. Rules are authored as JavaScript modules, loaded into CouchDB as design documents, and executed server-side on every document write.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ-β
β Web Interface β
β (Vanilla JS, served by nginx) β
β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββ β
β β RuleList β βRuleEditorβ βRuleDetailβ βTestPanel β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ ββββ-β¬ββββ β
β ββββββββββββββββΌβββββββββββββΌββββββββββββββ β
β β couchdb-client.js β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββ
β REST API (HTTP)
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββ
β CouchDB Server β
β β
β βββββββββββββββββββββββββββββββββββββββ β
β β Design Documents β β
β β _design/householdIncome β β
β β _design/householdSize β β
β β _design/interviewComplete β β
β β _design/numberOfDependents β β
β β β β
β β Each contains: β β
β β - rule_metadata {} β β
β β - validate_doc_update (function) β β
β βββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββ β
β β Regular Documents β β
β β (validated on write by all rules) β β
β βββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Validation logic runs inside CouchDB itself via validate_doc_update functions in design documents. This means:
- Rules execute server-side on every document insert/update
- No middleware layer needed for validation
- Rules are stored alongside the data they validate
- Only the first validation failure is reported (CouchDB limitation)
- Functions execute in unspecified order
The web interface uses no frameworks β only plain JavaScript, HTML, and CSS. This keeps the project dependency-free on the frontend and aligns with the project's philosophy of simplicity and minimal dependencies.
Each rule is a standalone Node.js module in validators/ that exports a single validation function. The index.js file auto-discovers and re-exports all validators. This pattern makes it easy to add, remove, or test rules independently.
| File | Purpose |
|---|---|
config.js |
CouchDB connection settings (URL, credentials) from env vars or CLI args |
index.js |
Auto-discovers and re-exports all validator modules |
couchLoader.js |
Reads validators, wraps them as design docs, PUTs them into CouchDB |
couchUnloader.js |
DELETEs design documents for all validators from CouchDB |
validators/*.js |
Individual validation rule modules |
utils/rule-metadata.js |
Helpers for creating/validating rule metadata |
generators/rule-generator.js |
Scaffolds new validator + test files from templates |
scripts/create-rule.js |
CLI entry point for the rule generator |
| File | Purpose |
|---|---|
web/index.html |
Single-page application shell |
web/js/app.js |
Main application logic, routing, initialization |
web/js/components/RuleList.js |
Displays list of loaded rules |
web/js/components/RuleDetails.js |
Shows full rule metadata and source |
web/js/components/RuleEditor.js |
Create/edit rule UI |
web/js/components/TestPanel.js |
Test documents against loaded rules |
web/js/utils/couchdb-client.js |
Thin wrapper around CouchDB REST API |
web/js/utils/helpers.js |
Utility functions for the web UI |
web/css/main.css |
Core styles with CSS custom properties |
web/css/components.css |
Component-specific styles |
| File | Purpose |
|---|---|
docker-compose.yml |
CouchDB + web interface + initializer services |
Dockerfile.initializer |
Builds the one-shot container that loads rules on startup |
web/Dockerfile |
Builds the nginx-based web interface container |
setup.sh |
Legacy standalone Docker setup script |
| Directory | Purpose |
|---|---|
test/unit/validators/ |
Unit tests for each validation rule |
test/unit/utils/ |
Unit tests for utility modules |
test/integration/ |
Integration tests requiring a running CouchDB |
test/helpers/ |
Test utilities, mocks, and setup |
test/fixtures/ |
Sample documents and expected results |
validators/*.js β couchLoader.js β CouchDB design documents
(reads module, (_design/ruleName with
wraps as design validate_doc_update and
doc with metadata) rule_metadata)
Client writes document β CouchDB β Each _design/* validate_doc_update
runs against the document
β First failure returns 403 Forbidden
β All pass β document saved (201)
Browser β nginx (port 8080) β static HTML/JS/CSS
Browser β CouchDB REST API (port 5984) β rule CRUD + document operations
- Runtime: Node.js (backend CLI tools)
- Database: Apache CouchDB 3.5.x
- Testing: Mocha
- Web Server: nginx (containerized)
- Containerization: Docker / Docker Compose
- CI: GitHub Actions