Create Temporal billing sweep schedule, workflow and activities and register them in the worker/start initialization. Add an HTMX preview route and banner for plan switches (switch button now GETs a preview; Confirm posts the switch). Extend the Stripe test mock to support invoice previews and add integration tests for PreviewSwitch behavior.
43 lines
1.4 KiB
Go
43 lines
1.4 KiB
Go
// Package billing holds Temporal workflows and activities for billing
|
|
// maintenance — currently the periodic sweep that fires due subscription
|
|
// scheduled changes as a backstop to the Stripe-webhook-primary firing path.
|
|
package billing
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"log/slog"
|
|
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/fulfillment"
|
|
)
|
|
|
|
// Activities holds dependencies for billing maintenance activities.
|
|
type Activities struct {
|
|
db *sql.DB
|
|
logger *slog.Logger
|
|
}
|
|
|
|
// NewActivities constructs an Activities ready for registration.
|
|
func NewActivities(db *sql.DB, logger *slog.Logger) *Activities {
|
|
if logger == nil {
|
|
logger = slog.Default()
|
|
}
|
|
return &Activities{db: db, logger: logger}
|
|
}
|
|
|
|
// SweepScheduledChangesOutput reports how many due scheduled changes fired.
|
|
type SweepScheduledChangesOutput struct {
|
|
Fired int
|
|
}
|
|
|
|
// SweepScheduledChangesActivity fires every due subscription scheduled change.
|
|
// It is idempotent (each row is claimed via a conditional scheduled->applied
|
|
// update), so re-running it — or racing the webhook path — is safe.
|
|
func (a *Activities) SweepScheduledChangesActivity(ctx context.Context) (SweepScheduledChangesOutput, error) {
|
|
fired, err := fulfillment.SweepDueScheduledChanges(ctx, a.db, a.logger)
|
|
if err != nil {
|
|
return SweepScheduledChangesOutput{}, err
|
|
}
|
|
return SweepScheduledChangesOutput{Fired: fired}, nil
|
|
}
|