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
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 48050ae5ddd2075cf436343c837ad75370660410f96c3a3d1c12e4d58612ec65
|
|
4
|
+
data.tar.gz: debc50e9f6570fa7361e8a03d23bab7c1c84e30214cb4b49ff2e66b957e493d9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bd7f31ec043899f985949285a8f3b47cfd9fda83885d06c9f89fc5052c7374113427c054c7868501c34d484ae62c4f58377d915300777df0ff150ea7d34068b4
|
|
7
|
+
data.tar.gz: ae8884205c3f95c991722517358897b1bb5ee559be3bca06d513f477e76e58fbb8bfeb4a20602be40517d51a8178e7e1d0cd2e744e069eefd1cae5b6950afa6e
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] — 2026-05-10
|
|
11
|
+
|
|
12
|
+
First public release on rubygems.org. The cumulative changelog from
|
|
13
|
+
Wave 1 through Wave 11A follows. Subsequent releases will track
|
|
14
|
+
per-version changes only.
|
|
15
|
+
|
|
16
|
+
### Wave 11A — Admin engine (Administrate-backed)
|
|
17
|
+
|
|
18
|
+
Ships `bin/rails generate seams:admin` as an opt-in canonical engine.
|
|
19
|
+
Hosts that have the canonical six in place (core, auth, accounts,
|
|
20
|
+
notifications, billing, teams) can mount an Administrate-backed admin
|
|
21
|
+
surface at `/admin` covering all twelve canonical seams models with a
|
|
22
|
+
single command. Dashboards, two-mode authorization, audit-log
|
|
23
|
+
auto-write, and the four config knobs all ship out of the box. See
|
|
24
|
+
[`doc/ARCHITECTURE_WAVE_11.md`](doc/ARCHITECTURE_WAVE_11.md) for the
|
|
25
|
+
new architecture material; the framework selection rationale lives in
|
|
26
|
+
[`proposals/admin_engine_administrate.md`](proposals/admin_engine_administrate.md).
|
|
27
|
+
|
|
28
|
+
#### Added
|
|
29
|
+
|
|
30
|
+
- **`bin/seams admin` generator + canonical engine.** Writes an
|
|
31
|
+
`engines/admin/` engine into the host with twelve Administrate
|
|
32
|
+
dashboards covering `Auth::Identity`, `Accounts::Account`,
|
|
33
|
+
`Accounts::Membership`, `Teams::Team`, `Teams::Membership`,
|
|
34
|
+
`Teams::Invitation`, `Notifications::Notification`,
|
|
35
|
+
`Notifications::NotificationPreference`, `Billing::Plan`,
|
|
36
|
+
`Billing::Subscription`, `Billing::Invoice`, and
|
|
37
|
+
`Billing::LifetimePass`. Each dashboard subclasses
|
|
38
|
+
`Administrate::BaseDashboard`; each controller subclasses
|
|
39
|
+
`Seams::Admin::ApplicationController` (NOT Administrate's directly)
|
|
40
|
+
so it inherits the gate, the `pundit_user` hook, and the audit-log
|
|
41
|
+
auto-write. Engine ships **no migrations** — read-only over existing
|
|
42
|
+
tables.
|
|
43
|
+
- **Two-mode authorization via Pundit `policy_namespace`.** Twelve
|
|
44
|
+
policies under `Admin::Platform::*` (gate: `Auth::Identity#staff?`,
|
|
45
|
+
no tenant filter) and twelve under `Admin::Tenant::*` (gate:
|
|
46
|
+
`Accounts::Membership#role == "admin"`, scope filtered by
|
|
47
|
+
`account_id` from `Accounts::Current.membership`). Plus two base
|
|
48
|
+
`ApplicationPolicy` classes — 26 policy files total.
|
|
49
|
+
`Seams::Admin.config.tenancy_scope` (`:platform` default, `:tenant`
|
|
50
|
+
alternative) selects the namespace at request time.
|
|
51
|
+
- **`Seams::Admin::Context` Struct.** Wraps the current Identity +
|
|
52
|
+
Membership as the value `pundit_user` returns. Exposes nil-safe
|
|
53
|
+
`staff?`, `role`, and `account_id` convenience methods so policies
|
|
54
|
+
stay readable without each one fishing values out of the controller.
|
|
55
|
+
- **Audit-log auto-write via `Core::Auditable` integration.**
|
|
56
|
+
`record_admin_audit` after_action on every successful
|
|
57
|
+
create/update/destroy emits a `Core::AuditLog` row keyed on
|
|
58
|
+
`Auth::Current.identity&.id`. Wrapped in `defined?(Core::AuditLog)`
|
|
59
|
+
so the engine boots without core. Update payloads carry
|
|
60
|
+
`record.saved_changes.transform_values(&:last)`; create/destroy
|
|
61
|
+
payloads carry attributes minus timestamps.
|
|
62
|
+
- **Four configuration knobs** in `Seams::Admin.config`:
|
|
63
|
+
`authenticator` (callable; default `staff?` on current Identity);
|
|
64
|
+
`tenancy_scope` (`:platform` | `:tenant`); `theme_css_path`
|
|
65
|
+
(host-supplied admin restyle path); `before_admin_action` (callable
|
|
66
|
+
hook for 2FA, IP allow-list, etc.).
|
|
67
|
+
- **Five Wave-10 insertion-point markers** placed in the admin engine:
|
|
68
|
+
`admin.engine.events`, `admin.routes.before_resources`,
|
|
69
|
+
`admin.routes.after_resources`, `admin.configuration.attributes`,
|
|
70
|
+
`admin.configuration.defaults`. Catalogue updated to 38 markers
|
|
71
|
+
total across seven engines.
|
|
72
|
+
- **Showcase install path on top of `seams-example`.** The admin
|
|
73
|
+
generator stub-loads `Auth::Current` and `Accounts::Current`
|
|
74
|
+
CurrentAttributes objects in the dummy app, ships slim
|
|
75
|
+
`ApplicationRecord` stubs for every dashboard's resource_class, and
|
|
76
|
+
appends `administrate` + `pundit` to both the engine's standalone
|
|
77
|
+
Gemfile and the host Gemfile.
|
|
78
|
+
- **Boot-time dependency assertion.** The engine raises a clear
|
|
79
|
+
`[seams admin] missing required dependency: ...` at boot when
|
|
80
|
+
`Auth::Identity`, `Administrate`, or `Pundit` is missing — fail
|
|
81
|
+
loud at boot rather than NameError mid-request.
|
|
82
|
+
- **`bin/seams help` + post-install message** updated to list `admin`
|
|
83
|
+
alongside the canonical generators (with the explicit "optional —
|
|
84
|
+
generate after the canonical six" caveat).
|
|
85
|
+
- **AdminUser-on-separate-tables rule reinterpretation** documented
|
|
86
|
+
inline in the engine README. Wave 9's credential-only
|
|
87
|
+
`Auth::Identity` already satisfies the rule's intent (no
|
|
88
|
+
customer-facing concerns on the admin authentication object); a
|
|
89
|
+
boolean `staff?` flag is the right granularity. Hosts that need
|
|
90
|
+
hard isolation override the authenticator.
|
|
91
|
+
|
|
92
|
+
### Wave 10 — Splicing tooling
|
|
93
|
+
|
|
94
|
+
Turns seams from a one-shot scaffolder into a long-lived framework.
|
|
95
|
+
Generated engines now expose stable, named extension points;
|
|
96
|
+
follow-up generators target those points to add features without
|
|
97
|
+
re-templating the whole engine; and `bin/seams resolve --eject`
|
|
98
|
+
marks any single host file as host-owned so subsequent
|
|
99
|
+
`bin/seams <engine>` runs leave it alone. See
|
|
100
|
+
[`doc/ARCHITECTURE_WAVE_10.md`](doc/ARCHITECTURE_WAVE_10.md) for the
|
|
101
|
+
addendum and [`doc/WRITING_FOLLOW_UP_GENERATORS.md`](doc/WRITING_FOLLOW_UP_GENERATORS.md)
|
|
102
|
+
for the author's guide.
|
|
103
|
+
|
|
104
|
+
#### Added
|
|
105
|
+
|
|
106
|
+
- **Insertion-point machinery.** `Seams::Generators::Splicer`
|
|
107
|
+
(idempotent splice primitives — looks up markers by name, never by
|
|
108
|
+
line number; auto-detects indentation off the marker line; fifty-line
|
|
109
|
+
idempotency window) and `Seams::Generators::FollowUpGenerator`
|
|
110
|
+
(Rails generator base class supplying `engine_path`, `splice`,
|
|
111
|
+
`assert_marker_exists!`, and a `report_summary` template-method
|
|
112
|
+
hook). Pure file I/O — no Rails dep on the Splicer itself, so
|
|
113
|
+
`bin/seams resolve` can reuse it without booting Rails.
|
|
114
|
+
- **Insertion-point catalogue.** 33 markers placed across the six
|
|
115
|
+
canonical engines (32 active + 1 deferred to Wave 12 pending the
|
|
116
|
+
core Configuration class). Marker shape:
|
|
117
|
+
`# seams:insertion-point <engine>.<area>.<scope>` — ASCII only,
|
|
118
|
+
greppable, parses through every Ruby linter. Format spec in
|
|
119
|
+
[`doc/INSERTION_POINTS.md`](doc/INSERTION_POINTS.md); canonical list
|
|
120
|
+
in [`doc/INSERTION_POINTS_CATALOGUE.md`](doc/INSERTION_POINTS_CATALOGUE.md).
|
|
121
|
+
- **`bin/seams resolve` CLI.** Three modes:
|
|
122
|
+
- `--eject <engine>/<file>` — prepends a
|
|
123
|
+
`# seams:ejected from <engine>.<path>` header to the host file;
|
|
124
|
+
refuses to eject framework-managed files (migrations, engine.rb,
|
|
125
|
+
version.rb, Gemfile, .gemspec).
|
|
126
|
+
- `--list-markers <engine>` — lists every insertion-point marker
|
|
127
|
+
the engine ships, with file:line and the catalogue's "purpose"
|
|
128
|
+
one-liner where present. Falls back to a "this engine may not
|
|
129
|
+
have been retrofitted" hint when the engine has zero markers.
|
|
130
|
+
- `--list-ejected` — surveys `engines/` for files carrying the
|
|
131
|
+
eject header, prints them with their source marker.
|
|
132
|
+
- **`Seams::Generators::EjectAware` mixin** — wired into all six
|
|
133
|
+
canonical engine generators (auth, accounts, billing, core,
|
|
134
|
+
notifications, teams). Every `template` call now goes through
|
|
135
|
+
`template_unless_ejected`, which detects the eject header in the
|
|
136
|
+
destination's first 200 bytes and short-circuits with a yellow
|
|
137
|
+
`skip` log line.
|
|
138
|
+
- **First showcase follow-up generator.**
|
|
139
|
+
`bin/rails generate seams:auth:add_oauth_provider <name>` (e.g.
|
|
140
|
+
`linkedin`, `apple`, `microsoft`) creates an
|
|
141
|
+
`Auth::OAuth::<Provider>` adapter under
|
|
142
|
+
`engines/auth/lib/auth/oauth/<name>.rb`, splices a configuration
|
|
143
|
+
entry into `engines/auth/lib/auth/configuration.rb` at the
|
|
144
|
+
`auth.configuration.oauth_providers` marker, and writes a matching
|
|
145
|
+
spec. Idempotent on rerun.
|
|
146
|
+
- **Documentation.**
|
|
147
|
+
[`doc/INSERTION_POINTS.md`](doc/INSERTION_POINTS.md) (format spec),
|
|
148
|
+
[`doc/INSERTION_POINTS_CATALOGUE.md`](doc/INSERTION_POINTS_CATALOGUE.md)
|
|
149
|
+
(canonical 33-marker list),
|
|
150
|
+
[`doc/WRITING_FOLLOW_UP_GENERATORS.md`](doc/WRITING_FOLLOW_UP_GENERATORS.md)
|
|
151
|
+
(author's guide), and
|
|
152
|
+
[`doc/ARCHITECTURE_WAVE_10.md`](doc/ARCHITECTURE_WAVE_10.md)
|
|
153
|
+
(architecture addendum with splice + eject sequence diagrams).
|
|
154
|
+
- **Host-facing surfaces updated.**
|
|
155
|
+
`bin/seams help` and `bin/seams resolve --help` document the new
|
|
156
|
+
resolve modes; the install generator's post-install message lists
|
|
157
|
+
the resolve sub-commands and points at the showcase follow-up
|
|
158
|
+
generator.
|
|
159
|
+
|
|
160
|
+
### Wave 9 — Identity / Account / Team rework (BREAKING)
|
|
161
|
+
|
|
162
|
+
Replaces the conflated `Auth::User` (which owned credentials AND
|
|
163
|
+
tenant-membership concepts) with three peer engines, each with one
|
|
164
|
+
clear responsibility. See `doc/UPGRADING_FROM_WAVE_8.md` for the
|
|
165
|
+
migration story.
|
|
166
|
+
|
|
167
|
+
#### Added
|
|
168
|
+
|
|
169
|
+
- New `accounts` engine. Owns `Accounts::Account` (the tenant) and
|
|
170
|
+
`Accounts::Membership` (Identity ↔ Account, role enum:
|
|
171
|
+
owner/admin/member/system). Provides `Accounts::Current.account`
|
|
172
|
+
and `Accounts::Current.membership` (the matching membership
|
|
173
|
+
auto-derived for the signed-in identity), `Accounts::AccountScoped`
|
|
174
|
+
concern (default-scope to the current account), and an
|
|
175
|
+
auto-created `system` Membership per Account so audit-log writes
|
|
176
|
+
from background jobs always have a valid actor to point at.
|
|
177
|
+
- `Accounts::Authorization` controller concern with default-on
|
|
178
|
+
`ensure_account_access`; opt out via `disallow_account_scope` or
|
|
179
|
+
`require_access_without_membership`. Helpers `ensure_admin` and
|
|
180
|
+
`ensure_staff` for admin-tooling guards.
|
|
181
|
+
- New `Auth::Current` per-request namespace (peer to
|
|
182
|
+
`Accounts::Current`, `Teams::Current`, and `Core::Current`). The
|
|
183
|
+
Auth engine sets `Auth::Current.identity` in its session lookup;
|
|
184
|
+
the rest of the engines read it.
|
|
185
|
+
- New `Teams::Current` per-request namespace, peer to
|
|
186
|
+
`Auth::Current` and `Accounts::Current`. `Teams::AccountScoped`
|
|
187
|
+
reads `Teams::Current.team` to scope rows to the current team.
|
|
188
|
+
- New `bin/seams accounts` command and Accounts engine generator.
|
|
189
|
+
|
|
190
|
+
#### Changed (BREAKING)
|
|
191
|
+
|
|
192
|
+
- `Auth::User` renamed to `Auth::Identity`. The `auth_users` table
|
|
193
|
+
becomes `auth_identities`. All credential state
|
|
194
|
+
(`password_digest`, OAuth grants, sessions, passkeys, magic-link
|
|
195
|
+
grants, API tokens) stays on `Auth::Identity` — the rename is
|
|
196
|
+
about meaning, not about splitting state.
|
|
197
|
+
- `Auth::Authentication` controller concern renamed `current_user`
|
|
198
|
+
to `current_identity` and `authenticate_user!` to
|
|
199
|
+
`authenticate_identity!`. Hosts that maintain a domain User on
|
|
200
|
+
top of `Auth::Identity` can re-expose `current_user` via their
|
|
201
|
+
own concern.
|
|
202
|
+
- The Rails-8 `has_secure_password` `reset_token: false` workaround
|
|
203
|
+
is dropped — the rename to `Auth::Identity` resolves the prior
|
|
204
|
+
naming clash on `password_reset_token`.
|
|
205
|
+
- `Teams::Membership` joins `Auth::Identity` directly (column
|
|
206
|
+
`identity_id`), not the host User. The `Teams::Teamable` concern
|
|
207
|
+
is removed entirely (Wave 9 dropped the canonical demo's host
|
|
208
|
+
User; nowhere to mix it into).
|
|
209
|
+
- `Team#member?` signature changed: previously took an
|
|
210
|
+
`Auth::User`-like record; now takes an `identity_id` integer.
|
|
211
|
+
Callers that passed a record need to pass `record.id` instead.
|
|
212
|
+
- Notifications subscribers re-target Identity/Account, not host
|
|
213
|
+
User:
|
|
214
|
+
- `Notifications::AuthSubscriber` reads `identity_id` from the
|
|
215
|
+
`identity.signed_up.auth` event payload.
|
|
216
|
+
- `Notifications::BillingSubscriber` resolves the owner by reading
|
|
217
|
+
`Billing.configuration.billable_class` (default
|
|
218
|
+
`Accounts::Account`) and looking up the row by `account_id`
|
|
219
|
+
carried on the billing event payload.
|
|
220
|
+
- `Notifications::PreferencesController` reads/writes
|
|
221
|
+
`notification_preferences.identity_id` (renamed from `user_id`).
|
|
222
|
+
- `Notifications::NotificationsController` and
|
|
223
|
+
`Notifications::NotificationChannel` resolve the recipient via
|
|
224
|
+
`Auth::Current.identity`, with a legacy `current_user` fallback
|
|
225
|
+
for hosts that maintain a domain User.
|
|
226
|
+
- `Billing.configuration.billable_class` defaults to
|
|
227
|
+
`"Accounts::Account"` (was `"User"`). The engine constantizes
|
|
228
|
+
lazily so hosts can flip this at runtime.
|
|
229
|
+
- Auth engine event names renamed:
|
|
230
|
+
- `user.signed_up.auth` → `identity.signed_up.auth`
|
|
231
|
+
- `user.signed_in.auth` → `identity.signed_in.auth`
|
|
232
|
+
- `user.signed_out.auth` → `identity.signed_out.auth`
|
|
233
|
+
Event payload keys renamed: `user_id:` → `identity_id:`.
|
|
234
|
+
- Teams engine event names renamed:
|
|
235
|
+
- `team.member_added.teams` → `team.member_joined.teams`
|
|
236
|
+
- `team.member_removed.teams` → `team.member_left.teams`
|
|
237
|
+
- Drop host `User` model from the canonical demo. Hosts that want
|
|
238
|
+
a domain-specific User keep their own; pure SaaS hosts don't need
|
|
239
|
+
one.
|
|
240
|
+
|
|
241
|
+
#### Fixed
|
|
242
|
+
|
|
243
|
+
- `Seams/NoCrossEngineModelAccess` cop relaxed: every engine ships
|
|
244
|
+
its own `<Engine>::Current` namespace, and these per-request
|
|
245
|
+
state holders are intentionally readable from any engine. The
|
|
246
|
+
cop now treats `Current` as a framework-level constant and
|
|
247
|
+
exempts it from the boundary rule. Documented in
|
|
248
|
+
`doc/CURRENT_ATTRIBUTES.md` and inline in the cop's docstring.
|
|
249
|
+
- `Teams::AccountScoped` now references `Teams::Current.team`
|
|
250
|
+
(previously a bare `Current.team` that resolved to nothing
|
|
251
|
+
inside `module Teams` — silently making the default_scope a
|
|
252
|
+
no-op for every host that didn't define a top-level `Current`).
|
|
253
|
+
- `Teams::Authorization`, `TeamsController#current_identity_id`,
|
|
254
|
+
and `InvitationsController#current_identity_id` now reference
|
|
255
|
+
`Auth::Current.identity` (previously a bare `Current.identity`
|
|
256
|
+
that resolved to nothing — silently 403-ing every team
|
|
257
|
+
membership check).
|
|
258
|
+
- `Notifications::PreferencesController` queries
|
|
259
|
+
`identity_id` (was `user_id`, which the migration never
|
|
260
|
+
created — every GET / PATCH was raising
|
|
261
|
+
`ActiveRecord::StatementInvalid`).
|
|
262
|
+
- `Core::HasCurrentAttributes#resolve_current_user` now reads
|
|
263
|
+
`Auth::Current.identity` first (with a `current_identity` and
|
|
264
|
+
`current_user` fallback chain for hosts that ship a domain
|
|
265
|
+
User). Previously fell through to `current_user` only, which
|
|
266
|
+
the canonical Wave-9 host doesn't expose, so
|
|
267
|
+
`Core::Current.user` was always nil and `Core::Auditable` wrote
|
|
268
|
+
`actor_id = nil` on every audit row.
|
|
269
|
+
- `Core::HasCurrentAttributes#resolve_current_team` no longer
|
|
270
|
+
reaches into `Teams::Team` directly; reads `Teams::Current.team`
|
|
271
|
+
instead. Inverts the dependency direction: teams may include
|
|
272
|
+
core's concerns, but core must not know about teams' models.
|
|
273
|
+
Hosts that want a different binding (e.g. URL `params[:team_id]`)
|
|
274
|
+
override the method.
|
|
275
|
+
- `Accounts::AccountScoped` is now fail-closed: when
|
|
276
|
+
`Accounts::Current.account` is unset, the default_scope returns
|
|
277
|
+
no rows (was: returned every row across every tenant — the
|
|
278
|
+
canonical multi-tenant data-leak bug). New `with_no_account_scope`
|
|
279
|
+
class method as the documented opt-out for seed scripts and
|
|
280
|
+
platform-admin tooling. Same treatment for `Teams::AccountScoped`.
|
|
281
|
+
- `accounts_memberships` migration: partial unique index over
|
|
282
|
+
`(account_id) WHERE role = 'system'` enforces the documented
|
|
283
|
+
invariant of EXACTLY ONE system actor per Account at the DB
|
|
284
|
+
level. Postgres treats NULLs as distinct in unique indexes, so
|
|
285
|
+
the existing `(account_id, identity_id)` compound index didn't
|
|
286
|
+
prevent two `(account_id, NULL)` system rows.
|
|
287
|
+
- `Notifications::Notification#owner_id` is now a `string`
|
|
288
|
+
column (was bigint). Holds both bigint Identity IDs and UUID
|
|
289
|
+
Account IDs simultaneously — necessary now that the
|
|
290
|
+
BillingSubscriber addresses notifications at the
|
|
291
|
+
`Accounts::Account` (UUID PK).
|
|
292
|
+
- `Accounts::Engine` and `Teams::Engine` raise a clear
|
|
293
|
+
`[seams ...] missing required cross-engine dependency` error
|
|
294
|
+
at boot when their required peer (auth) isn't installed.
|
|
295
|
+
Previously failed silently at first query.
|
|
296
|
+
- Notifications and Accounts dummy schemas align on the
|
|
297
|
+
`auth_identities` shape (text email + password_digest + staff
|
|
298
|
+
flag + partial staff index).
|
|
299
|
+
- Removed dead `User < ApplicationRecord` model from the core
|
|
300
|
+
engine's dummy app — the auditable spec stubs its own `Article`
|
|
301
|
+
via `stub_const`; nothing else referenced the User class.
|
|
302
|
+
|
|
303
|
+
### Pre-Wave-9 history
|
|
304
|
+
|
|
305
|
+
Waves 1–8 of the seams gem are summarised below. Detailed
|
|
306
|
+
per-commit history is in the git log; the published gem version
|
|
307
|
+
will be 0.9.0 covering Waves 1–9 cumulatively.
|
|
308
|
+
|
|
309
|
+
- **Wave 8** — Per-engine spec coverage harmonised; 4-agent audit
|
|
310
|
+
fixes; `bin/audit` consolidated as the single pre-push verification
|
|
311
|
+
command.
|
|
312
|
+
- **Wave 7** — End-to-end `spec/integration_full/` smoke probe
|
|
313
|
+
exercising every public seams API against a real `rails new`
|
|
314
|
+
host on Postgres.
|
|
315
|
+
- **Wave 6** — Replaced the in-house Faraday-based Stripe client
|
|
316
|
+
with the official `stripe` Ruby gem (cuts ~600 lines of adapter
|
|
317
|
+
code; Stripe gem now owns gateway evolution).
|
|
318
|
+
- **Wave 5** — Six-agent audit + risk-fix pass: 5 RISK-rated
|
|
319
|
+
defects across publisher contract, generator templates,
|
|
320
|
+
notifications adapter resolution, and CI YAML drift.
|
|
321
|
+
- **Wave 4** — Teams engine (Phases 4A.1 + 4A.2): Team /
|
|
322
|
+
Membership / Invitation models, controllers, views, mailer,
|
|
323
|
+
invitation accept flow with row-lock against double-clicks.
|
|
324
|
+
- **Wave 3** — Integration spec verifying billing + auth +
|
|
325
|
+
notifications wired together end-to-end (post-rails-new host).
|
|
326
|
+
- **Wave 2** — Notifications engine: STI strategies, ActionCable
|
|
327
|
+
bell, TypeRegistry, --channels flag.
|
|
328
|
+
- **Wave 1** — Auth engine + Billing engine + Core engine + the
|
|
329
|
+
custom RuboCop cops + the engine generator scaffold.
|
|
330
|
+
|
|
331
|
+
## [0.0.1]
|
|
332
|
+
|
|
333
|
+
### Added
|
|
334
|
+
|
|
335
|
+
- Initial gem skeleton: `Seams.configure`, `Seams::Configuration`, version constant.
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 David Silva
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Seams
|
|
2
|
+
|
|
3
|
+
> A CLI framework that generates modular Rails engines.
|
|
4
|
+
|
|
5
|
+
Seams gives you the architectural benefits of microservices — clear
|
|
6
|
+
boundaries, independent testing, team autonomy — without the
|
|
7
|
+
operational cost. You ship a single Rails app. You think in
|
|
8
|
+
independent engines.
|
|
9
|
+
|
|
10
|
+
> Seams materialises the patterns David Silva teaches in **[Modular
|
|
11
|
+
> Rails: Architecture for the Long Game](https://davidslv.uk/modular-rails/)**.
|
|
12
|
+
> The book is the artefact; this gem is the executable shorthand. See
|
|
13
|
+
> [seams-example](https://github.com/Davidslv/seams-example) for a
|
|
14
|
+
> reference host that wires every canonical engine end-to-end.
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
# Gemfile
|
|
20
|
+
gem "seams"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bundle install
|
|
25
|
+
bin/rails generate seams:install
|
|
26
|
+
bin/seams auth
|
|
27
|
+
bin/seams accounts
|
|
28
|
+
bin/seams notifications
|
|
29
|
+
bin/seams billing
|
|
30
|
+
bin/seams teams
|
|
31
|
+
bin/seams list
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
That's auth, tenant boundary, transactional email/SMS, Stripe
|
|
35
|
+
subscriptions, and multi-tenant teams generated as five real Rails
|
|
36
|
+
engines under `engines/`. Every file is yours to edit. Nothing is
|
|
37
|
+
hidden behind the gem.
|
|
38
|
+
|
|
39
|
+
## What you get
|
|
40
|
+
|
|
41
|
+
- `bin/seams install` — adds the framework + CI workflow + bin/seams wrapper
|
|
42
|
+
- `bin/seams engine <name>` — generic engine scaffold
|
|
43
|
+
- `bin/seams core` — canonical Core engine (Current attributes, AuditLog, TenantScoped, EmailFormatValidator)
|
|
44
|
+
- `bin/seams auth` — canonical Auth engine (Identity, Session, OAuth, API tokens, GDPR-encrypted PII)
|
|
45
|
+
- `bin/seams accounts` — canonical Accounts engine (Account tenant, Membership, AccountScoped, system actor)
|
|
46
|
+
- `bin/seams notifications` — canonical Notifications engine (STI strategies, ActionCable bell, TypeRegistry, --channels flag)
|
|
47
|
+
- `bin/seams billing` — canonical Billing engine (official Stripe gem, 13-handler webhook router, Lifetime Deals)
|
|
48
|
+
- `bin/seams teams` — canonical Teams engine (Team, Membership, Invitation, AccountScoped, --with flag)
|
|
49
|
+
- `bin/seams remove <name>` — clean removal + sibling cleanup + drop-table migration
|
|
50
|
+
- `bin/seams list` — engines, the events they emit, and what they subscribe to
|
|
51
|
+
- `bin/seams resolve` — eject host files / list insertion-point markers / list ejected files
|
|
52
|
+
- `bin/rails generate seams:auth:add_oauth_provider <name>` — first follow-up generator (adds an OAuth provider adapter to an installed Auth engine)
|
|
53
|
+
- Four custom RuboCop cops that enforce cross-engine boundaries
|
|
54
|
+
- A GitHub Actions CI workflow that runs every engine's specs in parallel
|
|
55
|
+
|
|
56
|
+
## Documentation
|
|
57
|
+
|
|
58
|
+
- [doc/GETTING_STARTED.md](doc/GETTING_STARTED.md)
|
|
59
|
+
- [doc/ARCHITECTURE.md](doc/ARCHITECTURE.md) — short overview
|
|
60
|
+
- [doc/ARCHITECTURE_WAVE_9.md](doc/ARCHITECTURE_WAVE_9.md) — full system walk-through (post-Wave-9)
|
|
61
|
+
- [doc/ARCHITECTURE_WAVE_10.md](doc/ARCHITECTURE_WAVE_10.md) — Wave 10 addendum: insertion points, follow-up generators, eject CLI
|
|
62
|
+
- [doc/ENGINE_CATALOGUE.md](doc/ENGINE_CATALOGUE.md)
|
|
63
|
+
- [doc/CURRENT_ATTRIBUTES.md](doc/CURRENT_ATTRIBUTES.md) — per-request namespaces (Auth::Current, Accounts::Current, Teams::Current, Core::Current)
|
|
64
|
+
- [doc/INSERTION_POINTS.md](doc/INSERTION_POINTS.md) — marker format spec
|
|
65
|
+
- [doc/INSERTION_POINTS_CATALOGUE.md](doc/INSERTION_POINTS_CATALOGUE.md) — the canonical 33 markers
|
|
66
|
+
- [doc/WRITING_FOLLOW_UP_GENERATORS.md](doc/WRITING_FOLLOW_UP_GENERATORS.md) — write your own follow-up generator
|
|
67
|
+
- [doc/ADDING_AN_ENGINE.md](doc/ADDING_AN_ENGINE.md)
|
|
68
|
+
- [doc/REMOVING_AN_ENGINE.md](doc/REMOVING_AN_ENGINE.md)
|
|
69
|
+
- [doc/WRITING_AN_ADAPTER.md](doc/WRITING_AN_ADAPTER.md)
|
|
70
|
+
- [doc/TESTING.md](doc/TESTING.md)
|
|
71
|
+
- [doc/UPGRADING_FROM_WAVE_8.md](doc/UPGRADING_FROM_WAVE_8.md) — if you adopted seams pre-Wave-9
|
|
72
|
+
|
|
73
|
+
## Why Seams instead of...
|
|
74
|
+
|
|
75
|
+
| ... | Seams gives you |
|
|
76
|
+
| --- | --- |
|
|
77
|
+
| Bullet Train | The substrate, not a starter kit. Code is in your repo, not behind a gem. |
|
|
78
|
+
| Jumpstart Pro | Same. Plus the boundary cops. |
|
|
79
|
+
| `rails plugin new --mountable` | Engines come pre-wired with events, registry, observability, boundary enforcement, CI. |
|
|
80
|
+
| Hand-rolled microservices | One process. No HTTP between services. Synchronous events with explicit subscribers. |
|
|
81
|
+
|
|
82
|
+
## Status
|
|
83
|
+
|
|
84
|
+
Waves 1–9 complete: foundation, auth (with OAuth, API tokens,
|
|
85
|
+
GDPR-encrypted PII), notifications (with TypeRegistry,
|
|
86
|
+
ActionCable bell, multipart mailers), billing (official Stripe
|
|
87
|
+
gem, 13-handler webhook router, Lifetime Deals), teams (with
|
|
88
|
+
team scoping, role-based authz). Wave 9 added the `accounts`
|
|
89
|
+
engine and reworked the identity/account/team boundary —
|
|
90
|
+
`Auth::Identity` (the human), `Accounts::Account` (the tenant),
|
|
91
|
+
`Teams::Team` (the optional grouping) are now three peer engines
|
|
92
|
+
with one clear responsibility each. See
|
|
93
|
+
[CHANGELOG.md](CHANGELOG.md#wave-9--identity--account--team-rework-breaking)
|
|
94
|
+
and [doc/UPGRADING_FROM_WAVE_8.md](doc/UPGRADING_FROM_WAVE_8.md).
|
|
95
|
+
|
|
96
|
+
See [issue #5](https://github.com/Davidslv/seams/issues/5) for the live
|
|
97
|
+
work tracker.
|
|
98
|
+
|
|
99
|
+
Suite: RuboCop clean, brakeman + bundle-audit clean. Run
|
|
100
|
+
`bin/audit` before any push.
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT — see [LICENSE](LICENSE).
|