PropFlow Events 1.0.0

The asynchronous contract of the PropFlow platform: every domain event, staged in a transactional outbox and relayed to RabbitMQ (transient fan-out) and Kafka (replayable history). Delivery is at-least-once — consumers dedupe on eventId. Narrative companion: docs/events.md; typed source of truth: libs/contracts.

Servers

  • amqp://rabbitmq:5672/amqprabbitmq

    Work distribution — topic exchange propflow.events.

  • kafka://kafka:9092/kafkakafka

    Audit stream — topic propflow.work-orders, keyed by workOrderId.

    Security:
    security.protocol:PLAINTEXT

Operations

  • SEND propflow.work-orders

    Every domain event, retained as a replayable log. Messages are keyed by workOrderId, so one aggregate's events stay ordered within a partition; a fresh consumer group at offset 0 rebuilds any projection.

    Work Orders service appends every domain event to the audit stream.

    Events are staged in the outbox_events table inside the same transaction as the state change (ADR-0007) and published by the outbox relay — the service never talks to a broker on the write path. The same relay also publishes each event to its RabbitMQ routing key.

    Operation IDpublishWorkOrderEvents

    Available only on servers:

    Accepts one of the following messages:

    • #0Work order created

      A maintenance request was opened.

      Message IDworkOrderCreated
      allOf

      Examples

    • #1Work order assigned

      A manager assigned (or reassigned) a technician.

      Message IDworkOrderAssigned
      allOf

      Examples

    • #2Work order started

      Status moved to in_progress.

      Message IDworkOrderStarted
      allOf

      Examples

    • #3Work order completed

      Status moved to completed.

      Message IDworkOrderCompleted
      allOf

      Examples

    • #4Work order cancelled

      Cancelled from any non-terminal state.

      Message IDworkOrderCancelled
      allOf

      Examples

    • #5Work order triaged

      The AI classification was applied (asynchronously, after created).

      Message IDworkOrderTriaged
      allOf

      Examples

  • RECEIVE work-order.created

    Notifications service alerts the property manager.

    Queue notifications.work-order-created. Failures retry via the TTL pattern (<queue>.retry, 5s, max 3 attempts) before parking in <queue>.dlq. Deduped by eventId in the processed-events store.

    Operation IDonWorkOrderCreatedNotify

    Available only on servers:

    object

    Accepts the following message:

    Work order created

    A maintenance request was opened.

    Message IDworkOrderCreated
    allOf

    Examples

  • RECEIVE work-order.created

    Work Orders service classifies the request with an LLM.

    Queue work-orders.triage. Best-effort — classification failures are skipped, never retried (ADR-0006). Applying a result emits work-order.triaged through the outbox. Idempotent via triaged_at.

    Operation IDonWorkOrderCreatedTriage

    Available only on servers:

    object

    Accepts the following message:

    Work order created

    A maintenance request was opened.

    Message IDworkOrderCreated
    allOf

    Examples

  • RECEIVE work-order.completed

    Notifications service alerts the tenant.

    Queue notifications.work-order-completed, same retry/DLQ and dedup semantics as the created consumer.

    Operation IDonWorkOrderCompletedNotify

    Available only on servers:

    object

    Accepts the following message:

    Work order completed

    Status moved to completed.

    Message IDworkOrderCompleted
    allOf

    Examples

  • RECEIVE propflow.work-orders

    Every domain event, retained as a replayable log. Messages are keyed by workOrderId, so one aggregate's events stay ordered within a partition; a fresh consumer group at offset 0 rebuilds any projection.

    Audit service projects the stream into the activity feed.

    Consumer group audit-service, reading from the beginning. Ingestion is idempotent by construction — INSERT … ON CONFLICT (event_id) DO NOTHING — so redeliveries and full replays are safe.

    Operation IDonAuditStream

    Available only on servers:

    Accepts one of the following messages:

    • #0Work order created

      A maintenance request was opened.

      Message IDworkOrderCreated
      allOf

      Examples

    • #1Work order assigned

      A manager assigned (or reassigned) a technician.

      Message IDworkOrderAssigned
      allOf

      Examples

    • #2Work order started

      Status moved to in_progress.

      Message IDworkOrderStarted
      allOf

      Examples

    • #3Work order completed

      Status moved to completed.

      Message IDworkOrderCompleted
      allOf

      Examples

    • #4Work order cancelled

      Cancelled from any non-terminal state.

      Message IDworkOrderCancelled
      allOf

      Examples

    • #5Work order triaged

      The AI classification was applied (asynchronously, after created).

      Message IDworkOrderTriaged
      allOf

      Examples

Messages

  • #1Work order created

    A maintenance request was opened.

    Message IDworkOrderCreated
    allOf
  • #2Work order assigned

    A manager assigned (or reassigned) a technician.

    Message IDworkOrderAssigned
    allOf
  • #3Work order started

    Status moved to in_progress.

    Message IDworkOrderStarted
    allOf
  • #4Work order completed

    Status moved to completed.

    Message IDworkOrderCompleted
    allOf
  • #5Work order cancelled

    Cancelled from any non-terminal state.

    Message IDworkOrderCancelled
    allOf
  • #6Work order triaged

    The AI classification was applied (asynchronously, after created).

    Message IDworkOrderTriaged
    allOf

Schemas

  • object

    Shared envelope of every domain event. eventId is the idempotency key consumers dedupe on.

  • object

    Full work-order snapshot at the time of the event.

  • object

    AI classification with closed vocabularies — the model is constrained to these enums via a JSON schema, so consumers can rely on them like any other contract enum.

  • allOf
  • allOf
  • allOf
  • allOf
  • allOf
  • allOf