Skip to content

feat: implement subscription event sourcing with full audit trail (#175) - #516

Merged
Smartdevs17 merged 2 commits into
Smartdevs17:mainfrom
Cyberking99:feat/175-event-sourcing-audit-trail
Jun 1, 2026
Merged

feat: implement subscription event sourcing with full audit trail (#175)#516
Smartdevs17 merged 2 commits into
Smartdevs17:mainfrom
Cyberking99:feat/175-event-sourcing-audit-trail

Conversation

@Cyberking99

@Cyberking99 Cyberking99 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Closes #175
Closes #170
Closes #169


Summary

Implements an event sourcing architecture that records every subscription state change as an immutable on-chain event, enabling full audit trails, regulatory compliance, and historical state reconstruction.

Changes

  • New module event_store.rs — Append-only event log with auto-incrementing event IDs, subscription-indexed lookups, merchant-level event export, and configurable retention policies
  • New module state.rs — reconstruct_state() replays events to rebuild subscription state without relying on stored state; supports point-in-time historical reconstruction
  • Enhanced events.rs — Added Charged/Downgraded event types, richer EventMetadata (timestamp, actor, ledger sequence), and EventFilter for querying
  • Lifecycle instrumentation — All 14 subscription state transitions now record a persistent event in addition to Soroban contract events
  • Error handling — New ContractError variants for event store operations
  • Retention policies — Configurable per-subscription event limits and auto-pruning

Acceptance Criteria

  • EventStore with append-only event log
  • Event types: Created, Charged, Paused, Resumed, Upgraded, Downgraded, Cancelled, etc.
  • Event serialization with metadata (timestamp, ledger sequence, actor)
  • State reconstruction from event history
  • Event querying with filters (by subscription, by type, by date range)
  • Event retention policy configuration
  • Event export for compliance reporting
  • Event sequence validation

- Add StoredEvent, EventFilter, EventRetentionPolicy, EventMetadata types
- Add Charged/Downgraded variants to SubscriptionEventType
- Implement EventStore with append-only event log using env.storage()
- Implement state reconstruction (current + point-in-time)
- Add event querying with filters (by subscription, by type, by date range)
- Add event export for compliance reporting
- Add configurable event retention policy with auto-pruning
- Add event-related error variants (EventNotFound, EventStoreFull, etc.)
- Instrument all lifecycle functions (subscribe, cancel, pause, resume,
  charge, refund, transfer, change_plan) to record events
- Event sequence validation for legal state machine transitions
@drips-wave

drips-wave Bot commented Jun 1, 2026

Copy link
Copy Markdown

@Cyberking99 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

…170 #169)

Billing Schedules (#170):
- Extend Interval enum with BiWeekly, BiMonthly, SemiAnnually, Custom(u64)
- Add BillingSchedule struct with trial, promo rate, custom invoice day support
- Add billing.rs module with next_billing, prorated_first_billing, preview
- Add schedule storage per subscription
- Add set/get_billing_schedule and get_billing_preview contract entry points

Multi-step Charging with Retry (#169):
- Add ChargeAttempt, ChargeStatus, RetryConfig types
- Add charging.rs module with state machine (Pending→Attempting→Retrying→Completed/Exhausted)
- Implement exponential backoff retry with configurable max retries
- Add circuit breaker pattern to pause after repeated failures
- Add charge history tracking per subscription
- Add start_charge, retry_charge, get_charge_history, abort_charge entry points

Fixes:
- Fix proration.rs to use Interval::Yearly (was Annually, non-existent variant)
@Smartdevs17
Smartdevs17 merged commit e62e1b4 into Smartdevs17:main Jun 1, 2026
4 of 28 checks passed
abimbolaalabi pushed a commit to abimbolaalabi/SubTrackr that referenced this pull request Jun 26, 2026
…artdevs17#175) (Smartdevs17#516)

* feat: implement subscription event sourcing with full audit trail (Smartdevs17#175)

- Add StoredEvent, EventFilter, EventRetentionPolicy, EventMetadata types
- Add Charged/Downgraded variants to SubscriptionEventType
- Implement EventStore with append-only event log using env.storage()
- Implement state reconstruction (current + point-in-time)
- Add event querying with filters (by subscription, by type, by date range)
- Add event export for compliance reporting
- Add configurable event retention policy with auto-pruning
- Add event-related error variants (EventNotFound, EventStoreFull, etc.)
- Instrument all lifecycle functions (subscribe, cancel, pause, resume,
  charge, refund, transfer, change_plan) to record events
- Event sequence validation for legal state machine transitions

* feat: implement billing schedules and multi-step charging with retry (Smartdevs17#170 Smartdevs17#169)

Billing Schedules (Smartdevs17#170):
- Extend Interval enum with BiWeekly, BiMonthly, SemiAnnually, Custom(u64)
- Add BillingSchedule struct with trial, promo rate, custom invoice day support
- Add billing.rs module with next_billing, prorated_first_billing, preview
- Add schedule storage per subscription
- Add set/get_billing_schedule and get_billing_preview contract entry points

Multi-step Charging with Retry (Smartdevs17#169):
- Add ChargeAttempt, ChargeStatus, RetryConfig types
- Add charging.rs module with state machine (Pending→Attempting→Retrying→Completed/Exhausted)
- Implement exponential backoff retry with configurable max retries
- Add circuit breaker pattern to pause after repeated failures
- Add charge history tracking per subscription
- Add start_charge, retry_charge, get_charge_history, abort_charge entry points

Fixes:
- Fix proration.rs to use Interval::Yearly (was Annually, non-existent variant)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants