Membership Events

The memberships Lambda consumes the site-user-service-users Kinesis stream and translates membership lifecycle events from the user-service into subscription record updates in the billing-activity table. It moves no money — its sole responsibility is keeping subscription statuses consistent with membership state.

Event Filter

A Kinesis filter on the event source mapping (deploy/lambda.tf) passes twelve event types: UPGRADE, DOWNGRADE, CANCEL, RETRACT, AUTODOWNGRADED, GONETOCOLLECTIONS, PAYNOW, SUB_PAUSED, UNPAUSE, UNPAUSE_CHARGE, CLOSEACCOUNT, REACTIVATE.

Six of them have handlers (Handlers). The rest hit the dispatch switch’s default case and return ErrUnsupportedType: the record is reported as a batch-item failure and retried (UPGRADE/DOWNGRADE are served by the API endpoints — subscription_lifecycle.adoc#upgrade-downgrade; REACTIVATE by subscription_lifecycle.adoc#reactivation; AUTODOWNGRADED, GONETOCOLLECTIONS, and PAYNOW mutate nothing in this service).

Handlers

Every handler except CLOSEACCOUNT first fetches the user from the User Service and discards the event unless status == ACTIVE (a missing user is a logged no-op), then acquires the per-user billing lock (dynamo.adoc#locks) before reading and batch-writing records. CLOSEACCOUNT skips both the status check and the lock. All writes set last_run_date and land in billing-activity plus billing-activity-history.

Event Records matched Effect

CANCEL

SCHEDULED, PAUSED

updated_event: PENDING_CANCELLATION; status unchanged — the next collections run sets CANCELLED. Emits memberships.user.cancelled.

SUB_PAUSED

SCHEDULED

Status → PAUSED; updated_event: SUB_PAUSED; pause_duration_months from the event (-1 = indefinite when the event carries ≤ 0); term forced to MONTHLY.

RETRACT

SCHEDULED with a non-empty updated_event

Clears updated_event and sets term from the event — un-does a pending change (e.g. a queued cancel or pause) before the collections engine processes it. Cancels nothing.

UNPAUSE

All PAUSED

Soonest record → SCHEDULED (updated_event: UNPAUSE, pause counter cleared); every other PAUSED record → CANCELLED.

UNPAUSE_CHARGE

All PAUSED

Same as UNPAUSE, but the soonest record gets updated_event: pause-pending-resume, which the pause collections run collects immediately (collections.adoc#pause).

CLOSEACCOUNT

SCHEDULED, PAUSED

Status → CANCELLED; updated_event: account-closed. No user-status check, no lock.

Source: pkg/memberships/.

Error Handling

The Kinesis entry point reports partial batch failures by sequence number: successfully processed records are not retried, failed records are, and the event source mapping bisects a failing batch to isolate bad records. Unmarshal and decode failures are logged and reported the same way.