open-loam 0.1.1 → 0.3.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 +4 -4
- data/CHANGELOG.md +148 -8
- data/LICENSE +1 -1
- data/README.md +27 -25
- data/app/jobs/{loam → open_loam}/custom_field_reindex_job.rb +6 -6
- data/app/jobs/{loam → open_loam}/event_delivery_job.rb +8 -8
- data/app/jobs/open_loam/event_log_prune_job.rb +15 -0
- data/app/jobs/{loam → open_loam}/event_redelivery_sweep_job.rb +4 -4
- data/app/jobs/{loam → open_loam}/webhook_delivery_job.rb +17 -8
- data/app/models/open_loam/api_token.rb +63 -0
- data/app/models/{loam → open_loam}/audit_record.rb +3 -3
- data/app/models/{loam → open_loam}/auth_attempt.rb +5 -5
- data/app/models/{loam → open_loam}/business_rule.rb +10 -10
- data/app/models/{loam → open_loam}/business_rule_run.rb +5 -5
- data/app/models/{loam → open_loam}/comment.rb +9 -9
- data/app/models/{loam → open_loam}/config.rb +7 -7
- data/app/models/{loam → open_loam}/custom_field_value.rb +5 -5
- data/app/models/{loam → open_loam}/dashboard_widget.rb +5 -5
- data/app/models/open_loam/dictionary.rb +20 -0
- data/app/models/{loam → open_loam}/dictionary_entry.rb +7 -7
- data/app/models/{loam → open_loam}/event_delivery.rb +4 -4
- data/app/models/open_loam/event_record.rb +42 -0
- data/app/models/{loam → open_loam}/field_definition.rb +8 -8
- data/app/models/{loam → open_loam}/inbound_webhook_delivery.rb +4 -4
- data/app/models/{loam → open_loam}/inbound_webhook_source.rb +13 -13
- data/app/models/{loam → open_loam}/membership.rb +6 -6
- data/app/models/{loam → open_loam}/mfa_credential.rb +8 -8
- data/app/models/{loam → open_loam}/notification.rb +10 -10
- data/app/models/{loam → open_loam}/pending_action.rb +70 -26
- data/app/models/{loam → open_loam}/perspective.rb +5 -5
- data/app/models/{loam → open_loam}/progress_job.rb +7 -7
- data/app/models/{loam → open_loam}/record_lock.rb +5 -5
- data/app/models/{loam → open_loam}/scheduled_job.rb +7 -7
- data/app/models/open_loam/search_token.rb +9 -0
- data/app/models/{loam → open_loam}/sso_identity.rb +4 -4
- data/app/models/open_loam/sso_provider.rb +66 -0
- data/app/models/open_loam/tenant.rb +20 -0
- data/app/models/{loam → open_loam}/translation.rb +5 -5
- data/app/models/open_loam/webhook_endpoint.rb +39 -0
- data/app/views/{loam → open_loam}/attachments/_attachments.html.erb +1 -1
- data/app/views/{loam → open_loam}/comments/_comments.html.erb +1 -1
- data/app/views/{loam → open_loam}/custom_fields/_fields.html.erb +6 -2
- data/lib/generators/{loam → open_loam}/entity/entity_generator.rb +9 -9
- data/lib/generators/{loam → open_loam}/entity/templates/api_controller.rb +2 -1
- data/lib/generators/{loam → open_loam}/entity/templates/controller.rb +32 -22
- data/lib/generators/{loam → open_loam}/entity/templates/entity_test.rb +12 -12
- data/lib/generators/{loam → open_loam}/entity/templates/migration.rb +5 -5
- data/lib/generators/{loam → open_loam}/entity/templates/model.rb +10 -10
- data/lib/generators/{loam → open_loam}/entity/templates/policy.rb +1 -1
- data/lib/generators/{loam → open_loam}/entity/templates/views/_form.html.erb +8 -5
- data/lib/generators/{loam → open_loam}/entity/templates/views/deleted.html.erb +7 -7
- data/lib/generators/open_loam/entity/templates/views/edit.html.erb +3 -0
- data/lib/generators/open_loam/entity/templates/views/index.html.erb +94 -0
- data/lib/generators/open_loam/entity/templates/views/new.html.erb +3 -0
- data/lib/generators/open_loam/entity/templates/views/show.html.erb +38 -0
- data/lib/generators/{loam → open_loam}/install/install_generator.rb +58 -47
- data/lib/generators/open_loam/install/templates/AGENTS.md +345 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_controller.rb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_index.html.erb +1 -1
- data/lib/generators/open_loam/install/templates/admin/api_tokens_controller.rb +48 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_index.html.erb +23 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/base_controller.rb +101 -38
- data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_form.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/comments_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/admin/configs_controller.rb +9 -9
- data/lib/generators/open_loam/install/templates/admin/dashboard_controller.rb +12 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_form.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/dictionary_entries_controller.rb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/events_controller.rb +7 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/features_controller.rb +9 -9
- data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_controller.rb +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_new.html.erb +2 -2
- data/lib/generators/open_loam/install/templates/admin/history_controller.rb +64 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/history_index.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/imports_controller.rb +25 -13
- data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_new.html.erb +2 -4
- data/lib/generators/open_loam/install/templates/admin/layout.html.erb +76 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_controller.rb +11 -6
- data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_controller.rb +5 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_controller.rb +3 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_index.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_controller.rb +3 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_controller.rb +13 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_index.html.erb +1 -1
- data/lib/generators/open_loam/install/templates/admin/progress_jobs_controller.rb +23 -0
- data/lib/generators/{loam → open_loam}/install/templates/admin/progress_jobs_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/record_locks_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_form.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/search_controller.rb +7 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_controller.rb +33 -34
- data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_controller.rb +6 -6
- data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_form.html.erb +2 -2
- data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_index.html.erb +8 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_controller.rb +7 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_new.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/translations_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/translations_index.html.erb +3 -3
- data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin.css +1 -1
- data/lib/generators/open_loam/install/templates/api_base_controller.rb +127 -0
- data/lib/generators/{loam → open_loam}/install/templates/guardrails_test.rb +17 -17
- data/lib/generators/open_loam/install/templates/import_job.rb +38 -0
- data/lib/generators/{loam → open_loam}/install/templates/inbound_webhooks_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/initializer.rb +87 -75
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_api_tokens.rb +15 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_audit_records.rb +14 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_auth_attempts.rb → open_loam/install/templates/migrations/create_open_loam_auth_attempts.rb} +3 -3
- data/lib/generators/{loam/install/templates/migrations/create_loam_business_rules.rb → open_loam/install/templates/migrations/create_open_loam_business_rules.rb} +10 -10
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_comments.rb +13 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_configs.rb → open_loam/install/templates/migrations/create_open_loam_configs.rb} +7 -7
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_custom_field_values.rb +19 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dashboard_widgets.rb +12 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dictionaries.rb +11 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_dictionary_entries.rb → open_loam/install/templates/migrations/create_open_loam_dictionary_entries.rb} +6 -6
- data/lib/generators/{loam/install/templates/migrations/create_loam_event_deliveries.rb → open_loam/install/templates/migrations/create_open_loam_event_deliveries.rb} +5 -5
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_event_records.rb +13 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_field_definitions.rb → open_loam/install/templates/migrations/create_open_loam_field_definitions.rb} +4 -4
- data/lib/generators/{loam/install/templates/migrations/create_loam_inbound_webhooks.rb → open_loam/install/templates/migrations/create_open_loam_inbound_webhooks.rb} +9 -10
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_memberships.rb +11 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_mfa_credentials.rb → open_loam/install/templates/migrations/create_open_loam_mfa_credentials.rb} +4 -4
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_notifications.rb +15 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_pending_actions.rb → open_loam/install/templates/migrations/create_open_loam_pending_actions.rb} +9 -9
- data/lib/generators/{loam/install/templates/migrations/create_loam_perspectives.rb → open_loam/install/templates/migrations/create_open_loam_perspectives.rb} +5 -5
- data/lib/generators/{loam/install/templates/migrations/create_loam_progress_jobs.rb → open_loam/install/templates/migrations/create_open_loam_progress_jobs.rb} +5 -5
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_record_locks.rb +16 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_scheduled_jobs.rb → open_loam/install/templates/migrations/create_open_loam_scheduled_jobs.rb} +5 -5
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_search_tokens.rb +18 -0
- data/lib/generators/{loam/install/templates/migrations/create_loam_sso_providers.rb → open_loam/install/templates/migrations/create_open_loam_sso_providers.rb} +15 -12
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_tenants.rb +9 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_translations.rb +15 -0
- data/lib/generators/open_loam/install/templates/migrations/create_open_loam_webhook_endpoints.rb +13 -0
- data/lib/generators/{loam → open_loam}/install/templates/migrations/create_users.rb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/user.rb +5 -5
- data/lib/generators/{loam → open_loam}/primary_key_options.rb +23 -23
- data/lib/open-loam.rb +2 -2
- data/lib/{loam → open_loam}/attachable.rb +4 -4
- data/lib/{loam → open_loam}/auditable.rb +23 -23
- data/lib/{loam → open_loam}/auth_throttle.rb +20 -12
- data/lib/{loam → open_loam}/base32.rb +1 -1
- data/lib/{loam → open_loam}/bulk.rb +7 -7
- data/lib/{loam → open_loam}/business_rules/actions.rb +7 -7
- data/lib/{loam → open_loam}/business_rules/condition.rb +5 -5
- data/lib/{loam → open_loam}/business_rules.rb +19 -19
- data/lib/{loam → open_loam}/commentable.rb +6 -6
- data/lib/{loam → open_loam}/configs.rb +19 -19
- data/lib/{loam → open_loam}/cron.rb +2 -2
- data/lib/{loam → open_loam}/csv.rb +2 -2
- data/lib/{loam → open_loam}/current.rb +5 -5
- data/lib/{loam → open_loam}/custom_field_index.rb +33 -30
- data/lib/{loam → open_loam}/custom_fields.rb +17 -17
- data/lib/{loam → open_loam}/dashboard.rb +5 -5
- data/lib/{loam → open_loam}/dictionaries.rb +12 -12
- data/lib/{loam → open_loam}/durable_events.rb +19 -19
- data/lib/{loam → open_loam}/encryptable.rb +39 -34
- data/lib/{loam → open_loam}/encryption/cipher.rb +3 -3
- data/lib/{loam → open_loam}/encryption/key_provider.rb +19 -3
- data/lib/{loam → open_loam}/encryption.rb +58 -15
- data/lib/open_loam/engine.rb +65 -0
- data/lib/{loam → open_loam}/enrichers.rb +5 -5
- data/lib/{loam → open_loam}/errors.rb +20 -10
- data/lib/{loam → open_loam}/eval.rb +2 -2
- data/lib/open_loam/event_log.rb +77 -0
- data/lib/{loam → open_loam}/event_stream.rb +14 -14
- data/lib/{loam → open_loam}/eventful.rb +12 -12
- data/lib/{loam → open_loam}/events.rb +5 -5
- data/lib/{loam → open_loam}/export.rb +12 -12
- data/lib/{loam → open_loam}/features.rb +15 -15
- data/lib/{loam → open_loam}/generated_key.rb +6 -6
- data/lib/{loam → open_loam}/import.rb +12 -15
- data/lib/{loam → open_loam}/inbound_webhooks.rb +19 -18
- data/lib/{loam → open_loam}/lifecycle.rb +54 -25
- data/lib/{loam/locales/loam.en.yml → open_loam/locales/open_loam.en.yml} +5 -5
- data/lib/{loam → open_loam}/mcp/server.rb +9 -9
- data/lib/{loam → open_loam}/mcp.rb +31 -22
- data/lib/{loam → open_loam}/notifications.rb +5 -5
- data/lib/{loam → open_loam}/open_api.rb +16 -16
- data/lib/open_loam/outbound_url.rb +100 -0
- data/lib/{loam → open_loam}/overrides.rb +10 -10
- data/lib/{loam → open_loam}/pending_actions.rb +9 -9
- data/lib/{loam → open_loam}/permissions.rb +8 -8
- data/lib/{loam → open_loam}/perspectives.rb +9 -9
- data/lib/{loam → open_loam}/policy.rb +21 -8
- data/lib/{loam → open_loam}/progress.rb +6 -6
- data/lib/{loam → open_loam}/record_locks.rb +9 -9
- data/lib/{loam → open_loam}/scheduler.rb +20 -20
- data/lib/{loam → open_loam}/search/driver.rb +3 -3
- data/lib/{loam → open_loam}/search/like_driver.rb +5 -5
- data/lib/{loam → open_loam}/search/token_driver.rb +16 -16
- data/lib/{loam → open_loam}/search.rb +5 -5
- data/lib/{loam → open_loam}/searchable.rb +22 -22
- data/lib/{loam → open_loam}/soft_deletable.rb +10 -10
- data/lib/{loam → open_loam}/sso/claims.rb +1 -1
- data/lib/{loam → open_loam}/sso/fake_provider.rb +1 -1
- data/lib/open_loam/sso/http_client.rb +51 -0
- data/lib/{loam → open_loam}/sso/oidc_provider.rb +2 -2
- data/lib/{loam → open_loam}/sso.rb +39 -18
- data/lib/{loam → open_loam}/telemetry.rb +6 -6
- data/lib/{loam → open_loam}/tenant_record.rb +10 -10
- data/lib/{loam → open_loam}/test_helpers.rb +4 -4
- data/lib/{loam → open_loam}/totp.rb +3 -3
- data/lib/{loam → open_loam}/translatable.rb +24 -24
- data/lib/{loam → open_loam}/undo.rb +11 -11
- data/lib/open_loam/version.rb +3 -0
- data/lib/{loam → open_loam}/webhooks.rb +4 -4
- data/lib/{loam → open_loam}/widgets.rb +9 -9
- data/lib/{loam → open_loam}/workflow.rb +45 -45
- data/lib/open_loam.rb +124 -0
- data/lib/tasks/open_loam.rake +203 -0
- data/lib/tasks/{loam_eval.rake → open_loam_eval.rake} +7 -7
- data/lib/tasks/open_loam_mcp.rake +20 -0
- metadata +247 -242
- data/app/models/loam/api_token.rb +0 -40
- data/app/models/loam/dictionary.rb +0 -20
- data/app/models/loam/search_token.rb +0 -9
- data/app/models/loam/sso_provider.rb +0 -35
- data/app/models/loam/tenant.rb +0 -20
- data/app/models/loam/webhook_endpoint.rb +0 -26
- data/lib/generators/loam/entity/templates/views/edit.html.erb +0 -3
- data/lib/generators/loam/entity/templates/views/index.html.erb +0 -90
- data/lib/generators/loam/entity/templates/views/new.html.erb +0 -3
- data/lib/generators/loam/entity/templates/views/show.html.erb +0 -36
- data/lib/generators/loam/install/templates/AGENTS.md +0 -341
- data/lib/generators/loam/install/templates/admin/api_tokens_controller.rb +0 -30
- data/lib/generators/loam/install/templates/admin/dashboard_controller.rb +0 -10
- data/lib/generators/loam/install/templates/admin/history_controller.rb +0 -38
- data/lib/generators/loam/install/templates/admin/layout.html.erb +0 -76
- data/lib/generators/loam/install/templates/admin/progress_jobs_controller.rb +0 -19
- data/lib/generators/loam/install/templates/api_base_controller.rb +0 -90
- data/lib/generators/loam/install/templates/import_job.rb +0 -25
- data/lib/generators/loam/install/templates/migrations/create_loam_api_tokens.rb +0 -15
- data/lib/generators/loam/install/templates/migrations/create_loam_audit_records.rb +0 -14
- data/lib/generators/loam/install/templates/migrations/create_loam_comments.rb +0 -13
- data/lib/generators/loam/install/templates/migrations/create_loam_custom_field_values.rb +0 -19
- data/lib/generators/loam/install/templates/migrations/create_loam_dashboard_widgets.rb +0 -12
- data/lib/generators/loam/install/templates/migrations/create_loam_dictionaries.rb +0 -11
- data/lib/generators/loam/install/templates/migrations/create_loam_memberships.rb +0 -11
- data/lib/generators/loam/install/templates/migrations/create_loam_notifications.rb +0 -15
- data/lib/generators/loam/install/templates/migrations/create_loam_record_locks.rb +0 -16
- data/lib/generators/loam/install/templates/migrations/create_loam_search_tokens.rb +0 -18
- data/lib/generators/loam/install/templates/migrations/create_loam_tenants.rb +0 -9
- data/lib/generators/loam/install/templates/migrations/create_loam_translations.rb +0 -15
- data/lib/generators/loam/install/templates/migrations/create_loam_webhook_endpoints.rb +0 -13
- data/lib/loam/engine.rb +0 -57
- data/lib/loam/sso/http_client.rb +0 -42
- data/lib/loam/version.rb +0 -3
- data/lib/loam.rb +0 -122
- data/lib/tasks/loam.rake +0 -171
- data/lib/tasks/loam_mcp.rake +0 -20
- /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/features_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_preview.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_summary.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_activated.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_show.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/pagination.rb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/search_index.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_mfa_challenge.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_edit.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_new.html.erb +0 -0
- /data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_new.html.erb +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
namespace :open_loam do
|
|
2
|
+
desc "Re-run every OpenLoam.on_tenant_created callback for every existing tenant (idempotent)"
|
|
3
|
+
task sync: :environment do
|
|
4
|
+
synced = OpenLoam.sync_tenants!
|
|
5
|
+
puts "open_loam:sync — ran #{OpenLoam.tenant_created_callbacks.size} tenant callback(s) across #{synced} tenant(s)."
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
namespace :openapi do
|
|
9
|
+
# Write the OpenAPI 3.1 document + a Markdown rendering to disk, for CI or
|
|
10
|
+
# publishing. Introspection only — no server, no network.
|
|
11
|
+
#
|
|
12
|
+
# bin/rails open_loam:openapi:export
|
|
13
|
+
desc "Export the API's OpenAPI JSON + Markdown to doc/"
|
|
14
|
+
task export: :environment do
|
|
15
|
+
require "json"
|
|
16
|
+
dir = ENV["DIR"].presence || "doc"
|
|
17
|
+
FileUtils.mkdir_p(dir)
|
|
18
|
+
File.write(File.join(dir, "openapi.json"), JSON.pretty_generate(OpenLoam::OpenApi.document))
|
|
19
|
+
File.write(File.join(dir, "openapi.md"), OpenLoam::OpenApi.markdown)
|
|
20
|
+
puts "open_loam:openapi:export — wrote #{dir}/openapi.json and #{dir}/openapi.md."
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
namespace :scheduler do
|
|
25
|
+
# Fire every due recurring job once. Wire to system cron, every minute:
|
|
26
|
+
# * * * * * cd /app && bin/rails open_loam:scheduler:tick
|
|
27
|
+
# The claim is atomic, so running this from several hosts never double-fires
|
|
28
|
+
# a job (Postgres SKIP LOCKED; SQLite serializes the single-process claim).
|
|
29
|
+
desc "Enqueue every due OpenLoam::ScheduledJob (run from cron)"
|
|
30
|
+
task tick: :environment do
|
|
31
|
+
fired = OpenLoam::Scheduler.tick
|
|
32
|
+
puts "open_loam:scheduler:tick — fired #{fired} scheduled job(s)."
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
namespace :index do
|
|
37
|
+
# Rebuild the custom-field read-model index (OpenLoam::CustomFieldIndex) for every
|
|
38
|
+
# entity with custom fields, in every tenant. Run once after enabling it so
|
|
39
|
+
# existing rows are projected; new/updated records index themselves on save.
|
|
40
|
+
#
|
|
41
|
+
# bin/rails open_loam:index:reindex
|
|
42
|
+
desc "Rebuild the custom-field read-model index for every model in every tenant"
|
|
43
|
+
task reindex: :environment do
|
|
44
|
+
Rails.application.eager_load!
|
|
45
|
+
models = OpenLoam::TenantRecord.descendants.select do |model|
|
|
46
|
+
model.name.present? && model.respond_to?(:custom_field_definitions)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
tenants = 0
|
|
50
|
+
OpenLoam::Tenant.find_each do |tenant|
|
|
51
|
+
OpenLoam.as_tenant(tenant) { models.each { |model| OpenLoam::CustomFieldIndex.reindex(model) } }
|
|
52
|
+
tenants += 1
|
|
53
|
+
end
|
|
54
|
+
puts "open_loam:index:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s)."
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Report custom-field index coverage (indexed vs expected) per model/field
|
|
58
|
+
# per tenant — the trust signal for whether the index is complete or drifting.
|
|
59
|
+
#
|
|
60
|
+
# bin/rails open_loam:index:coverage
|
|
61
|
+
desc "Report custom-field index coverage per model/field per tenant"
|
|
62
|
+
task coverage: :environment do
|
|
63
|
+
Rails.application.eager_load!
|
|
64
|
+
models = OpenLoam::TenantRecord.descendants.select do |model|
|
|
65
|
+
model.name.present? && model.respond_to?(:custom_field_definitions)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
OpenLoam::Tenant.find_each do |tenant|
|
|
69
|
+
OpenLoam.as_tenant(tenant) do
|
|
70
|
+
models.each do |model|
|
|
71
|
+
model.custom_field_definitions.find_each do |definition|
|
|
72
|
+
c = OpenLoam::CustomFieldIndex.coverage(model, definition.name)
|
|
73
|
+
flag = c[:complete] ? "ok" : "GAP"
|
|
74
|
+
puts " [#{flag}] #{tenant.slug} #{model.name}.#{definition.name}: #{c[:indexed]}/#{c[:expected]} indexed"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
namespace :search do
|
|
83
|
+
# Rebuild the active driver's search index for every searchable model in
|
|
84
|
+
# every tenant. Needed once after switching to a driver that keeps an index
|
|
85
|
+
# (OpenLoam::Search::TokenDriver): existing rows have no tokens until reindexed,
|
|
86
|
+
# while new and updated records index themselves on save. A no-op under the
|
|
87
|
+
# default LikeDriver (its reindex does nothing), so it is always safe to run.
|
|
88
|
+
#
|
|
89
|
+
# bin/rails open_loam:search:reindex
|
|
90
|
+
desc "Rebuild the search index for every searchable model in every tenant"
|
|
91
|
+
task reindex: :environment do
|
|
92
|
+
Rails.application.eager_load!
|
|
93
|
+
models = OpenLoam::TenantRecord.descendants.select do |model|
|
|
94
|
+
model.name.present? && model.respond_to?(:open_loam_searchable?) && model.open_loam_searchable?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
tenants = 0
|
|
98
|
+
OpenLoam::Tenant.find_each do |tenant|
|
|
99
|
+
OpenLoam.as_tenant(tenant) { models.each { |model| OpenLoam::Search.reindex(model) } }
|
|
100
|
+
tenants += 1
|
|
101
|
+
end
|
|
102
|
+
puts "open_loam:search:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s) using #{OpenLoam::Search.driver}."
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
namespace :sso do
|
|
107
|
+
# Domain ownership can only be granted from OUTSIDE the tenant: the manager
|
|
108
|
+
# who typed the domain is the party this check exists to constrain. Confirm
|
|
109
|
+
# ownership out of band (DNS TXT, a signed request from the domain's
|
|
110
|
+
# operator, an existing contract) BEFORE running this.
|
|
111
|
+
#
|
|
112
|
+
# bin/rails open_loam:sso:verify_domain[42]
|
|
113
|
+
desc "Mark an SSO provider's domain as proven-owned (operator only)"
|
|
114
|
+
task :verify_domain, %i[provider_id] => :environment do |_task, args|
|
|
115
|
+
provider = OpenLoam::SsoProvider.unscoped.find(args[:provider_id])
|
|
116
|
+
tenant = OpenLoam::Tenant.find(provider.tenant_id)
|
|
117
|
+
OpenLoam.as_tenant(tenant) { provider.verify_domain! }
|
|
118
|
+
puts "open_loam:sso:verify_domain — #{provider.domain} verified for tenant #{tenant.slug} (provider #{provider.id})."
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
desc "Revoke an SSO provider's domain verification"
|
|
122
|
+
task :unverify_domain, %i[provider_id] => :environment do |_task, args|
|
|
123
|
+
provider = OpenLoam::SsoProvider.unscoped.find(args[:provider_id])
|
|
124
|
+
tenant = OpenLoam::Tenant.find(provider.tenant_id)
|
|
125
|
+
OpenLoam.as_tenant(tenant) { provider.update!(domain_verified_at: nil) }
|
|
126
|
+
puts "open_loam:sso:unverify_domain — #{provider.domain} is no longer verified."
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
desc "List SSO providers and their domain-verification state"
|
|
130
|
+
task providers: :environment do
|
|
131
|
+
OpenLoam::SsoProvider.unscoped.order(:domain).each do |provider|
|
|
132
|
+
state = provider.domain_verified? ? "verified #{provider.domain_verified_at.to_fs(:db)}" : "UNVERIFIED"
|
|
133
|
+
puts format("%-6s %-30s tenant=%-6s %s", provider.id, provider.domain, provider.tenant_id, state)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
namespace :encryption do
|
|
139
|
+
# Rotate a tenant's encrypted data under the current key: read each record's
|
|
140
|
+
# encrypted fields (old key) and re-seal them (new key), one record at a
|
|
141
|
+
# time. The version tag in the stored format means old and new ciphertext
|
|
142
|
+
# coexist, so this can run incrementally without downtime. Each record is an
|
|
143
|
+
# ordinary audited "[encrypted]" update.
|
|
144
|
+
#
|
|
145
|
+
# bin/rails open_loam:encryption:rotate[Customer,42]
|
|
146
|
+
desc "Re-encrypt a model's encrypted fields for one tenant (rotation step)"
|
|
147
|
+
task :rotate, %i[model tenant_id] => :environment do |_task, args|
|
|
148
|
+
model = fetch_encryptable_model(args[:model])
|
|
149
|
+
tenant = OpenLoam::Tenant.find(args[:tenant_id])
|
|
150
|
+
|
|
151
|
+
count = 0
|
|
152
|
+
OpenLoam.as_tenant(tenant) do
|
|
153
|
+
each_record(model) do |record|
|
|
154
|
+
record.open_loam_reencrypt!
|
|
155
|
+
count += 1
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
puts "open_loam:encryption:rotate — re-encrypted #{count} #{model.name} record(s) in tenant #{tenant.slug}."
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Decrypt and print one tenant's encrypted fields, e.g. for a GDPR data
|
|
162
|
+
# export or a migration. OPERATIONAL CAUTION: this prints plaintext PII to
|
|
163
|
+
# stdout — run it only where that output is safe (never into shared logs or
|
|
164
|
+
# a shell history that syncs), and only for a tenant you are authorized to
|
|
165
|
+
# export.
|
|
166
|
+
#
|
|
167
|
+
# bin/rails open_loam:encryption:decrypt_dump[Customer,42]
|
|
168
|
+
desc "Print decrypted encrypted-field values for one tenant (GDPR export; handle with care)"
|
|
169
|
+
task :decrypt_dump, %i[model tenant_id] => :environment do |_task, args|
|
|
170
|
+
require "json"
|
|
171
|
+
model = fetch_encryptable_model(args[:model])
|
|
172
|
+
tenant = OpenLoam::Tenant.find(args[:tenant_id])
|
|
173
|
+
fields = model.open_loam_encrypted_attributes
|
|
174
|
+
|
|
175
|
+
OpenLoam.as_tenant(tenant) do
|
|
176
|
+
each_record(model) do |record|
|
|
177
|
+
row = { id: record.id }.merge(fields.index_with { |field| record.public_send(field) })
|
|
178
|
+
puts row.to_json
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Resolve a model name to a class that actually uses OpenLoam::Encryptable — a typo
|
|
186
|
+
# or a plain model should fail loudly, not silently dump/rotate nothing.
|
|
187
|
+
def fetch_encryptable_model(name)
|
|
188
|
+
# Force the app's classes (and OpenLoam::TenantRecord, required lazily via the
|
|
189
|
+
# active_record on_load hook) to load before we constantize a model name.
|
|
190
|
+
Rails.application.eager_load!
|
|
191
|
+
model = name.to_s.constantize
|
|
192
|
+
unless model.respond_to?(:open_loam_encrypted_attributes) && model.open_loam_encrypted_attributes.any?
|
|
193
|
+
abort "#{name} does not `include OpenLoam::Encryptable` with any `encrypts` fields."
|
|
194
|
+
end
|
|
195
|
+
model
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Iterate every record, soft-deleted ones included (a GDPR export must not miss
|
|
199
|
+
# data hidden in the recycle bin), staying inside the current tenant scope.
|
|
200
|
+
def each_record(model, &block)
|
|
201
|
+
scope = model.respond_to?(:with_deleted) ? model.with_deleted : model.all
|
|
202
|
+
scope.find_each(&block)
|
|
203
|
+
end
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
require "json"
|
|
2
2
|
require "fileutils"
|
|
3
3
|
|
|
4
|
-
namespace :
|
|
4
|
+
namespace :open_loam do
|
|
5
5
|
# Score the app's current test suite as a golden-task eval result and record it
|
|
6
|
-
# under ai/benchmark_runs/ (L-303). Run this in a
|
|
6
|
+
# under ai/benchmark_runs/ (L-303). Run this in a OpenLoam app AFTER an agent (or
|
|
7
7
|
# you) has implemented a golden task:
|
|
8
8
|
#
|
|
9
|
-
# bin/rails "
|
|
10
|
-
# bin/rails "
|
|
9
|
+
# bin/rails "open_loam:eval[2]" # task 2, tests only
|
|
10
|
+
# bin/rails "open_loam:eval[2,tenancy_leak:unscoped]" # note an invariant breach
|
|
11
11
|
#
|
|
12
12
|
# Exits non-zero if the task did not pass, so it drops straight into CI.
|
|
13
|
-
desc "Score the current test suite as a golden-task eval result (
|
|
13
|
+
desc "Score the current test suite as a golden-task eval result (open_loam:eval[task,violation,violation,...])"
|
|
14
14
|
task :eval, [ :task ] => :environment do |_task, args|
|
|
15
15
|
task_id = args[:task] || "unspecified"
|
|
16
16
|
violations = args.extras # any positional args after the task id are violations
|
|
17
17
|
|
|
18
18
|
output = `bin/rails test 2>&1`
|
|
19
|
-
summary =
|
|
20
|
-
card =
|
|
19
|
+
summary = OpenLoam::Eval.parse_summary(output)
|
|
20
|
+
card = OpenLoam::Eval.scorecard(task: task_id, summary: summary, violations: violations)
|
|
21
21
|
|
|
22
22
|
dir = Rails.root.join("ai", "benchmark_runs")
|
|
23
23
|
FileUtils.mkdir_p(dir)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "logger"
|
|
2
|
+
|
|
3
|
+
namespace :open_loam do
|
|
4
|
+
namespace :mcp do
|
|
5
|
+
# Serve the OpenLoam MCP server over stdio. Point an MCP client (Claude Code,
|
|
6
|
+
# Cursor, Codex) at `bin/rails open_loam:mcp:serve` with OPEN_LOAM_MCP_TOKEN set to a
|
|
7
|
+
# OpenLoam API token — the agent then acts as that token's user, in that tenant.
|
|
8
|
+
#
|
|
9
|
+
# stdout carries JSON-RPC only; every log is sent to stderr so it can't
|
|
10
|
+
# corrupt the stream.
|
|
11
|
+
desc "Serve the OpenLoam MCP server over stdio (auth via OPEN_LOAM_MCP_TOKEN)"
|
|
12
|
+
task serve: :environment do
|
|
13
|
+
Rails.logger = Logger.new($stderr)
|
|
14
|
+
ActiveRecord::Base.logger = Rails.logger
|
|
15
|
+
$stdout.sync = true
|
|
16
|
+
|
|
17
|
+
OpenLoam::Mcp::Server.new.run
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|