Status: 📋 Contract frozen (implementation 📝 Planned — no production RPC until migrations ship)
Last Updated: 2026-04-26 Canonical integration reference for FA-18: revenue contracts, revenue schedules (invoice XOR contract source), deferred revenue, single fiscal period recognition runs, and GL posting via FA-02. Authoritative duplicates: Event payload is defined identically in EVENT_CONTRACTS.md § FA-18. HTTP shape (if used) is defined in API_CONTRACTS.md § FA-18. This file ties them together and documents GL line mapping and transport choice.
Integration Summary
Transport (frozen)
Callers must hold PF-30
fa.revenue_recognitions.process (or equivalent) in addition to tenant RLS.
RPC: fa_process_revenue_recognition
Signature (frozen):
- Select active
fa_revenue_schedulesforp_organization_idthat intersect the fiscal period identified byp_fiscal_period_id(viafa_fiscal_periods), haveremaining_to_recognize > 0, and satisfy date window rules per spec. - For each schedule, insert at most one
fa_revenue_recognitionsrow for(revenue_schedule_id, fiscal_period_id)(UNIQUE). - Update
fa_revenue_schedules.total_recognizedin the same transaction as the insert. - Phase 1 GL scope (DEFERRED): Do not call
fa_create_journal_entry()fromfa_process_revenue_recognition()in Phase 1. Recognition rows are written withjournal_entry_id IS NULLandjournal_entry_line_id IS NULL. A Phase 2 task will post GL via FA-02 and back-fill the linkage. This boundary keeps Phase 1 self-contained and decoupled from FA-02’s not-yet-frozen RPC signature. - Inserts MUST use
ON CONFLICT (revenue_schedule_id, fiscal_period_id) DO NOTHINGso the function is idempotent on retry.
schedule_ids?: uuid[], it MUST filter to those IDs within p_organization_id only; omitting the array means “all due schedules” for the period (same as RPC-only callers invoking for the whole org period batch).
Event: revenue_recognized
Publisher: FA (FA-18)Subscribers (planned): FA-02, FA-05, FA-13 Emit after a recognition row is committed (and ideally after GL post when GL is in scope for that run). Payload (frozen) — see EVENT_CONTRACTS.md:
HTTP: Recognize revenue (optional wrapper)
Endpoint:POST /api/v1/fa/revenue/recognizeLogical mapping: Body →
fa_process_revenue_recognition with p_user_id = auth.uid().
Request:
400 invalid body / unknown period; 403 tenant or permission; 422 schedule not eligible (closed period, zero remaining, etc.). Do not echo internal SQL.
GL mapping (FA-02)
Exact account resolution: FA-01 CoA + org policy; implementation calls FA-02’s standard journal entry API/RPC.
journal_entry_line_id SHOULD reference the credit revenue line (or documented pair) for audit trail per FA-18 spec clarifications.
Planned consumers (Phase 2)
invoice_sent(FA-05),contract_signed(FA-13) — auto-create schedules/contracts; not in Phase 1.