seams 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +335 -0
- data/LICENSE +21 -0
- data/README.md +104 -0
- data/lib/generators/seams/accounts/accounts_generator.rb +272 -0
- data/lib/generators/seams/accounts/templates/README.md.tt +219 -0
- data/lib/generators/seams/accounts/templates/app/models/account.rb.tt +124 -0
- data/lib/generators/seams/accounts/templates/app/models/application_record.rb.tt +7 -0
- data/lib/generators/seams/accounts/templates/app/models/current.rb.tt +38 -0
- data/lib/generators/seams/accounts/templates/app/models/membership.rb.tt +114 -0
- data/lib/generators/seams/accounts/templates/config/routes.rb.tt +8 -0
- data/lib/generators/seams/accounts/templates/db/migrate/create_accounts.rb.tt +29 -0
- data/lib/generators/seams/accounts/templates/db/migrate/create_accounts_memberships.rb.tt +49 -0
- data/lib/generators/seams/accounts/templates/lib/accounts.rb.tt +21 -0
- data/lib/generators/seams/accounts/templates/lib/concerns/account_scoped.rb.tt +97 -0
- data/lib/generators/seams/accounts/templates/lib/concerns/authorization.rb.tt +105 -0
- data/lib/generators/seams/accounts/templates/lib/configuration.rb.tt +26 -0
- data/lib/generators/seams/accounts/templates/lib/engine.rb.tt +55 -0
- data/lib/generators/seams/accounts/templates/spec/factories/accounts.rb.tt +49 -0
- data/lib/generators/seams/accounts/templates/spec/models/accounts/account_spec.rb.tt +64 -0
- data/lib/generators/seams/accounts/templates/spec/models/accounts/membership_spec.rb.tt +99 -0
- data/lib/generators/seams/accounts/templates/spec/runtime/accounts_boot_spec.rb.tt +181 -0
- data/lib/generators/seams/admin/admin_generator.rb +852 -0
- data/lib/generators/seams/admin/templates/README.md.tt +266 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/accounts_controller.rb.tt +16 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/accounts_memberships_controller.rb.tt +16 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/application_controller.rb.tt +282 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/identities_controller.rb.tt +26 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/invitations_controller.rb.tt +14 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/invoices_controller.rb.tt +14 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/lifetime_passes_controller.rb.tt +14 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/notification_preferences_controller.rb.tt +15 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/notifications_controller.rb.tt +18 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/plans_controller.rb.tt +14 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/subscriptions_controller.rb.tt +14 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/teams_controller.rb.tt +14 -0
- data/lib/generators/seams/admin/templates/app/controllers/admin/teams_memberships_controller.rb.tt +16 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/account_dashboard.rb.tt +50 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/accounts_membership_dashboard.rb.tt +58 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/identity_dashboard.rb.tt +48 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/invitation_dashboard.rb.tt +51 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/invoice_dashboard.rb.tt +67 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/lifetime_pass_dashboard.rb.tt +65 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/notification_dashboard.rb.tt +58 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/notification_preference_dashboard.rb.tt +43 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/plan_dashboard.rb.tt +72 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/subscription_dashboard.rb.tt +59 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/team_dashboard.rb.tt +39 -0
- data/lib/generators/seams/admin/templates/app/dashboards/admin/teams_membership_dashboard.rb.tt +43 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/account_policy.rb.tt +10 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/accounts_membership_policy.rb.tt +10 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/application_policy.rb.tt +85 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/identity_policy.rb.tt +18 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/invitation_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/invoice_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/lifetime_pass_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/notification_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/notification_preference_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/plan_policy.rb.tt +11 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/subscription_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/team_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/platform/teams_membership_policy.rb.tt +9 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/account_policy.rb.tt +33 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/accounts_membership_policy.rb.tt +24 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/application_policy.rb.tt +169 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/identity_policy.rb.tt +67 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/invitation_policy.rb.tt +24 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/invoice_policy.rb.tt +21 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/lifetime_pass_policy.rb.tt +21 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/notification_policy.rb.tt +25 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/notification_preference_policy.rb.tt +23 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/plan_policy.rb.tt +47 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/subscription_policy.rb.tt +22 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/team_policy.rb.tt +28 -0
- data/lib/generators/seams/admin/templates/app/policies/admin/tenant/teams_membership_policy.rb.tt +24 -0
- data/lib/generators/seams/admin/templates/config/routes.rb.tt +38 -0
- data/lib/generators/seams/admin/templates/lib/admin.rb.tt +36 -0
- data/lib/generators/seams/admin/templates/lib/concerns/authenticator.rb.tt +66 -0
- data/lib/generators/seams/admin/templates/lib/configuration.rb.tt +90 -0
- data/lib/generators/seams/admin/templates/lib/context.rb.tt +44 -0
- data/lib/generators/seams/admin/templates/lib/engine.rb.tt +68 -0
- data/lib/generators/seams/admin/templates/spec/factories/admin.rb.tt +10 -0
- data/lib/generators/seams/admin/templates/spec/runtime/admin_boot_spec.rb.tt +604 -0
- data/lib/generators/seams/auth/add_oauth_provider/add_oauth_provider_generator.rb +157 -0
- data/lib/generators/seams/auth/add_oauth_provider/templates/adapter.rb.tt +95 -0
- data/lib/generators/seams/auth/add_oauth_provider/templates/adapter_spec.rb.tt +58 -0
- data/lib/generators/seams/auth/auth_generator.rb +311 -0
- data/lib/generators/seams/auth/templates/README.md.tt +289 -0
- data/lib/generators/seams/auth/templates/app/controllers/oauth/callbacks_controller.rb.tt +80 -0
- data/lib/generators/seams/auth/templates/app/controllers/password_resets_controller.rb.tt +44 -0
- data/lib/generators/seams/auth/templates/app/controllers/registrations_controller.rb.tt +34 -0
- data/lib/generators/seams/auth/templates/app/controllers/sessions_controller.rb.tt +49 -0
- data/lib/generators/seams/auth/templates/app/jobs/application_job.rb.tt +7 -0
- data/lib/generators/seams/auth/templates/app/jobs/cleanup_expired_sessions_job.rb.tt +30 -0
- data/lib/generators/seams/auth/templates/app/mailers/passwords_mailer.rb.tt +15 -0
- data/lib/generators/seams/auth/templates/app/models/api_token.rb.tt +62 -0
- data/lib/generators/seams/auth/templates/app/models/application_record.rb.tt +7 -0
- data/lib/generators/seams/auth/templates/app/models/current.rb.tt +15 -0
- data/lib/generators/seams/auth/templates/app/models/identity.rb.tt +74 -0
- data/lib/generators/seams/auth/templates/app/models/oauth/provider.rb.tt +48 -0
- data/lib/generators/seams/auth/templates/app/models/session.rb.tt +28 -0
- data/lib/generators/seams/auth/templates/app/services/authenticate_identity.rb.tt +31 -0
- data/lib/generators/seams/auth/templates/app/services/generate_api_token.rb.tt +35 -0
- data/lib/generators/seams/auth/templates/app/services/oauth/authenticator.rb.tt +94 -0
- data/lib/generators/seams/auth/templates/app/services/register_identity.rb.tt +57 -0
- data/lib/generators/seams/auth/templates/app/services/reset_password.rb.tt +41 -0
- data/lib/generators/seams/auth/templates/app/services/revoke_api_token.rb.tt +38 -0
- data/lib/generators/seams/auth/templates/app/views/password_resets/edit.html.erb.tt +12 -0
- data/lib/generators/seams/auth/templates/app/views/password_resets/new.html.erb.tt +11 -0
- data/lib/generators/seams/auth/templates/app/views/passwords_mailer/reset_email.html.erb.tt +7 -0
- data/lib/generators/seams/auth/templates/app/views/registrations/new.html.erb.tt +26 -0
- data/lib/generators/seams/auth/templates/app/views/sessions/_oauth_buttons.html.erb.tt +18 -0
- data/lib/generators/seams/auth/templates/app/views/sessions/new.html.erb.tt +17 -0
- data/lib/generators/seams/auth/templates/config/routes.rb.tt +21 -0
- data/lib/generators/seams/auth/templates/db/migrate/create_auth_api_tokens.rb.tt +26 -0
- data/lib/generators/seams/auth/templates/db/migrate/create_auth_identities.rb.tt +29 -0
- data/lib/generators/seams/auth/templates/db/migrate/create_auth_oauth_providers.rb.tt +35 -0
- data/lib/generators/seams/auth/templates/db/migrate/create_auth_sessions.rb.tt +19 -0
- data/lib/generators/seams/auth/templates/lib/auth.rb.tt +39 -0
- data/lib/generators/seams/auth/templates/lib/concerns/api_authenticatable.rb.tt +58 -0
- data/lib/generators/seams/auth/templates/lib/concerns/authenticatable.rb.tt +32 -0
- data/lib/generators/seams/auth/templates/lib/concerns/authentication.rb.tt +60 -0
- data/lib/generators/seams/auth/templates/lib/configuration.rb.tt +45 -0
- data/lib/generators/seams/auth/templates/lib/engine.rb.tt +46 -0
- data/lib/generators/seams/auth/templates/lib/oauth/abstract.rb.tt +87 -0
- data/lib/generators/seams/auth/templates/lib/oauth/github.rb.tt +112 -0
- data/lib/generators/seams/auth/templates/lib/oauth/google.rb.tt +78 -0
- data/lib/generators/seams/auth/templates/lib/tasks/auth_pii.rake.tt +68 -0
- data/lib/generators/seams/auth/templates/spec/factories/auth.rb.tt +38 -0
- data/lib/generators/seams/auth/templates/spec/mailers/passwords_mailer_spec.rb.tt +37 -0
- data/lib/generators/seams/auth/templates/spec/models/api_token_spec.rb.tt +84 -0
- data/lib/generators/seams/auth/templates/spec/models/identity_spec.rb.tt +56 -0
- data/lib/generators/seams/auth/templates/spec/models/oauth/provider_spec.rb.tt +64 -0
- data/lib/generators/seams/auth/templates/spec/models/session_spec.rb.tt +34 -0
- data/lib/generators/seams/auth/templates/spec/runtime/boot_spec.rb.tt +30 -0
- data/lib/generators/seams/auth/templates/spec/runtime/event_payload_spec.rb.tt +29 -0
- data/lib/generators/seams/auth/templates/spec/runtime/login_flow_spec.rb.tt +45 -0
- data/lib/generators/seams/billing/billing_generator.rb +476 -0
- data/lib/generators/seams/billing/templates/README.md.tt +355 -0
- data/lib/generators/seams/billing/templates/app/controllers/admin/lifetime_passes_controller.rb.tt +84 -0
- data/lib/generators/seams/billing/templates/app/controllers/checkout_controller.rb.tt +92 -0
- data/lib/generators/seams/billing/templates/app/controllers/invoices_controller.rb.tt +63 -0
- data/lib/generators/seams/billing/templates/app/controllers/plans_controller.rb.tt +14 -0
- data/lib/generators/seams/billing/templates/app/controllers/portal_controller.rb.tt +45 -0
- data/lib/generators/seams/billing/templates/app/controllers/subscriptions_controller.rb.tt +119 -0
- data/lib/generators/seams/billing/templates/app/controllers/webhooks_controller.rb.tt +98 -0
- data/lib/generators/seams/billing/templates/app/helpers/currency_helper.rb.tt +44 -0
- data/lib/generators/seams/billing/templates/app/jobs/application_job.rb.tt +6 -0
- data/lib/generators/seams/billing/templates/app/jobs/cancel_subscription_job.rb.tt +39 -0
- data/lib/generators/seams/billing/templates/app/jobs/start_subscription_job.rb.tt +32 -0
- data/lib/generators/seams/billing/templates/app/jobs/webhooks/process_event_job.rb.tt +37 -0
- data/lib/generators/seams/billing/templates/app/models/application_record.rb.tt +7 -0
- data/lib/generators/seams/billing/templates/app/models/invoice.rb.tt +35 -0
- data/lib/generators/seams/billing/templates/app/models/lifetime_pass.rb.tt +60 -0
- data/lib/generators/seams/billing/templates/app/models/plan.rb.tt +95 -0
- data/lib/generators/seams/billing/templates/app/models/subscription.rb.tt +31 -0
- data/lib/generators/seams/billing/templates/app/models/webhook_event.rb.tt +13 -0
- data/lib/generators/seams/billing/templates/app/services/checkout_session_service.rb.tt +25 -0
- data/lib/generators/seams/billing/templates/app/services/customers/find_or_create_service.rb.tt +73 -0
- data/lib/generators/seams/billing/templates/app/services/invoices/sync_service.rb.tt +50 -0
- data/lib/generators/seams/billing/templates/app/services/lifetime/create_lifetime_session_service.rb.tt +82 -0
- data/lib/generators/seams/billing/templates/app/services/lifetime/create_pass_from_checkout_service.rb.tt +88 -0
- data/lib/generators/seams/billing/templates/app/services/lifetime/grant_pass_service.rb.tt +80 -0
- data/lib/generators/seams/billing/templates/app/services/lifetime/revoke_pass_service.rb.tt +59 -0
- data/lib/generators/seams/billing/templates/app/services/portal_session_service.rb.tt +23 -0
- data/lib/generators/seams/billing/templates/app/services/service_result.rb.tt +38 -0
- data/lib/generators/seams/billing/templates/app/services/stripe_service.rb.tt +67 -0
- data/lib/generators/seams/billing/templates/app/services/subscriptions/cancel_service.rb.tt +42 -0
- data/lib/generators/seams/billing/templates/app/services/subscriptions/change_plan_service.rb.tt +48 -0
- data/lib/generators/seams/billing/templates/app/services/subscriptions/reactivate_service.rb.tt +28 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/event_router.rb.tt +54 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handler.rb.tt +93 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/charge_refunded_handler.rb.tt +18 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/checkout_session_completed_handler.rb.tt +58 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/invoice_created_handler.rb.tt +16 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/invoice_finalized_handler.rb.tt +14 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/invoice_handler_base.rb.tt +80 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/invoice_paid_handler.rb.tt +12 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/invoice_payment_failed_handler.rb.tt +12 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/invoice_voided_handler.rb.tt +12 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/payment_failed_handler.rb.tt +15 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/payment_succeeded_handler.rb.tt +19 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/subscription_created_handler.rb.tt +11 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/subscription_deleted_handler.rb.tt +15 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/subscription_handler_base.rb.tt +92 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/subscription_trial_will_end_handler.rb.tt +15 -0
- data/lib/generators/seams/billing/templates/app/services/webhooks/handlers/subscription_updated_handler.rb.tt +11 -0
- data/lib/generators/seams/billing/templates/app/views/admin/lifetime_passes/index.html.erb.tt +36 -0
- data/lib/generators/seams/billing/templates/app/views/admin/lifetime_passes/new.html.erb.tt +37 -0
- data/lib/generators/seams/billing/templates/app/views/checkout/success.html.erb.tt +5 -0
- data/lib/generators/seams/billing/templates/app/views/invoices/index.html.erb.tt +22 -0
- data/lib/generators/seams/billing/templates/app/views/invoices/show.html.erb.tt +14 -0
- data/lib/generators/seams/billing/templates/app/views/plans/index.html.erb.tt +51 -0
- data/lib/generators/seams/billing/templates/app/views/subscriptions/index.html.erb.tt +16 -0
- data/lib/generators/seams/billing/templates/app/views/subscriptions/show.html.erb.tt +25 -0
- data/lib/generators/seams/billing/templates/config/routes.rb.tt +39 -0
- data/lib/generators/seams/billing/templates/db/migrate/create_billing_invoices.rb.tt +32 -0
- data/lib/generators/seams/billing/templates/db/migrate/create_billing_lifetime_passes.rb.tt +43 -0
- data/lib/generators/seams/billing/templates/db/migrate/create_billing_plans.rb.tt +31 -0
- data/lib/generators/seams/billing/templates/db/migrate/create_billing_subscriptions.rb.tt +33 -0
- data/lib/generators/seams/billing/templates/db/migrate/create_billing_webhook_events.rb.tt +24 -0
- data/lib/generators/seams/billing/templates/lib/billing.rb.tt +34 -0
- data/lib/generators/seams/billing/templates/lib/concerns/billable.rb.tt +100 -0
- data/lib/generators/seams/billing/templates/lib/configuration.rb.tt +52 -0
- data/lib/generators/seams/billing/templates/lib/engine.rb.tt +72 -0
- data/lib/generators/seams/billing/templates/lib/gateways/abstract.rb.tt +65 -0
- data/lib/generators/seams/billing/templates/lib/gateways/adyen.rb.tt +16 -0
- data/lib/generators/seams/billing/templates/lib/gateways/paddle.rb.tt +22 -0
- data/lib/generators/seams/billing/templates/lib/gateways/stripe.rb.tt +155 -0
- data/lib/generators/seams/billing/templates/lib/stripe/client.rb.tt +101 -0
- data/lib/generators/seams/billing/templates/lib/stripe/webhook_signature.rb.tt +43 -0
- data/lib/generators/seams/billing/templates/lib/tasks/billing_check.rake.tt +34 -0
- data/lib/generators/seams/billing/templates/spec/factories/billing.rb.tt +65 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/charge_refunded.json.tt +19 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/checkout_session_completed.json.tt +17 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/customer_subscription_created.json.tt +25 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/customer_subscription_deleted.json.tt +17 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/customer_subscription_trial_will_end.json.tt +17 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/customer_subscription_updated.json.tt +28 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/invoice_created.json.tt +18 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/invoice_finalized.json.tt +18 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/invoice_paid.json.tt +19 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/invoice_payment_failed.json.tt +20 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/invoice_voided.json.tt +18 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/payment_intent_payment_failed.json.tt +21 -0
- data/lib/generators/seams/billing/templates/spec/fixtures/stripe/payment_intent_succeeded.json.tt +17 -0
- data/lib/generators/seams/billing/templates/spec/gateways/contract_spec.rb.tt +11 -0
- data/lib/generators/seams/billing/templates/spec/gateways/stripe_spec.rb.tt +53 -0
- data/lib/generators/seams/billing/templates/spec/models/plan_spec.rb.tt +81 -0
- data/lib/generators/seams/billing/templates/spec/models/subscription_spec.rb.tt +43 -0
- data/lib/generators/seams/billing/templates/spec/runtime/boot_spec.rb.tt +38 -0
- data/lib/generators/seams/billing/templates/spec/runtime/webhook_handlers_spec.rb.tt +382 -0
- data/lib/generators/seams/billing/templates/spec/support/shared_examples/a_billing_gateway.rb.tt +100 -0
- data/lib/generators/seams/billing/templates/spec/support/stripe_helpers.rb.tt +59 -0
- data/lib/generators/seams/core/core_generator.rb +191 -0
- data/lib/generators/seams/core/templates/README.md.tt +45 -0
- data/lib/generators/seams/core/templates/app/controllers/concerns/has_current_attributes.rb.tt +71 -0
- data/lib/generators/seams/core/templates/app/models/application_record.rb.tt +7 -0
- data/lib/generators/seams/core/templates/app/models/audit_log.rb.tt +19 -0
- data/lib/generators/seams/core/templates/app/models/concerns/auditable.rb.tt +64 -0
- data/lib/generators/seams/core/templates/app/models/concerns/sluggable.rb.tt +53 -0
- data/lib/generators/seams/core/templates/app/models/concerns/soft_deletable.rb.tt +37 -0
- data/lib/generators/seams/core/templates/app/models/concerns/tenant_scoped.rb.tt +39 -0
- data/lib/generators/seams/core/templates/app/models/current.rb.tt +16 -0
- data/lib/generators/seams/core/templates/app/services/event_publisher.rb.tt +23 -0
- data/lib/generators/seams/core/templates/app/validators/email_format_validator.rb.tt +21 -0
- data/lib/generators/seams/core/templates/db/migrate/create_core_audit_logs.rb.tt +29 -0
- data/lib/generators/seams/core/templates/lib/core.rb.tt +8 -0
- data/lib/generators/seams/core/templates/lib/engine.rb.tt +28 -0
- data/lib/generators/seams/core/templates/spec/concerns/auditable_spec.rb.tt +39 -0
- data/lib/generators/seams/core/templates/spec/concerns/sluggable_spec.rb.tt +29 -0
- data/lib/generators/seams/core/templates/spec/models/audit_log_spec.rb.tt +22 -0
- data/lib/generators/seams/core/templates/spec/runtime/boot_spec.rb.tt +25 -0
- data/lib/generators/seams/core/templates/spec/validators/email_format_validator_spec.rb.tt +29 -0
- data/lib/generators/seams/engine/engine_generator.rb +165 -0
- data/lib/generators/seams/engine/templates/Gemfile.tt +19 -0
- data/lib/generators/seams/engine/templates/LICENSE.tt +21 -0
- data/lib/generators/seams/engine/templates/README.md.tt +40 -0
- data/lib/generators/seams/engine/templates/Rakefile.tt +14 -0
- data/lib/generators/seams/engine/templates/app/application_controller.rb.tt +6 -0
- data/lib/generators/seams/engine/templates/app/application_record.rb.tt +16 -0
- data/lib/generators/seams/engine/templates/config/locales/en.yml.tt +14 -0
- data/lib/generators/seams/engine/templates/config/routes.rb.tt +4 -0
- data/lib/generators/seams/engine/templates/gemspec.tt +20 -0
- data/lib/generators/seams/engine/templates/host_initializer.rb.tt +13 -0
- data/lib/generators/seams/engine/templates/lib/engine.rb.tt +27 -0
- data/lib/generators/seams/engine/templates/lib/root.rb.tt +7 -0
- data/lib/generators/seams/engine/templates/lib/version.rb.tt +5 -0
- data/lib/generators/seams/engine/templates/rubocop.yml.tt +55 -0
- data/lib/generators/seams/engine/templates/spec/example_spec.rb.tt +16 -0
- data/lib/generators/seams/engine/templates/spec/spec_helper.rb.tt +23 -0
- data/lib/generators/seams/install/install_generator.rb +211 -0
- data/lib/generators/seams/install/templates/Dockerfile.tt +52 -0
- data/lib/generators/seams/install/templates/Procfile.tt +14 -0
- data/lib/generators/seams/install/templates/bin_seams.tt +107 -0
- data/lib/generators/seams/install/templates/ci.yml.tt +123 -0
- data/lib/generators/seams/install/templates/deploy.yml.tt +63 -0
- data/lib/generators/seams/install/templates/doc/ARCHITECTURE.md.tt +86 -0
- data/lib/generators/seams/install/templates/docker-entrypoint.tt +27 -0
- data/lib/generators/seams/install/templates/rubocop.yml.tt +33 -0
- data/lib/generators/seams/install/templates/ruby-version.tt +1 -0
- data/lib/generators/seams/install/templates/script/collate_coverage.rb.tt +33 -0
- data/lib/generators/seams/install/templates/script/run_affected_tests.sh.tt +64 -0
- data/lib/generators/seams/install/templates/seams.rake.tt +65 -0
- data/lib/generators/seams/install/templates/seams.rb.tt +9 -0
- data/lib/generators/seams/install/templates/seams_engines.rb.tt +15 -0
- data/lib/generators/seams/notifications/notifications_generator.rb +395 -0
- data/lib/generators/seams/notifications/templates/README.md.tt +269 -0
- data/lib/generators/seams/notifications/templates/app/channels/notification_channel.rb.tt +36 -0
- data/lib/generators/seams/notifications/templates/app/controllers/notifications_controller.rb.tt +58 -0
- data/lib/generators/seams/notifications/templates/app/controllers/preferences_controller.rb.tt +54 -0
- data/lib/generators/seams/notifications/templates/app/javascript/controllers/notification_bell_controller.js.tt +34 -0
- data/lib/generators/seams/notifications/templates/app/jobs/application_job.rb.tt +6 -0
- data/lib/generators/seams/notifications/templates/app/jobs/create_notification_job.rb.tt +31 -0
- data/lib/generators/seams/notifications/templates/app/jobs/send_due_notifications_job.rb.tt +22 -0
- data/lib/generators/seams/notifications/templates/app/jobs/send_notification_job.rb.tt +13 -0
- data/lib/generators/seams/notifications/templates/app/mailers/application_mailer.rb.tt +12 -0
- data/lib/generators/seams/notifications/templates/app/mailers/notification_mailer.rb.tt +23 -0
- data/lib/generators/seams/notifications/templates/app/models/application_record.rb.tt +7 -0
- data/lib/generators/seams/notifications/templates/app/models/delivery.rb.tt +13 -0
- data/lib/generators/seams/notifications/templates/app/models/notification.rb.tt +218 -0
- data/lib/generators/seams/notifications/templates/app/models/notification_preference.rb.tt +29 -0
- data/lib/generators/seams/notifications/templates/app/models/strategies/email.rb.tt +38 -0
- data/lib/generators/seams/notifications/templates/app/models/strategies/in_app.rb.tt +26 -0
- data/lib/generators/seams/notifications/templates/app/models/strategies/sms.rb.tt +33 -0
- data/lib/generators/seams/notifications/templates/app/subscribers/auth_subscriber.rb.tt +71 -0
- data/lib/generators/seams/notifications/templates/app/subscribers/billing_subscriber.rb.tt +127 -0
- data/lib/generators/seams/notifications/templates/app/views/layouts/notifications/mailer.html.erb.tt +22 -0
- data/lib/generators/seams/notifications/templates/app/views/layouts/notifications/mailer.text.erb.tt +4 -0
- data/lib/generators/seams/notifications/templates/app/views/notifications/_bell.html.erb.tt +15 -0
- data/lib/generators/seams/notifications/templates/app/views/notifications/index.html.erb.tt +15 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/invoice_failed.html.erb.tt +4 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/invoice_failed.text.erb.tt +4 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/invoice_paid.html.erb.tt +3 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/invoice_paid.text.erb.tt +3 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/lifetime_granted.html.erb.tt +5 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/lifetime_granted.text.erb.tt +5 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/lifetime_purchased.html.erb.tt +5 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/lifetime_purchased.text.erb.tt +5 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/subscription_canceled.html.erb.tt +4 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/subscription_canceled.text.erb.tt +4 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/subscription_started.html.erb.tt +4 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/subscription_started.text.erb.tt +5 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/subscription_updated.html.erb.tt +3 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/billing/subscription_updated.text.erb.tt +3 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/default.html.erb.tt +10 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/default.text.erb.tt +11 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/welcome.html.erb.tt +6 -0
- data/lib/generators/seams/notifications/templates/app/views/templates/welcome.text.erb.tt +6 -0
- data/lib/generators/seams/notifications/templates/config/initializers/notifications.rb.tt +58 -0
- data/lib/generators/seams/notifications/templates/config/routes.rb.tt +17 -0
- data/lib/generators/seams/notifications/templates/db/migrate/create_notification_deliveries.rb.tt +16 -0
- data/lib/generators/seams/notifications/templates/db/migrate/create_notification_preferences.rb.tt +25 -0
- data/lib/generators/seams/notifications/templates/db/migrate/create_notifications.rb.tt +35 -0
- data/lib/generators/seams/notifications/templates/lib/adapters/abstract.rb.tt +20 -0
- data/lib/generators/seams/notifications/templates/lib/adapters/action_mailer.rb.tt +17 -0
- data/lib/generators/seams/notifications/templates/lib/adapters/null_sms.rb.tt +23 -0
- data/lib/generators/seams/notifications/templates/lib/concerns/notifiable.rb.tt +135 -0
- data/lib/generators/seams/notifications/templates/lib/configuration.rb.tt +24 -0
- data/lib/generators/seams/notifications/templates/lib/engine.rb.tt +35 -0
- data/lib/generators/seams/notifications/templates/lib/notifications.rb.tt +75 -0
- data/lib/generators/seams/notifications/templates/lib/type_registry.rb.tt +74 -0
- data/lib/generators/seams/notifications/templates/spec/factories/notifications.rb.tt +53 -0
- data/lib/generators/seams/notifications/templates/spec/models/delivery_spec.rb.tt +28 -0
- data/lib/generators/seams/notifications/templates/spec/models/notification_preference_spec.rb.tt +46 -0
- data/lib/generators/seams/notifications/templates/spec/models/notification_spec.rb.tt +60 -0
- data/lib/generators/seams/notifications/templates/spec/runtime/bell_broadcast_spec.rb.tt +59 -0
- data/lib/generators/seams/notifications/templates/spec/runtime/billing_subscriber_skip_spec.rb.tt +87 -0
- data/lib/generators/seams/notifications/templates/spec/runtime/boot_spec.rb.tt +39 -0
- data/lib/generators/seams/notifications/templates/spec/runtime/schedule_round_trip_spec.rb.tt +55 -0
- data/lib/generators/seams/remove/remove_generator.rb +259 -0
- data/lib/generators/seams/teams/teams_generator.rb +298 -0
- data/lib/generators/seams/teams/templates/README.md.tt +88 -0
- data/lib/generators/seams/teams/templates/app/controllers/invitations_controller.rb.tt +102 -0
- data/lib/generators/seams/teams/templates/app/controllers/memberships_controller.rb.tt +54 -0
- data/lib/generators/seams/teams/templates/app/controllers/teams_controller.rb.tt +68 -0
- data/lib/generators/seams/teams/templates/app/jobs/application_job.rb.tt +6 -0
- data/lib/generators/seams/teams/templates/app/mailers/invitation_mailer.rb.tt +34 -0
- data/lib/generators/seams/teams/templates/app/models/application_record.rb.tt +7 -0
- data/lib/generators/seams/teams/templates/app/models/current.rb.tt +30 -0
- data/lib/generators/seams/teams/templates/app/models/invitation.rb.tt +36 -0
- data/lib/generators/seams/teams/templates/app/models/membership.rb.tt +36 -0
- data/lib/generators/seams/teams/templates/app/models/team.rb.tt +32 -0
- data/lib/generators/seams/teams/templates/app/subscribers/invitation_subscriber.rb.tt +36 -0
- data/lib/generators/seams/teams/templates/app/views/invitation_mailer/invite.text.erb.tt +8 -0
- data/lib/generators/seams/teams/templates/app/views/invitations/index.html.erb.tt +44 -0
- data/lib/generators/seams/teams/templates/app/views/memberships/index.html.erb.tt +32 -0
- data/lib/generators/seams/teams/templates/app/views/teams/edit.html.erb.tt +28 -0
- data/lib/generators/seams/teams/templates/app/views/teams/index.html.erb.tt +15 -0
- data/lib/generators/seams/teams/templates/app/views/teams/new.html.erb.tt +24 -0
- data/lib/generators/seams/teams/templates/app/views/teams/show.html.erb.tt +17 -0
- data/lib/generators/seams/teams/templates/config/routes.rb.tt +19 -0
- data/lib/generators/seams/teams/templates/db/migrate/create_team_invitations.rb.tt +24 -0
- data/lib/generators/seams/teams/templates/db/migrate/create_team_memberships.rb.tt +25 -0
- data/lib/generators/seams/teams/templates/db/migrate/create_teams.rb.tt +18 -0
- data/lib/generators/seams/teams/templates/lib/concerns/account_scoped.rb.tt +79 -0
- data/lib/generators/seams/teams/templates/lib/concerns/authorization.rb.tt +55 -0
- data/lib/generators/seams/teams/templates/lib/configuration.rb.tt +45 -0
- data/lib/generators/seams/teams/templates/lib/engine.rb.tt +51 -0
- data/lib/generators/seams/teams/templates/lib/teams.rb.tt +22 -0
- data/lib/generators/seams/teams/templates/spec/factories/teams.rb.tt +47 -0
- data/lib/generators/seams/teams/templates/spec/models/invitation_spec.rb.tt +25 -0
- data/lib/generators/seams/teams/templates/spec/models/membership_spec.rb.tt +29 -0
- data/lib/generators/seams/teams/templates/spec/models/team_spec.rb.tt +23 -0
- data/lib/generators/seams/teams/templates/spec/runtime/boot_spec.rb.tt +32 -0
- data/lib/seams/cli/list.rb +111 -0
- data/lib/seams/cli/quality.rb +99 -0
- data/lib/seams/cli/resolve.rb +276 -0
- data/lib/seams/cli/test_changed.rb +116 -0
- data/lib/seams/cli.rb +48 -0
- data/lib/seams/configuration.rb +19 -0
- data/lib/seams/cops/known_queue_names.rb +42 -0
- data/lib/seams/cops/migration_comments.rb +68 -0
- data/lib/seams/cops/no_cross_engine_dependency.rb +58 -0
- data/lib/seams/cops/no_cross_engine_model_access.rb +153 -0
- data/lib/seams/cops.rb +18 -0
- data/lib/seams/event_registry.rb +49 -0
- data/lib/seams/events/adapter.rb +24 -0
- data/lib/seams/events/adapters/active_support.rb +31 -0
- data/lib/seams/events/publisher.rb +178 -0
- data/lib/seams/events.rb +39 -0
- data/lib/seams/generators/dummy_app_writer.rb +424 -0
- data/lib/seams/generators/eject_aware.rb +102 -0
- data/lib/seams/generators/follow_up_generator.rb +148 -0
- data/lib/seams/generators/host_injector.rb +124 -0
- data/lib/seams/generators/sibling_rubocop_writer.rb +77 -0
- data/lib/seams/generators/splicer.rb +217 -0
- data/lib/seams/observability/adapter.rb +33 -0
- data/lib/seams/observability/adapters/rails_logger.rb +59 -0
- data/lib/seams/observability.rb +34 -0
- data/lib/seams/runtime.rb +23 -0
- data/lib/seams/version.rb +5 -0
- data/lib/seams.rb +23 -0
- metadata +493 -0
data/lib/generators/seams/admin/templates/app/controllers/admin/notifications_controller.rb.tt
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Administrate controller for the Notifications::Notification
|
|
4
|
+
# dashboard. Note: Notification is an STI base — the table contains
|
|
5
|
+
# rows for InApp / Email / Sms subclasses. The admin index lists
|
|
6
|
+
# every subclass; the form lets admins set `type` to any of the
|
|
7
|
+
# permitted STI subclasses.
|
|
8
|
+
module Admin
|
|
9
|
+
class NotificationsController < ::Seams::Admin::ApplicationController
|
|
10
|
+
def resource_class
|
|
11
|
+
::Notifications::Notification
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def dashboard
|
|
15
|
+
@dashboard ||= NotificationDashboard.new
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Administrate controller for the Billing::Plan dashboard.
|
|
4
|
+
module Admin
|
|
5
|
+
class PlansController < ::Seams::Admin::ApplicationController
|
|
6
|
+
def resource_class
|
|
7
|
+
::Billing::Plan
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def dashboard
|
|
11
|
+
@dashboard ||= PlanDashboard.new
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/generators/seams/admin/templates/app/controllers/admin/subscriptions_controller.rb.tt
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Administrate controller for the Billing::Subscription dashboard.
|
|
4
|
+
module Admin
|
|
5
|
+
class SubscriptionsController < ::Seams::Admin::ApplicationController
|
|
6
|
+
def resource_class
|
|
7
|
+
::Billing::Subscription
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def dashboard
|
|
11
|
+
@dashboard ||= SubscriptionDashboard.new
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Administrate controller for the Teams::Team dashboard.
|
|
4
|
+
module Admin
|
|
5
|
+
class TeamsController < ::Seams::Admin::ApplicationController
|
|
6
|
+
def resource_class
|
|
7
|
+
::Teams::Team
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def dashboard
|
|
11
|
+
@dashboard ||= TeamDashboard.new
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/generators/seams/admin/templates/app/controllers/admin/teams_memberships_controller.rb.tt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Administrate controller for the Teams::Membership dashboard.
|
|
4
|
+
# Routed under `teams_memberships` (engine-prefixed) to disambiguate
|
|
5
|
+
# from `accounts_memberships`.
|
|
6
|
+
module Admin
|
|
7
|
+
class TeamsMembershipsController < ::Seams::Admin::ApplicationController
|
|
8
|
+
def resource_class
|
|
9
|
+
::Teams::Membership
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dashboard
|
|
13
|
+
@dashboard ||= TeamsMembershipDashboard.new
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Accounts::Account — the tenant boundary.
|
|
6
|
+
#
|
|
7
|
+
# Account uses a UUID primary key (so account ids can appear in
|
|
8
|
+
# shareable URLs without leaking row counts). Administrate's default
|
|
9
|
+
# Field::Number doesn't render UUIDs cleanly, so `id` is rendered as
|
|
10
|
+
# Field::String. The bigint `external_account_id` is a slug-friendly
|
|
11
|
+
# secondary identifier and renders fine as Field::Number.
|
|
12
|
+
module Admin
|
|
13
|
+
class AccountDashboard < Administrate::BaseDashboard
|
|
14
|
+
ATTRIBUTE_TYPES = {
|
|
15
|
+
# UUID PK — Field::String, not Field::Number.
|
|
16
|
+
id: Field::String,
|
|
17
|
+
name: Field::String,
|
|
18
|
+
external_account_id: Field::Number,
|
|
19
|
+
cancelled_at: Field::DateTime,
|
|
20
|
+
incinerated_at: Field::DateTime,
|
|
21
|
+
memberships: Field::HasMany,
|
|
22
|
+
created_at: Field::DateTime,
|
|
23
|
+
updated_at: Field::DateTime
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
COLLECTION_ATTRIBUTES = %i[id name external_account_id cancelled_at created_at].freeze
|
|
27
|
+
|
|
28
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
29
|
+
id
|
|
30
|
+
name
|
|
31
|
+
external_account_id
|
|
32
|
+
cancelled_at
|
|
33
|
+
incinerated_at
|
|
34
|
+
memberships
|
|
35
|
+
created_at
|
|
36
|
+
updated_at
|
|
37
|
+
].freeze
|
|
38
|
+
|
|
39
|
+
FORM_ATTRIBUTES = %i[name].freeze
|
|
40
|
+
|
|
41
|
+
COLLECTION_FILTERS = {
|
|
42
|
+
active: ->(resources) { resources.where(cancelled_at: nil) },
|
|
43
|
+
cancelled: ->(resources) { resources.where.not(cancelled_at: nil) }
|
|
44
|
+
}.freeze
|
|
45
|
+
|
|
46
|
+
def display_resource(account)
|
|
47
|
+
account.name.presence || "Account ##{account.id}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/generators/seams/admin/templates/app/dashboards/admin/accounts_membership_dashboard.rb.tt
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Accounts::Membership — joins an
|
|
6
|
+
# Auth::Identity to an Accounts::Account with a role.
|
|
7
|
+
#
|
|
8
|
+
# Class name is `Admin::AccountsMembershipDashboard` (with the engine
|
|
9
|
+
# prefix) to disambiguate from `Admin::TeamsMembershipDashboard` —
|
|
10
|
+
# both engines ship a Membership model and Administrate resolves
|
|
11
|
+
# dashboards by class name, so the prefixed form is necessary to keep
|
|
12
|
+
# them distinct in the same admin namespace.
|
|
13
|
+
#
|
|
14
|
+
# UUID primary key (matches Accounts::Account). identity_id is a bare
|
|
15
|
+
# bigint FK with no DB-level FK because cross-engine model access is
|
|
16
|
+
# forbidden by the seams architecture (NoCrossEngineModelAccess cop) —
|
|
17
|
+
# the admin surface treats identity_id as a typed integer reference.
|
|
18
|
+
module Admin
|
|
19
|
+
class AccountsMembershipDashboard < Administrate::BaseDashboard
|
|
20
|
+
ATTRIBUTE_TYPES = {
|
|
21
|
+
# UUID PK — Field::String, not Field::Number.
|
|
22
|
+
id: Field::String,
|
|
23
|
+
account: Field::BelongsTo.with_options(class_name: "Accounts::Account"),
|
|
24
|
+
identity_id: Field::Number,
|
|
25
|
+
name: Field::String,
|
|
26
|
+
role: Field::Select.with_options(collection: %w[owner admin member system]),
|
|
27
|
+
active: Field::Boolean,
|
|
28
|
+
verified_at: Field::DateTime,
|
|
29
|
+
created_at: Field::DateTime,
|
|
30
|
+
updated_at: Field::DateTime
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
COLLECTION_ATTRIBUTES = %i[id account name role active created_at].freeze
|
|
34
|
+
|
|
35
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
36
|
+
id
|
|
37
|
+
account
|
|
38
|
+
identity_id
|
|
39
|
+
name
|
|
40
|
+
role
|
|
41
|
+
active
|
|
42
|
+
verified_at
|
|
43
|
+
created_at
|
|
44
|
+
updated_at
|
|
45
|
+
].freeze
|
|
46
|
+
|
|
47
|
+
FORM_ATTRIBUTES = %i[account identity_id name role active].freeze
|
|
48
|
+
|
|
49
|
+
COLLECTION_FILTERS = {
|
|
50
|
+
active: ->(resources) { resources.where(active: true).where.not(role: "system") },
|
|
51
|
+
system: ->(resources) { resources.where(role: "system") }
|
|
52
|
+
}.freeze
|
|
53
|
+
|
|
54
|
+
def display_resource(membership)
|
|
55
|
+
"#{membership.role}: #{membership.name}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Auth::Identity. Identity is the canonical
|
|
6
|
+
# "who is logging in" record — credentials only, no customer-facing
|
|
7
|
+
# concerns. The encrypted email column is rendered with truncation and
|
|
8
|
+
# an "(encrypted at rest)" annotation so admins know they are looking
|
|
9
|
+
# at a column ActiveRecord::Encryption decrypts on read.
|
|
10
|
+
#
|
|
11
|
+
# Form fields deliberately exclude `password_digest` — admin should
|
|
12
|
+
# never see or set the bcrypt hash. Password resets go through the
|
|
13
|
+
# auth engine's reset flow, not through the admin surface.
|
|
14
|
+
module Admin
|
|
15
|
+
class IdentityDashboard < Administrate::BaseDashboard
|
|
16
|
+
# ATTRIBUTE_TYPES describes how Administrate renders each column.
|
|
17
|
+
# Administrate auto-discovers attributes from the model; declaring
|
|
18
|
+
# them explicitly here makes the rendering deterministic and lets
|
|
19
|
+
# us mark encrypted columns specially.
|
|
20
|
+
ATTRIBUTE_TYPES = {
|
|
21
|
+
id: Field::Number,
|
|
22
|
+
# email is encrypted at rest via ActiveRecord::Encryption (see
|
|
23
|
+
# Auth::Identity#encrypts). Truncated to 32 chars so a long
|
|
24
|
+
# ciphertext-padded email doesn't blow up the index column.
|
|
25
|
+
email: Field::String.with_options(searchable: true, truncate: 32), # (encrypted at rest)
|
|
26
|
+
staff: Field::Boolean,
|
|
27
|
+
created_at: Field::DateTime,
|
|
28
|
+
updated_at: Field::DateTime
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
COLLECTION_ATTRIBUTES = %i[id email staff created_at].freeze
|
|
32
|
+
|
|
33
|
+
SHOW_PAGE_ATTRIBUTES = %i[id email staff created_at updated_at].freeze
|
|
34
|
+
|
|
35
|
+
# password is intentionally absent — admin must not set the password
|
|
36
|
+
# directly. Hosts that need a "force-reset" admin action ship it as
|
|
37
|
+
# a custom action, not as a form field.
|
|
38
|
+
FORM_ATTRIBUTES = %i[email staff].freeze
|
|
39
|
+
|
|
40
|
+
COLLECTION_FILTERS = {
|
|
41
|
+
staff: ->(resources) { resources.where(staff: true) }
|
|
42
|
+
}.freeze
|
|
43
|
+
|
|
44
|
+
def display_resource(identity)
|
|
45
|
+
"Identity ##{identity.id}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Teams::Invitation — the lifecycle record
|
|
6
|
+
# for a pending team invite. Token is rendered with truncation since
|
|
7
|
+
# it's a 32-byte URL-safe base64 secret; admins should not need to
|
|
8
|
+
# read the full token (they re-issue if lost).
|
|
9
|
+
module Admin
|
|
10
|
+
class InvitationDashboard < Administrate::BaseDashboard
|
|
11
|
+
ATTRIBUTE_TYPES = {
|
|
12
|
+
id: Field::Number,
|
|
13
|
+
team: Field::BelongsTo.with_options(class_name: "Teams::Team"),
|
|
14
|
+
email: Field::String.with_options(searchable: true),
|
|
15
|
+
# Truncated to 16 chars so the table view doesn't get blown up
|
|
16
|
+
# by the 43-char base64 token. Full value still available on the
|
|
17
|
+
# show page (truncate doesn't apply there).
|
|
18
|
+
token: Field::String.with_options(truncate: 16),
|
|
19
|
+
role: Field::Select.with_options(collection: %w[owner admin member]),
|
|
20
|
+
expires_at: Field::DateTime,
|
|
21
|
+
accepted_at: Field::DateTime,
|
|
22
|
+
created_at: Field::DateTime,
|
|
23
|
+
updated_at: Field::DateTime
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
COLLECTION_ATTRIBUTES = %i[id team email role expires_at accepted_at].freeze
|
|
27
|
+
|
|
28
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
29
|
+
id
|
|
30
|
+
team
|
|
31
|
+
email
|
|
32
|
+
token
|
|
33
|
+
role
|
|
34
|
+
expires_at
|
|
35
|
+
accepted_at
|
|
36
|
+
created_at
|
|
37
|
+
updated_at
|
|
38
|
+
].freeze
|
|
39
|
+
|
|
40
|
+
FORM_ATTRIBUTES = %i[team email role expires_at].freeze
|
|
41
|
+
|
|
42
|
+
COLLECTION_FILTERS = {
|
|
43
|
+
pending: ->(resources) { resources.where(accepted_at: nil).where("expires_at > ?", Time.current) },
|
|
44
|
+
accepted: ->(resources) { resources.where.not(accepted_at: nil) }
|
|
45
|
+
}.freeze
|
|
46
|
+
|
|
47
|
+
def display_resource(invitation)
|
|
48
|
+
"Invitation to #{invitation.email}"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Billing::Invoice — local mirror of a
|
|
6
|
+
# gateway invoice. account_id is a UUID; rendered as Field::String.
|
|
7
|
+
#
|
|
8
|
+
# `amount_cents` is rendered as Field::Number for now; a custom
|
|
9
|
+
# Money field that formats "$12.34" with currency awareness is
|
|
10
|
+
# deferred to Wave 12 polish.
|
|
11
|
+
# TODO: Wave 12 — Field::Money custom field reading the `currency`
|
|
12
|
+
# column on the same row.
|
|
13
|
+
module Admin
|
|
14
|
+
class InvoiceDashboard < Administrate::BaseDashboard
|
|
15
|
+
ATTRIBUTE_TYPES = {
|
|
16
|
+
id: Field::Number,
|
|
17
|
+
# UUID — Field::String, not Field::Number.
|
|
18
|
+
account_id: Field::String,
|
|
19
|
+
gateway_ref: Field::String,
|
|
20
|
+
customer_ref: Field::String,
|
|
21
|
+
subscription_ref: Field::String,
|
|
22
|
+
# TODO: format as currency (Wave 12 — custom Money field)
|
|
23
|
+
amount_cents: Field::Number,
|
|
24
|
+
currency: Field::String,
|
|
25
|
+
status: Field::Select.with_options(collection: %w[draft open paid void uncollectible]),
|
|
26
|
+
paid_at: Field::DateTime,
|
|
27
|
+
created_at: Field::DateTime,
|
|
28
|
+
updated_at: Field::DateTime
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
COLLECTION_ATTRIBUTES = %i[id account_id gateway_ref status amount_cents paid_at].freeze
|
|
32
|
+
|
|
33
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
34
|
+
id
|
|
35
|
+
account_id
|
|
36
|
+
gateway_ref
|
|
37
|
+
customer_ref
|
|
38
|
+
subscription_ref
|
|
39
|
+
amount_cents
|
|
40
|
+
currency
|
|
41
|
+
status
|
|
42
|
+
paid_at
|
|
43
|
+
created_at
|
|
44
|
+
updated_at
|
|
45
|
+
].freeze
|
|
46
|
+
|
|
47
|
+
FORM_ATTRIBUTES = %i[
|
|
48
|
+
account_id
|
|
49
|
+
gateway_ref
|
|
50
|
+
customer_ref
|
|
51
|
+
subscription_ref
|
|
52
|
+
amount_cents
|
|
53
|
+
currency
|
|
54
|
+
status
|
|
55
|
+
paid_at
|
|
56
|
+
].freeze
|
|
57
|
+
|
|
58
|
+
COLLECTION_FILTERS = {
|
|
59
|
+
paid: ->(resources) { resources.where(status: "paid") },
|
|
60
|
+
open: ->(resources) { resources.where(status: "open") }
|
|
61
|
+
}.freeze
|
|
62
|
+
|
|
63
|
+
def display_resource(invoice)
|
|
64
|
+
"Invoice #{invoice.gateway_ref} (#{invoice.status})"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Billing::LifetimePass — one-time-paid OR
|
|
6
|
+
# privately-granted permanent access record. account_id is a UUID
|
|
7
|
+
# (Field::String). granted_by_identity_id / revoked_by_identity_id
|
|
8
|
+
# track the human (Auth::Identity bigint) who pressed the button.
|
|
9
|
+
module Admin
|
|
10
|
+
class LifetimePassDashboard < Administrate::BaseDashboard
|
|
11
|
+
ATTRIBUTE_TYPES = {
|
|
12
|
+
id: Field::Number,
|
|
13
|
+
# UUID — Field::String, not Field::Number.
|
|
14
|
+
account_id: Field::String,
|
|
15
|
+
customer_ref: Field::String,
|
|
16
|
+
plan_ref: Field::String,
|
|
17
|
+
gateway_ref: Field::String,
|
|
18
|
+
granted_by_identity_id: Field::Number,
|
|
19
|
+
granted_at: Field::DateTime,
|
|
20
|
+
revoked_at: Field::DateTime,
|
|
21
|
+
revoked_by_identity_id: Field::Number,
|
|
22
|
+
notes: Field::Text,
|
|
23
|
+
created_at: Field::DateTime,
|
|
24
|
+
updated_at: Field::DateTime
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
COLLECTION_ATTRIBUTES = %i[id account_id plan_ref granted_at revoked_at].freeze
|
|
28
|
+
|
|
29
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
30
|
+
id
|
|
31
|
+
account_id
|
|
32
|
+
customer_ref
|
|
33
|
+
plan_ref
|
|
34
|
+
gateway_ref
|
|
35
|
+
granted_by_identity_id
|
|
36
|
+
granted_at
|
|
37
|
+
revoked_at
|
|
38
|
+
revoked_by_identity_id
|
|
39
|
+
notes
|
|
40
|
+
created_at
|
|
41
|
+
updated_at
|
|
42
|
+
].freeze
|
|
43
|
+
|
|
44
|
+
FORM_ATTRIBUTES = %i[
|
|
45
|
+
account_id
|
|
46
|
+
customer_ref
|
|
47
|
+
plan_ref
|
|
48
|
+
gateway_ref
|
|
49
|
+
granted_by_identity_id
|
|
50
|
+
granted_at
|
|
51
|
+
revoked_at
|
|
52
|
+
revoked_by_identity_id
|
|
53
|
+
notes
|
|
54
|
+
].freeze
|
|
55
|
+
|
|
56
|
+
COLLECTION_FILTERS = {
|
|
57
|
+
active: ->(resources) { resources.where(revoked_at: nil) },
|
|
58
|
+
revoked: ->(resources) { resources.where.not(revoked_at: nil) }
|
|
59
|
+
}.freeze
|
|
60
|
+
|
|
61
|
+
def display_resource(pass)
|
|
62
|
+
"LifetimePass ##{pass.id} (#{pass.plan_ref})"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Notifications::Notification — the STI
|
|
6
|
+
# base. The `owner` association is polymorphic (Auth::Identity bigint
|
|
7
|
+
# OR Accounts::Account UUID OR a host model) and rendered via
|
|
8
|
+
# Field::Polymorphic so Administrate can handle both PK shapes.
|
|
9
|
+
#
|
|
10
|
+
# `schedule_data` is a jsonb cache of the IceCube::Schedule hash; it's
|
|
11
|
+
# verbose and rarely actionable in admin, so it's hidden from the
|
|
12
|
+
# collection view and only shown on the show page.
|
|
13
|
+
module Admin
|
|
14
|
+
class NotificationDashboard < Administrate::BaseDashboard
|
|
15
|
+
ATTRIBUTE_TYPES = {
|
|
16
|
+
id: Field::Number,
|
|
17
|
+
type: Field::String,
|
|
18
|
+
# Polymorphic owner — Field::Polymorphic resolves owner_type +
|
|
19
|
+
# owner_id, regardless of whether the owning row has a bigint or
|
|
20
|
+
# UUID PK (notification.owner_id is a string column).
|
|
21
|
+
owner: Field::Polymorphic,
|
|
22
|
+
recipient: Field::String,
|
|
23
|
+
template: Field::String,
|
|
24
|
+
next_delivery_at: Field::DateTime,
|
|
25
|
+
read_at: Field::DateTime,
|
|
26
|
+
schedule_data: Field::String.with_options(searchable: false),
|
|
27
|
+
created_at: Field::DateTime,
|
|
28
|
+
updated_at: Field::DateTime
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
COLLECTION_ATTRIBUTES = %i[id type owner template next_delivery_at read_at].freeze
|
|
32
|
+
|
|
33
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
34
|
+
id
|
|
35
|
+
type
|
|
36
|
+
owner
|
|
37
|
+
recipient
|
|
38
|
+
template
|
|
39
|
+
schedule_data
|
|
40
|
+
next_delivery_at
|
|
41
|
+
read_at
|
|
42
|
+
created_at
|
|
43
|
+
updated_at
|
|
44
|
+
].freeze
|
|
45
|
+
|
|
46
|
+
FORM_ATTRIBUTES = %i[type owner recipient template].freeze
|
|
47
|
+
|
|
48
|
+
COLLECTION_FILTERS = {
|
|
49
|
+
due: ->(resources) { resources.where(next_delivery_at: ..Time.current) },
|
|
50
|
+
unread: ->(resources) { resources.where(read_at: nil) },
|
|
51
|
+
completed: ->(resources) { resources.where(next_delivery_at: nil) }
|
|
52
|
+
}.freeze
|
|
53
|
+
|
|
54
|
+
def display_resource(notification)
|
|
55
|
+
"#{notification.type&.demodulize}: #{notification.template}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Notifications::NotificationPreference —
|
|
6
|
+
# per-Identity channel + notification-type toggle. Absence of a row
|
|
7
|
+
# means "use defaults" (everything enabled); a row with `enabled:
|
|
8
|
+
# false` is an explicit opt-out.
|
|
9
|
+
module Admin
|
|
10
|
+
class NotificationPreferenceDashboard < Administrate::BaseDashboard
|
|
11
|
+
ATTRIBUTE_TYPES = {
|
|
12
|
+
id: Field::Number,
|
|
13
|
+
identity_id: Field::Number,
|
|
14
|
+
channel: Field::Select.with_options(collection: %w[in_app email sms]),
|
|
15
|
+
notification_type: Field::String,
|
|
16
|
+
enabled: Field::Boolean,
|
|
17
|
+
created_at: Field::DateTime,
|
|
18
|
+
updated_at: Field::DateTime
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
21
|
+
COLLECTION_ATTRIBUTES = %i[id identity_id channel notification_type enabled].freeze
|
|
22
|
+
|
|
23
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
24
|
+
id
|
|
25
|
+
identity_id
|
|
26
|
+
channel
|
|
27
|
+
notification_type
|
|
28
|
+
enabled
|
|
29
|
+
created_at
|
|
30
|
+
updated_at
|
|
31
|
+
].freeze
|
|
32
|
+
|
|
33
|
+
FORM_ATTRIBUTES = %i[identity_id channel notification_type enabled].freeze
|
|
34
|
+
|
|
35
|
+
COLLECTION_FILTERS = {
|
|
36
|
+
disabled: ->(resources) { resources.where(enabled: false) }
|
|
37
|
+
}.freeze
|
|
38
|
+
|
|
39
|
+
def display_resource(preference)
|
|
40
|
+
"Identity #{preference.identity_id} / #{preference.channel}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Billing::Plan — local mirror of a Stripe
|
|
6
|
+
# Price (or other gateway's recurring billable thing).
|
|
7
|
+
#
|
|
8
|
+
# `amount_cents` is rendered as Field::Number for now; a custom
|
|
9
|
+
# Money field that formats "$12.34" with currency awareness is
|
|
10
|
+
# deferred to Wave 12 polish.
|
|
11
|
+
# TODO: Wave 12 — ship a Field::Money custom field that reads
|
|
12
|
+
# `currency` from the same row and formats accordingly.
|
|
13
|
+
module Admin
|
|
14
|
+
class PlanDashboard < Administrate::BaseDashboard
|
|
15
|
+
ATTRIBUTE_TYPES = {
|
|
16
|
+
id: Field::Number,
|
|
17
|
+
gateway_ref: Field::String,
|
|
18
|
+
name: Field::String,
|
|
19
|
+
description: Field::Text,
|
|
20
|
+
# TODO: format as currency (Wave 12 — custom Money field)
|
|
21
|
+
amount_cents: Field::Number,
|
|
22
|
+
currency: Field::String,
|
|
23
|
+
interval: Field::Select.with_options(collection: %w[day week month year lifetime]),
|
|
24
|
+
trial_period_days: Field::Number,
|
|
25
|
+
max_lifetime_units: Field::Number,
|
|
26
|
+
active: Field::Boolean,
|
|
27
|
+
features: Field::String.with_options(searchable: false),
|
|
28
|
+
created_at: Field::DateTime,
|
|
29
|
+
updated_at: Field::DateTime
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
COLLECTION_ATTRIBUTES = %i[id name gateway_ref interval amount_cents active].freeze
|
|
33
|
+
|
|
34
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
35
|
+
id
|
|
36
|
+
gateway_ref
|
|
37
|
+
name
|
|
38
|
+
description
|
|
39
|
+
amount_cents
|
|
40
|
+
currency
|
|
41
|
+
interval
|
|
42
|
+
trial_period_days
|
|
43
|
+
max_lifetime_units
|
|
44
|
+
active
|
|
45
|
+
features
|
|
46
|
+
created_at
|
|
47
|
+
updated_at
|
|
48
|
+
].freeze
|
|
49
|
+
|
|
50
|
+
FORM_ATTRIBUTES = %i[
|
|
51
|
+
gateway_ref
|
|
52
|
+
name
|
|
53
|
+
description
|
|
54
|
+
amount_cents
|
|
55
|
+
currency
|
|
56
|
+
interval
|
|
57
|
+
trial_period_days
|
|
58
|
+
max_lifetime_units
|
|
59
|
+
active
|
|
60
|
+
].freeze
|
|
61
|
+
|
|
62
|
+
COLLECTION_FILTERS = {
|
|
63
|
+
active: ->(resources) { resources.where(active: true) },
|
|
64
|
+
lifetime: ->(resources) { resources.where(interval: "lifetime") },
|
|
65
|
+
recurring: ->(resources) { resources.where.not(interval: "lifetime") }
|
|
66
|
+
}.freeze
|
|
67
|
+
|
|
68
|
+
def display_resource(plan)
|
|
69
|
+
plan.name.presence || plan.gateway_ref
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "administrate/base_dashboard"
|
|
4
|
+
|
|
5
|
+
# Administrate dashboard for Billing::Subscription — local mirror of a
|
|
6
|
+
# gateway subscription. account_id is a UUID (Accounts::Account#id) —
|
|
7
|
+
# rendered as Field::String since Field::Number truncates UUID strings.
|
|
8
|
+
# No belongs_to declaration on the model: cross-engine model access is
|
|
9
|
+
# forbidden by NoCrossEngineModelAccess, so the admin surface treats
|
|
10
|
+
# account_id as an opaque tenant reference rather than a belongs_to.
|
|
11
|
+
module Admin
|
|
12
|
+
class SubscriptionDashboard < Administrate::BaseDashboard
|
|
13
|
+
ATTRIBUTE_TYPES = {
|
|
14
|
+
id: Field::Number,
|
|
15
|
+
# UUID — Field::String, not Field::Number.
|
|
16
|
+
account_id: Field::String,
|
|
17
|
+
customer_ref: Field::String,
|
|
18
|
+
plan_ref: Field::String,
|
|
19
|
+
gateway_ref: Field::String,
|
|
20
|
+
status: Field::Select.with_options(
|
|
21
|
+
collection: %w[trialing active past_due canceled unpaid incomplete incomplete_expired paused]
|
|
22
|
+
),
|
|
23
|
+
current_period_end: Field::DateTime,
|
|
24
|
+
created_at: Field::DateTime,
|
|
25
|
+
updated_at: Field::DateTime
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
COLLECTION_ATTRIBUTES = %i[id account_id status plan_ref current_period_end].freeze
|
|
29
|
+
|
|
30
|
+
SHOW_PAGE_ATTRIBUTES = %i[
|
|
31
|
+
id
|
|
32
|
+
account_id
|
|
33
|
+
customer_ref
|
|
34
|
+
plan_ref
|
|
35
|
+
gateway_ref
|
|
36
|
+
status
|
|
37
|
+
current_period_end
|
|
38
|
+
created_at
|
|
39
|
+
updated_at
|
|
40
|
+
].freeze
|
|
41
|
+
|
|
42
|
+
FORM_ATTRIBUTES = %i[
|
|
43
|
+
account_id
|
|
44
|
+
customer_ref
|
|
45
|
+
plan_ref
|
|
46
|
+
gateway_ref
|
|
47
|
+
status
|
|
48
|
+
current_period_end
|
|
49
|
+
].freeze
|
|
50
|
+
|
|
51
|
+
COLLECTION_FILTERS = {
|
|
52
|
+
active_or_trialing: ->(resources) { resources.where(status: %w[active trialing]) }
|
|
53
|
+
}.freeze
|
|
54
|
+
|
|
55
|
+
def display_resource(subscription)
|
|
56
|
+
"Subscription #{subscription.gateway_ref} (#{subscription.status})"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|