Examples¶
Production-scale reference applications demonstrating Verity patterns
The verity/examples/ directory contains full-stack applications that showcase Verity in realistic domains. Each example includes a baseline version that implements the same functionality without Verity, allowing direct comparison.
Quick Start¶
Run any example locally:
# Setup
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Run an example
python verity/examples/invoices_alpine/app.py
# Then open http://localhost:5000
Example Applications¶
1. Invoices (Alpine.js)¶
Domain: Invoice management with CRUD operations
Framework: Alpine.js
Complexity: ⭐ Beginner
Path: verity/examples/invoices_alpine/
What it demonstrates:
- ✅ Basic CRUD (Create, Read, Update, Delete)
- ✅ SSE-driven updates across tabs
- ✅ Skeleton states for initial loads
- ✅ Toast notifications without optimistic updates
- ✅ Collection filtering and parameters
Architecture:
graph TB
Browser[Browser<br/>Alpine.js + Verity]
Flask[Flask Backend<br/>SQLite]
SSE[SSE Stream<br/>/api/events]
Browser -->|GET /api/invoices| Flask
Browser -->|POST /api/invoices| Flask
Browser -->|PUT /api/invoices/:id| Flask
Browser -->|DELETE /api/invoices/:id| Flask
Flask -->|directives| Browser
Flask -->|emit| SSE
SSE -->|directives| Browser
style Browser fill:#e1ffe1
style Flask fill:#e1f5ff
style SSE fill:#fff4e1
Key Files:
app.py- Flask routes and directive emissionstatic/app.js- Alpine + Verity setuptemplates/index.html- UI with truth/view state separation
Run:
Compare with baseline:
python verity/examples/invoices_alpine_baseline/app.py
# Baseline: manual state management, no directives
Perfect for: Learning Verity basics, understanding directives
2. Financial Crime Case Management (Alpine.js)¶
Domain: Compliance case tracking and analyst workflow
Framework: Alpine.js
Complexity: ⭐⭐ Intermediate
Path: verity/examples/financial_crime_alpine/
What it demonstrates:
- ✅ Parameterized collections (cases by status, region, analyst)
- ✅ Desk assignment workflows
- ✅ Multi-user collaboration via SSE
- ✅ Role-based directive targeting
- ✅ Complex filtering and search
Architecture:
graph TB
subgraph "Multiple Analysts"
A1[Analyst A<br/>Browser]
A2[Analyst B<br/>Browser]
end
Backend[Flask Backend<br/>Case Management]
SSE[SSE Hub<br/>Audience Routing]
A1 -->|Assign case| Backend
A2 -->|View cases| Backend
Backend -->|directives<br/>audience: global| SSE
Backend -->|directives<br/>audience: user-A| SSE
SSE -->|filtered| A1
SSE -->|filtered| A2
style A1 fill:#e1ffe1
style A2 fill:#e1ffe1
style Backend fill:#e1f5ff
style SSE fill:#fff4e1
Key Patterns:
// Different analysts see different cases
registry.registerCollection('cases', {
fetch: async (params) => {
const url = new URL('/api/cases', location.origin)
if (params.status) url.searchParams.set('status', params.status)
if (params.analyst) url.searchParams.set('analyst', params.analyst)
if (params.region) url.searchParams.set('region', params.region)
const res = await fetch(url)
return res.json()
}
})
@app.put('/api/cases/<int:case_id>/assign')
def assign_case(case_id):
case = Case.query.get(case_id)
case.analyst_id = request.json['analyst_id']
db.session.commit()
directives = [
{ 'op': 'refresh_item', 'name': 'case', 'id': case_id },
# Refresh for both analysts
{ 'op': 'refresh_collection', 'name': 'cases',
'params': { 'analyst': old_analyst_id } },
{ 'op': 'refresh_collection', 'name': 'cases',
'params': { 'analyst': case.analyst_id } }
]
emit_directives(directives, audience='global')
return { 'directives': directives }
Run:
Compare with baseline:
Perfect for: Multi-user apps, parameterized queries, role-based access
3. Manufacturing Monitor (Multi-Framework)¶
Domain: Real-time factory floor monitoring
Frameworks: Alpine.js, React, Vue 3
Complexity: ⭐⭐⭐ Advanced
Paths:
verity/examples/manufacturing_monitor/(Alpine)verity/examples/manufacturing_monitor_react/(React)verity/examples/manufacturing_monitor_vue/(Vue)
What it demonstrates:
- ✅ Real-time data updates (every 3-5 seconds)
- ✅ Same backend, three different frontends
- ✅ Framework adapter consistency
- ✅ High-frequency SSE directives
- ✅ Complex nested state
Architecture:
graph TB
subgraph "Frontend Options"
Alpine[Alpine.js]
React[React]
Vue[Vue 3]
end
subgraph "Backend"
Flask[Flask API]
DB[(SQLite<br/>Machines)]
SSE[SSE Stream]
Sim[Simulator<br/>Background Thread]
end
Alpine <-->|fetch/directives| Flask
React <-->|fetch/directives| Flask
Vue <-->|fetch/directives| Flask
Flask <--> DB
Flask --> SSE
SSE --> Alpine
SSE --> React
SSE --> Vue
Sim -->|update machines| DB
Sim -->|emit directives| SSE
style Alpine fill:#e1ffe1
style React fill:#ffe1e1
style Vue fill:#e1f0ff
style Flask fill:#e1f5ff
style SSE fill:#fff4e1
Key Features:
# Background simulator
def simulate_machines():
while True:
time.sleep(random.uniform(3, 7))
# Random machine update
machine = random.choice(Machine.query.all())
machine.status = random.choice(['running', 'idle', 'maintenance'])
machine.temperature = random.randint(60, 95)
db.session.commit()
# Emit directive
emit_directives([
{ 'op': 'refresh_item', 'name': 'machine', 'id': machine.id },
{ 'op': 'refresh_collection', 'name': 'machines' }
], audience='global')
Alpine:
<div x-data="{ machines: $verity.collection('machines') }">
<template x-for="m in machines.state.items" :key="m.id">
<div x-text="m.name"></div>
</template>
</div>
React:
function MachineList() {
const { state } = useVerityCollection('machines')
return (
<div>
{state.items.map(m => (
<div key={m.id}>{m.name}</div>
))}
</div>
)
}
Vue:
Run:
Compare with baselines:
python verity/examples/manufacturing_monitor_alpine_baseline/app.py
python verity/examples/manufacturing_monitor_react_baseline/app.py
python verity/examples/manufacturing_monitor_vue_baseline/app.py
Perfect for: Real-time dashboards, framework comparison, SSE at scale
4. Telehealth Triage Hub¶
Domain: Emergency room patient triage and queue management
Framework: Alpine.js
Complexity: ⭐⭐⭐ Advanced
Path: verity/examples/telehealth_triage_hub/
What it demonstrates:
- ✅ Multi-queue workflows (waiting, in-progress, completed)
- ✅ Role-based directive audiences (triage nurses, doctors)
- ✅ Drag-and-drop with truth-state updates
- ✅ Critical/urgent priority handling
- ✅ Audit trail of state changes
Architecture:
graph TB
subgraph "Roles"
Nurse[Triage Nurse<br/>audience: nurse]
Doctor[Doctor<br/>audience: doctor]
Admin[Admin<br/>audience: admin]
end
subgraph "Backend"
API[Flask API]
Queue[(Patient Queue)]
SSE[SSE Hub<br/>Audience Router]
end
Nurse -->|Triage patient| API
Doctor -->|Assign to room| API
Admin -->|View all| API
API <--> Queue
API -->|directives + audience| SSE
SSE -->|nurse events| Nurse
SSE -->|doctor events| Doctor
SSE -->|admin events| Admin
style Nurse fill:#e1ffe1
style Doctor fill:#ffe1f0
style Admin fill:#f0e1ff
style API fill:#e1f5ff
style SSE fill:#fff4e1
Key Patterns:
@app.put('/api/patients/<int:patient_id>/triage')
def triage_patient(patient_id):
patient = Patient.query.get(patient_id)
patient.priority = request.json['priority']
patient.status = 'triaged'
db.session.commit()
directives = [
{ 'op': 'refresh_item', 'name': 'patient', 'id': patient_id },
{ 'op': 'refresh_collection', 'name': 'patients' }
]
# Nurses and doctors see update, patients don't
emit_directives(directives, audience='nurse')
emit_directives(directives, audience='doctor')
return { 'directives': directives }
// Nurse connects to nurse audience
const nurseRegistry = createRegistry({
sse: {
url: '/api/events',
audience: 'nurse' // Only receives nurse directives
}
})
// Doctor connects to doctor audience
const doctorRegistry = createRegistry({
sse: {
url: '/api/events',
audience: 'doctor' // Only receives doctor directives
}
})
Run:
Compare with baseline:
python verity/examples/telehealth_triage_hub_baseline/app.py
# Baseline: manual state sync, no role filtering
Perfect for: Multi-role apps, queue management, critical workflows
Example Comparison Matrix¶
| Feature | Invoices | Financial Crime | Manufacturing | Telehealth |
|---|---|---|---|---|
| Complexity | ⭐ Simple | ⭐⭐ Medium | ⭐⭐⭐ Complex | ⭐⭐⭐ Complex |
| CRUD | ✅ Full | ✅ Full | ✅ Read-heavy | ✅ Full |
| SSE | ✅ Basic | ✅ Advanced | ✅ High-freq | ✅ Advanced |
| Params | ✅ Basic | ✅ Complex | ✅ Basic | ✅ Complex |
| Multi-user | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
| Audiences | Global only | Global | Global | Role-based |
| Frameworks | Alpine | Alpine | Alpine/React/Vue | Alpine |
| Real-time | Low | Medium | High | High |
Common Patterns Across Examples¶
Pattern 1: Directive Response Structure¶
All examples follow this server pattern:
@app.post('/api/resource')
def create_resource():
# 1. Perform business logic
resource = Resource(...)
db.session.add(resource)
db.session.commit()
# 2. Define directives
directives = [
{ 'op': 'refresh_collection', 'name': 'resources' }
]
# 3. Emit to SSE (for other clients)
emit_directives(directives, audience='global')
# 4. Return to requesting client
return {
'resource': resource.to_dict(),
'directives': directives
}
Pattern 2: Client Registry Setup¶
All examples use similar client setup:
// Create registry
const registry = Verity.createRegistry({
sse: {
url: '/api/events',
audience: 'global' // or role-specific
},
memory: {
stalenessMs: 30000 // 30 seconds
}
})
// Register collections
registry.registerCollection('resources', {
fetch: async (params) => {
const res = await fetch('/api/resources')
return res.json()
}
})
// Install adapter (Alpine example)
VerityAlpine.install(window.Alpine, { registry })
Pattern 3: Mutation Helper¶
Most examples extract a mutation helper:
async function mutateResource(method, url, data) {
const res = await fetch(url, {
method,
headers: {
'Content-Type': 'application/json',
'X-Verity-Client-ID': registry.clientId
},
body: JSON.stringify(data)
})
const payload = await res.json()
if (payload.directives) {
await registry.applyDirectives(payload.directives)
}
return payload
}
Baseline Comparisons¶
Each example includes a baseline version that implements identical functionality without Verity. This allows direct comparison of:
- Lines of code
- Complexity
- Bug surface area
- Multi-client synchronization
Baseline differences:
| Aspect | With Verity | Baseline (Manual) |
|---|---|---|
| State management | Automatic (directives) | Manual (polling or WebSocket) |
| Caching | Built-in | Custom implementation |
| Multi-client sync | SSE directives | Manual broadcast logic |
| Staleness | Declarative (stalenessMs) |
Manual TTL tracking |
| Coalescing | Automatic | Manual request deduplication |
| Code volume | ~30-40% less | Baseline (100%) |
To compare:
- Run the Verity version
- Run the baseline version
- Open both in separate tabs
- Make changes in one tab
- Observe synchronization behavior
Running Examples¶
Prerequisites¶
# Python 3.8+
python --version
# Virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
Environment Variables¶
Some examples support environment variables:
# Change port
export PORT=8000
# Use in-memory SQLite
export DATABASE=:memory:
# Enable debug mode
export FLASK_DEBUG=1
Viewing with Devtools¶
Add devtools to any example:
- Open the example's
templates/index.html - Add before
</body>: - Reload the page
- Press
Ctrl+Shift+Dto open devtools
Learning Path¶
Recommended order:
- Start with Invoices (Alpine) - Learn Verity basics
- Try Manufacturing Monitor (Alpine) - See real-time updates
- Compare with baselines - Understand what Verity provides
- Explore Financial Crime - Learn parameterized collections
- Study Telehealth - Master role-based audiences
- Try other frameworks - React/Vue versions
Building Your Own Example¶
Want to create a new example? Follow this structure:
your_example/
├── app.py # Flask backend
├── templates/
│ └── index.html # Main page
├── static/
│ └── app.js # Verity setup + UI logic
├── README.md # Example-specific docs
└── requirements.txt # Python dependencies (if special)
Checklist:
- ✅ Use
create_shared_static_blueprint()for Verity assets - ✅ Implement SSE endpoint at
/api/events - ✅ Return directives from mutation endpoints
- ✅ Include both Verity and baseline versions
- ✅ Add architecture diagram to README
- ✅ Document key patterns
Troubleshooting Examples¶
Example won't start¶
# Check Python version
python --version # Should be 3.8+
# Reinstall dependencies
pip install -r requirements.txt --force-reinstall
# Check if port is in use
lsof -i :5000 # On macOS/Linux
SSE not working¶
-
Check if
/api/eventsendpoint is accessible: -
Open browser devtools → Network tab → Look for
/api/eventswith typeeventsource -
Check Verity devtools (
Ctrl+Shift+D) → SSE panel
Updates not appearing¶
- Open Verity devtools
- Check Events panel - Are directives arriving?
- Check Truth panel - Is cache updating?
- Check browser console for errors
Next Steps¶
- Study the code: Each example is fully commented
- Modify and experiment: Change parameters, add features
- Read the patterns: See UX Patterns
- Build your own: Use examples as templates
- Compare frameworks: See how adapters maintain consistency
Contributing Examples¶
Have an example to share? We'd love to see it!
Requirements:
- Real-world domain (not TODO app)
- Include baseline comparison
- Follow established patterns
- Document key learnings
- Add architecture diagram
Submit: Open a PR with your example in verity/examples/your_example/
See CONTRIBUTING.md for details.