architect/_archive/2025-11-13-before-restructure/platform-projects/projects/cifra/archive/2025-11-10-restructure-v2/EVENT_SYSTEM.md

CIFRA Event System

Версия: 1.0.0
Дата: 2025-11-10


Event Naming Convention

<domain>.<entity>.<action>

Examples:
- entity.Contact.created
- entity.Deal.stage_changed
- process.order_fulfillment.started
- user.login.success
- integration.stripe.payment_received

Emit Events

from cifra.events import event_bus

# Simple event
await event_bus.emit('entity.Contact.created', {
    'id': contact.id,
    'email': contact.email,
    'name': contact.name
})

# With priority (0-9, 9=highest)
await event_bus.emit('user.login.failed', {
    'user_id': user.id,
    'ip': request.client.host
}, priority=8)

Subscribe to Events

from cifra.events import subscribe

@subscribe('entity.Contact.created')
async def send_welcome_email(event):
    """Send welcome email when contact created"""
    contact = event.payload
    await email_service.send(
        to=contact['email'],
        template='welcome',
        data=contact
    )

# Subscribe with filter
@subscribe('entity.Deal.*', filter={'amount': {'$gt': 100000}})
async def notify_manager_large_deal(event):
    """Notify manager about large deals"""
    deal = event.payload
    await notify(f"Large deal: ${deal['amount']}")

# Wildcard subscriptions
@subscribe('entity.*.*')
async def log_all_entity_events(event):
    """Log all entity events"""
    logger.info(f"Event: {event.name}")

Event Structure

class Event:
    id: UUID
    name: str               # entity.Contact.created
    payload: dict           # Event data
    timestamp: datetime
    priority: int           # 0-9
    user_id: UUID | None   # Who triggered
    metadata: dict          # Additional info

Event Log (Persistence)

# All events stored in database
SELECT * FROM event_log
WHERE name = 'entity.Contact.created'
ORDER BY timestamp DESC;

# Replay events (восстановление состояния)
await event_bus.replay(
    from_time=datetime(2025, 11, 1),
    to_time=datetime(2025, 11, 10)
)

Use Cases

# 1. Audit Trail
@subscribe('entity.*.*')
async def audit_log(event):
    await AuditLog.create({
        'event': event.name,
        'user_id': event.user_id,
        'changes': event.payload
    })

# 2. Notifications
@subscribe('entity.Deal.stage_changed')
async def notify_on_deal_won(event):
    if event.payload['new_stage'] == 'won':
        await send_notification(...)

# 3. Integration
@subscribe('entity.Order.created')
async def send_to_fulfillment_system(event):
    await external_api.post('/orders', event.payload)

Документация: https://docs.cifra.io/events