backbone-events 0.5.1

Events core + the sale/booth/crm/sms/desk overlay — registrations under one authoritative seat counter, the sale seam (order-minted registrations, forward-only paid heal, SO-cancel mirror cascade), booth bookings with the DB exclusivity wall, closed-vocabulary lead rules through a host sink port, the dual-channel (mail/sms) self-arming scheduler, and the exact-match desk verb (Odoo event port, core + overlay)
# Codegen policy for event (crate backbone-events).
#
# `user_owned` globs are hand-written files that live inside generator-owned
# trees but are NOT schema-derived. `metaphor schema generate [--force]`
# skips them wholesale (never reads, merges, or deletes them). Everything
# else in src/ is regenerated from schema/models.
#
# Re-exports/declarations that must sit alongside generated code live inside
# `// <<< CUSTOM ... // END CUSTOM` markers (lib.rs, application/service/
# mod.rs, exports/services.rs) and are preserved by the marker mechanism,
# not listed here.
#
# Declared BEFORE any file lands (the regen-safety contract): a landing
# without the declaration is clobbered on the next regen; a declaration
# without the file is the dangling class removed by review — later seats
# extend this list on the same contract, declaring each hand file in the
# same change that lands it.

user_owned:
  # The shared-audit-trail funnel (hand-written; replaces this module's
  # retired per-module audit table).
  - "src/infrastructure/persistence/audit.rs"

  # Hand-written files the audit found undeclared; declared so a schema
  # regeneration cannot delete them.
  - "src/module.rs"


  # The module's typed error surface (one enum, HTTP mappings) — shared by
  # every hand service below.
  - "src/application/service/event_error.rs"

  # THE ONE seat aggregation service (EBB-1/EVM-3 replaced): state IN
  # open,done AND active; 0 cap = unlimited; multi-slot x
  # event_slot_count. The ONLY seat counter in the module — a second
  # counter anywhere is the frozen W8 seam refusal.
  - "src/application/service/seat_service.rs"

  # The registration verbs: the ONE register verb (lock-first,
  # count-then-insert, one transaction — SELECT ... FOR UPDATE on the
  # event row, slot row too when multi-slot, INSIDE the verb), the four
  # one-liner state verbs (arm rule: entering open arms the after_sub
  # engines; re-confirm never re-arms), sync_from_partner (fill-only-
  # when-empty), archive.
  - "src/application/service/registration_service.rs"

  # Event verbs: create (template-apply, once, never re-propagates), the
  # typed patch whitelist (is_published/date_publish refused — the fence),
  # publish/unpublish (the ONLY writers of the pair), mark_done (writes
  # the first pipe_end stage by sequence), the daily done sweep verb
  # (bounded batches, FOR UPDATE SKIP LOCKED claims, drives mark_done).
  - "src/application/service/event_service.rs"

  # Tier A capability tokens (ADR-0018): HMAC-SHA256, purpose-separated
  # ("event-ics-access" expiry+rotation default; the my_tickets
  # "event-registration-ticket-report-access" never-expiring DEVIATION
  # documented at the mint), constant-time verify, fail-closed secret.
  - "src/application/service/capability.rs"

  # The /ics body builder + publication gate (uniform typed 404 for
  # unpublished/archived/missing — no oracle; optionally slot-scoped under
  # the SAME token).
  - "src/application/service/ics_service.rs"

  # The attendee ticket/badge read (responsive payloads over the API; the
  # webapp renders).
  - "src/application/service/my_tickets_service.rs"

  # The guarded intake executor (the W8 funnel contract): typed field
  # allowlist at parse (deny_unknown_fields; identity/authority columns
  # NEVER admitted — no partner_id, no state, no sale_*, no active), no
  # partner minting, per-identity AND per-IP fixed windows, then the ONE
  # register verb.
  - "src/application/service/intake_service.rs"

  # The self-arming scheduler pass (ADR-0020): claim with FOR UPDATE SKIP
  # LOCKED, the three engines off one row (after_sub receipts / slot
  # fan-out / event cursor), receipt-truth completion (late registrants
  # re-open), 'sent'=queued at enqueue, commit_per_batch with
  # re-arm on overflow, typed per-scheduler failures (record ->
  # continue), visible window-closed drops.
  - "src/application/service/scheduler_service.rs"

  # The template seam port (EVM2-2 closed): host-installed
  # EventTemplateRenderer + the refusing default (unwired = typed
  # template_renderer_not_composed, never a silent skip, never a
  # registration blocker).
  - "src/application/service/template_port.rs"

  # The exported trait surface (seat availability, publication state, the
  # guarded intake verb, the split's state+sale_status pair read,
  # capability minting, the scheduler run verb) — the W8 seam contract.
  - "src/application/service/event_surface.rs"

  # The sale-order intake seam: exactly-once delivery claims through the
  # seam inbox (consumer, external_id), the mint fork (zero grand total
  # -> born open + armed; non-zero -> born draft held (sale, to_pay)),
  # the forward-only paid heal (draft/cancel + to_pay -> open + sold +
  # armed; sale_status KEPT on the cancel mirror), the one-way booth
  # paid latch. The producer side (sale outbox) is host-owned.
  - "src/application/service/sale_seam_service.rs"

  # Booth verbs: create/patch (state, sale link, is_paid, event refused
  # at patch), the confirm/release pair (release is the ONLY path back
  # to available and stays human — SO-cancel never frees a booth), the
  # typed delete fences (booking rows -> release first; sale link ->
  # refused outright), booking lifecycle with the EBS-1 partial-unique
  # wall surfaced as a typed 409 with the losing intent kept pending.
  - "src/application/service/booth_command_service.rs"

  # The typed lead-rule surface: the CLOSED predicate vocabulary
  # (event / event_type / company / question_answer — stored domains
  # banned; deny_unknown_fields DTOs), the answer-to-rule bridge, the
  # rule read model (both grouping grains), and the merge-relink verb
  # the host lead side calls.
  - "src/application/service/lead_command_service.rs"

  # The self-arming lead queue pass: claim with FOR UPDATE SKIP LOCKED,
  # set-based eligible-registration walks (provenance anti-join, batch
  # caps), grouping as STRATEGY (per_order for sale-linked,
  # per_event_day for walk-ins), group create-vs-grow through the host
  # sink, LOUD park on sink refusal (done stays false).
  - "src/application/service/lead_generation_service.rs"

  # The host lead sink port (create-lead / update-lead per group) + the
  # refusing default (unwired host = typed park reason, never a silent
  # skip). Provenance rows live here; the host lead schema is untouched.
  - "src/application/service/lead_sink.rs"

  # The host SMS queue port + the refusing default (unconfigured
  # gateway = sms_enqueue_refused recorded, receipt unsent, row parked
  # loudly — ESM-2). Rides the scheduler's channel branch, never the
  # mail queue.
  - "src/application/service/sms_port.rs"

  # The desk scan verb (EBT-3): the FROZEN branch order — invalid ->
  # canceled -> unconfirmed (no write) -> not-ongoing -> cross-event
  # manual confirmation (no write) -> already-registered -> the ONE
  # write (done through the transition verb). Barcode is EXACT-MATCH
  # over the globally-unique column; the nomenclature machinery stays
  # fenced out (register row).
  - "src/application/service/desk_service.rs"

  # The composer-installed request-pool shim the verb repositories resolve
  # their database through (ADR-0029 pool law): hand-written, never
  # schema-derived.
  - "src/request_pool.rs"

  # Hand repositories carrying the transactional SQL the services compose
  # (services hold no raw sqlx — the DDD boundary): the seat-lock
  # registration transaction (lock -> count -> insert -> arm), the
  # event verbs (create + one template-apply, fence-exempt patch,
  # publish/unpublish/mark_done; separate filename — the generated
  # CRUD event_repository.rs keeps its own path), and the scheduler's
  # SKIP LOCKED claims + receipt fan-out + receipt-truth completion.
  - "src/infrastructure/persistence/seat_repository.rs"
  - "src/infrastructure/persistence/event_command_repository.rs"
  - "src/infrastructure/persistence/scheduler_repository.rs"

  # Overlay hand repositories (same DDD boundary): the seam inbox
  # claims + mint/heal/cancel-mirror SQL + booth paid latch; the booth
  # verb SQL (confirm five-write, release, delete fences, the EBS-1
  # pre-check demoted to nice-error under the real partial unique
  # index); the lead-rule/predicate CRUD (typed rows, no stored
  # domains), the self-arming request queue (SKIP LOCKED), the
  # eligible-registration conjunctive SQL composed from typed
  # predicates, provenance upsert/junction (idempotent), relink, and
  # the events-owned catalog exclusion read.
  - "src/infrastructure/persistence/sale_seam_repository.rs"
  - "src/infrastructure/persistence/booth_command_repository.rs"
  - "src/infrastructure/persistence/lead_command_repository.rs"

  # The declared public capability tree (ics + my-tickets; the intake
  # verb's router rides here too — mounted by the host only when the W8
  # funnel arms). Mounted BARE of company_auth: the capability + throttle
  # are the fence.
  - "src/presentation/http/public_routes.rs"

  # The officer tree (events/registrations/mails + generated CRUD reads).
  # The host mounts it behind company_auth with the module-write gate
  # keyed "event" as the innermost route layer.
  - "src/presentation/http/admin_routes.rs"

  # GENERATOR-DEFECT FREEZE (the website-module pattern): the pinned
  # generator maps the `@default(now)` attribute to the datetime
  # sentinel even when the field's type is an ENUM whose variant is
  # literally named `now` (EventIntervalUnit::Now — the spec-frozen
  # upstream DB value). Two arms of the one defect, each frozen at its
  # generated state plus the one-line fix; unlist ONLY after the
  # generator fixes the attribute-to-type arm:
  #  - Rust entity builders: `self.interval_unit.unwrap_or(Utc::now())`
  #    (E0308 — expected EventIntervalUnit).
  #  - SQL table DDL: `DEFAULT NOW()` on an enum column (CREATE TABLE
  #    refuses: "default expression is of type timestamp with time
  #    zone"); the fix is the enum literal `DEFAULT 'now'`.
  - "src/domain/entity/mail.rs"
  - "src/domain/entity/type_mail.rs"
  - "migrations/20260426220005_create_mail_table.up.sql"
  - "migrations/20260426220017_create_type_mail_table.up.sql"

  # Hand-written DDL hardening: the EBG CHECK family (belonging, XOR,
  # date orders, slot hours, default-question-reusable, per-order cap),
  # the shared_blank RLS policies on events + registrations, the
  # EVM2-3/EBG-1 constraint polish, and the overlay hardening (the
  # EBS-1 partial unique exclusivity wall, the lead-rule/request
  # uniques, the seam inbox PK).
  - "migrations/*hardening*"

  # The ADR-0029 tenancy strip: drops the shared_blank policies and the
  # company_id columns under the ordering guard (decorator-first); the
  # composing service's tenancy decorator re-declares the fence.
  - "migrations/*strip_tenancy*"

  # Retirement of this module's own audit table: the audited facts moved to
  # the shared audit trail, so the per-module table and its closed vocabulary
  # go.
  - "migrations/*retire_event_audit_log*"

  # The event URL shape guarantee: an external event page must carry a scheme
  # and a host, the rule both the specification and the model description
  # already declared as a database CHECK.
  - "migrations/*event_url_scheme_check*"

  # GENERATOR-DEFECT FREEZE, second arm (same pattern as 20005/20017
  # above): the pinned generator numbers migration files alphabetically
  # by table name, which strands four FK constraints AHEAD of the
  # tables they reference (the referenced table's own migration file
  # sorts later). In each frozen file the stranded FK is hand-removed
  # and moved to the overlay hardening migration (20260426220040),
  # which runs after every overlay table exists. Unlist ONLY after the
  # generator learns dependency-ordered FK placement:
  #  - booth_bookings -> booths (table file sorts later at 20033)
  #  - lead_provenance_registrations -> lead_provenances (20035)
  #  - lead_provenances -> lead_rules (20038)
  #  - lead_rule_predicates -> lead_rules (20038)
  - "migrations/20260426220031_create_booth_booking_table.up.sql"
  - "migrations/20260426220031_create_booth_booking_table.down.sql"
  - "migrations/20260426220034_create_lead_provenance_registration_table.up.sql"
  - "migrations/20260426220034_create_lead_provenance_registration_table.down.sql"
  - "migrations/20260426220035_create_lead_provenance_table.up.sql"
  - "migrations/20260426220035_create_lead_provenance_table.down.sql"
  - "migrations/20260426220037_create_lead_rule_predicate_table.up.sql"
  - "migrations/20260426220037_create_lead_rule_predicate_table.down.sql"

  # Hand-authored module documentation (root docs + the frozen build
  # contract).
  - "README.md"
  - "SPEC.md"
  - "docs/**"

  # The fail-hard probe suite (fresh scratch DB on 5433,
  # EVENT_TEST_ADMIN_URL override; a missing scratch Postgres panics the
  # suite) — the concurrent-registration zero-oversell DoD probe, the
  # /ics refusal family, the receipt re-open probe, the arm-rule probe,
  # the EVM2-4 pair probe, the fence probes, mount introspection, the
  # overlay families (booth exclusivity, desk branches, the sale seam,
  # scheduler arming, sms overlay, transition-at-cap, CRM typed rules,
  # lead-pass exclusivity).
  - "tests/**"