open-loam 0.1.0 → 0.2.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 +48 -8
- data/LICENSE +1 -1
- data/README.md +24 -24
- 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/{loam → open_loam}/event_redelivery_sweep_job.rb +4 -4
- data/app/jobs/{loam → open_loam}/webhook_delivery_job.rb +7 -7
- data/app/models/{loam → open_loam}/api_token.rb +7 -7
- 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/{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 +23 -23
- 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/{loam → open_loam}/sso_provider.rb +8 -8
- data/app/models/open_loam/tenant.rb +20 -0
- data/app/models/{loam → open_loam}/translation.rb +5 -5
- data/app/models/{loam → open_loam}/webhook_endpoint.rb +6 -6
- 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 +2 -2
- data/lib/generators/{loam → open_loam}/entity/entity_generator.rb +9 -9
- data/lib/generators/{loam → open_loam}/entity/templates/api_controller.rb +1 -1
- data/lib/generators/{loam → open_loam}/entity/templates/controller.rb +21 -21
- 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 +4 -4
- 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 +90 -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 +36 -0
- data/lib/generators/{loam → open_loam}/install/install_generator.rb +47 -47
- data/lib/generators/open_loam/install/templates/AGENTS.md +341 -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/{loam → open_loam}/install/templates/admin/api_tokens_controller.rb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/base_controller.rb +38 -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 +10 -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 +5 -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/{loam → open_loam}/install/templates/admin/history_controller.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/admin/history_index.html.erb +1 -1
- data/lib/generators/{loam → open_loam}/install/templates/admin/imports_controller.rb +12 -12
- data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_controller.rb +6 -6
- data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_new.html.erb +2 -2
- 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 +6 -6
- data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_controller.rb +3 -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 +7 -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 +19 -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 +5 -5
- data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_controller.rb +32 -32
- 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/sudo_controller.rb +5 -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/{loam → open_loam}/install/templates/api_base_controller.rb +15 -15
- data/lib/generators/{loam → open_loam}/install/templates/guardrails_test.rb +17 -17
- data/lib/generators/{loam → open_loam}/install/templates/import_job.rb +7 -7
- data/lib/generators/{loam → open_loam}/install/templates/inbound_webhooks_controller.rb +4 -4
- data/lib/generators/{loam → open_loam}/install/templates/initializer.rb +74 -74
- 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/{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 -9
- 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} +12 -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 +10 -10
- 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 +23 -23
- 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 +33 -33
- data/lib/{loam → open_loam}/encryption/cipher.rb +3 -3
- data/lib/{loam → open_loam}/encryption/key_provider.rb +3 -3
- data/lib/{loam → open_loam}/encryption.rb +11 -11
- data/lib/open_loam/engine.rb +57 -0
- data/lib/{loam → open_loam}/enrichers.rb +5 -5
- data/lib/{loam → open_loam}/errors.rb +10 -10
- data/lib/{loam → open_loam}/eval.rb +2 -2
- 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 +8 -8
- 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 -12
- data/lib/{loam → open_loam}/inbound_webhooks.rb +7 -7
- data/lib/{loam → open_loam}/lifecycle.rb +25 -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 +21 -21
- data/lib/{loam → open_loam}/notifications.rb +5 -5
- data/lib/{loam → open_loam}/open_api.rb +16 -16
- 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 +6 -6
- 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 +15 -15
- 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/{loam → open_loam}/sso/http_client.rb +3 -3
- data/lib/{loam → open_loam}/sso/oidc_provider.rb +2 -2
- data/lib/{loam → open_loam}/sso.rb +17 -17
- 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 +122 -0
- data/lib/tasks/{loam.rake → open_loam.rake} +43 -43
- data/lib/tasks/{loam_eval.rake → open_loam_eval.rake} +7 -7
- data/lib/tasks/open_loam_mcp.rake +20 -0
- metadata +242 -242
- data/app/models/loam/dictionary.rb +0 -20
- data/app/models/loam/search_token.rb +0 -9
- data/app/models/loam/tenant.rb +0 -20
- 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/dashboard_controller.rb +0 -10
- 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/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/version.rb +0 -3
- data/lib/loam.rb +0 -122
- data/lib/tasks/loam_mcp.rake +0 -20
- /data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_index.html.erb +0 -0
- /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_index.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
data/lib/open_loam.rb
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require "open_loam/version"
|
|
2
|
+
require "open_loam/errors"
|
|
3
|
+
require "open_loam/current"
|
|
4
|
+
require "open_loam/events"
|
|
5
|
+
require "open_loam/policy"
|
|
6
|
+
require "open_loam/lifecycle"
|
|
7
|
+
require "open_loam/configs"
|
|
8
|
+
require "open_loam/features"
|
|
9
|
+
require "open_loam/auth_throttle"
|
|
10
|
+
require "open_loam/dictionaries"
|
|
11
|
+
require "open_loam/custom_field_index"
|
|
12
|
+
require "open_loam/undo"
|
|
13
|
+
require "open_loam/permissions"
|
|
14
|
+
require "open_loam/telemetry"
|
|
15
|
+
require "open_loam/eval"
|
|
16
|
+
require "open_loam/mcp"
|
|
17
|
+
require "open_loam/mcp/server"
|
|
18
|
+
require "open_loam/progress"
|
|
19
|
+
require "open_loam/cron"
|
|
20
|
+
require "open_loam/scheduler"
|
|
21
|
+
require "open_loam/csv"
|
|
22
|
+
require "open_loam/export"
|
|
23
|
+
require "open_loam/import"
|
|
24
|
+
require "open_loam/bulk"
|
|
25
|
+
require "open_loam/widgets"
|
|
26
|
+
require "open_loam/dashboard"
|
|
27
|
+
require "open_loam/overrides"
|
|
28
|
+
require "open_loam/open_api"
|
|
29
|
+
require "open_loam/encryption"
|
|
30
|
+
require "open_loam/base32"
|
|
31
|
+
require "open_loam/totp"
|
|
32
|
+
require "open_loam/pending_actions"
|
|
33
|
+
require "open_loam/perspectives"
|
|
34
|
+
require "open_loam/record_locks"
|
|
35
|
+
require "open_loam/event_stream"
|
|
36
|
+
require "open_loam/enrichers"
|
|
37
|
+
require "open_loam/search"
|
|
38
|
+
require "open_loam/search/driver"
|
|
39
|
+
require "open_loam/search/like_driver"
|
|
40
|
+
require "open_loam/search/token_driver"
|
|
41
|
+
require "open_loam/notifications"
|
|
42
|
+
require "open_loam/sso"
|
|
43
|
+
require "open_loam/business_rules"
|
|
44
|
+
require "open_loam/webhooks"
|
|
45
|
+
require "open_loam/inbound_webhooks"
|
|
46
|
+
require "open_loam/durable_events"
|
|
47
|
+
require "open_loam/engine" if defined?(Rails::Engine)
|
|
48
|
+
|
|
49
|
+
module OpenLoam
|
|
50
|
+
# The current tenant, or a loud failure. This is THE guardrail: tenant-scoped
|
|
51
|
+
# code paths call this, so a missing tenant context can never silently widen
|
|
52
|
+
# a query to all tenants.
|
|
53
|
+
def self.tenant!
|
|
54
|
+
Current.tenant or raise MissingTenantError
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.tenant
|
|
58
|
+
Current.tenant
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.actor
|
|
62
|
+
Current.actor
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Feature-string permission check for the current actor's role (see
|
|
66
|
+
# OpenLoam::Permissions) — deny-by-default, wildcard-aware. `role:` overrides the
|
|
67
|
+
# actor's role. Returns false with no actor/role.
|
|
68
|
+
def self.can?(permission, role: nil)
|
|
69
|
+
role ||= Current.actor && OpenLoam::Membership.find_by(user_id: Current.actor.id)&.role
|
|
70
|
+
OpenLoam::Permissions.allow?(role, permission)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# The approval-gate seam. When a caller runs under :confirm (an MCP tool acting
|
|
74
|
+
# for an AI agent), a write should be STAGED for human approval via
|
|
75
|
+
# OpenLoam::PendingActions.stage instead of committed. OpenLoam does not intercept
|
|
76
|
+
# Active Record globally — this is the documented hook a write path checks.
|
|
77
|
+
def self.mutation_mode
|
|
78
|
+
Current.mutation_mode || :direct
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.require_confirmation?
|
|
82
|
+
mutation_mode == :confirm
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Run a block with writes gated for approval. The one blessed way to enter
|
|
86
|
+
# confirm-mode; restores the previous mode afterwards.
|
|
87
|
+
def self.with_confirmation
|
|
88
|
+
previous = Current.mutation_mode
|
|
89
|
+
Current.mutation_mode = :confirm
|
|
90
|
+
yield
|
|
91
|
+
ensure
|
|
92
|
+
Current.mutation_mode = previous
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Run a block inside a tenant (and optional actor) context, restoring the
|
|
96
|
+
# previous context afterwards. The one blessed way to switch tenants.
|
|
97
|
+
def self.as_tenant(tenant, actor: nil)
|
|
98
|
+
previous_tenant = Current.tenant
|
|
99
|
+
previous_actor = Current.actor
|
|
100
|
+
Current.tenant = tenant
|
|
101
|
+
Current.actor = actor if actor
|
|
102
|
+
yield
|
|
103
|
+
ensure
|
|
104
|
+
Current.tenant = previous_tenant
|
|
105
|
+
Current.actor = previous_actor
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
ActiveSupport.on_load(:active_record) do
|
|
110
|
+
require "open_loam/generated_key"
|
|
111
|
+
require "open_loam/tenant_record"
|
|
112
|
+
require "open_loam/auditable"
|
|
113
|
+
require "open_loam/soft_deletable"
|
|
114
|
+
require "open_loam/eventful"
|
|
115
|
+
require "open_loam/custom_fields"
|
|
116
|
+
require "open_loam/workflow"
|
|
117
|
+
require "open_loam/searchable"
|
|
118
|
+
require "open_loam/encryptable"
|
|
119
|
+
require "open_loam/translatable"
|
|
120
|
+
require "open_loam/commentable"
|
|
121
|
+
require "open_loam/attachable"
|
|
122
|
+
end
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
namespace :
|
|
2
|
-
desc "Re-run every
|
|
1
|
+
namespace :open_loam do
|
|
2
|
+
desc "Re-run every OpenLoam.on_tenant_created callback for every existing tenant (idempotent)"
|
|
3
3
|
task sync: :environment do
|
|
4
|
-
synced =
|
|
5
|
-
puts "
|
|
4
|
+
synced = OpenLoam.sync_tenants!
|
|
5
|
+
puts "open_loam:sync — ran #{OpenLoam.tenant_created_callbacks.size} tenant callback(s) across #{synced} tenant(s)."
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
namespace :openapi do
|
|
9
9
|
# Write the OpenAPI 3.1 document + a Markdown rendering to disk, for CI or
|
|
10
10
|
# publishing. Introspection only — no server, no network.
|
|
11
11
|
#
|
|
12
|
-
# bin/rails
|
|
12
|
+
# bin/rails open_loam:openapi:export
|
|
13
13
|
desc "Export the API's OpenAPI JSON + Markdown to doc/"
|
|
14
14
|
task export: :environment do
|
|
15
15
|
require "json"
|
|
16
16
|
dir = ENV["DIR"].presence || "doc"
|
|
17
17
|
FileUtils.mkdir_p(dir)
|
|
18
|
-
File.write(File.join(dir, "openapi.json"), JSON.pretty_generate(
|
|
19
|
-
File.write(File.join(dir, "openapi.md"),
|
|
20
|
-
puts "
|
|
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
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
namespace :scheduler do
|
|
25
25
|
# Fire every due recurring job once. Wire to system cron, every minute:
|
|
26
|
-
# * * * * * cd /app && bin/rails
|
|
26
|
+
# * * * * * cd /app && bin/rails open_loam:scheduler:tick
|
|
27
27
|
# The claim is atomic, so running this from several hosts never double-fires
|
|
28
28
|
# a job (Postgres SKIP LOCKED; SQLite serializes the single-process claim).
|
|
29
|
-
desc "Enqueue every due
|
|
29
|
+
desc "Enqueue every due OpenLoam::ScheduledJob (run from cron)"
|
|
30
30
|
task tick: :environment do
|
|
31
|
-
fired =
|
|
32
|
-
puts "
|
|
31
|
+
fired = OpenLoam::Scheduler.tick
|
|
32
|
+
puts "open_loam:scheduler:tick — fired #{fired} scheduled job(s)."
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
namespace :index do
|
|
37
|
-
# Rebuild the custom-field read-model index (
|
|
37
|
+
# Rebuild the custom-field read-model index (OpenLoam::CustomFieldIndex) for every
|
|
38
38
|
# entity with custom fields, in every tenant. Run once after enabling it so
|
|
39
39
|
# existing rows are projected; new/updated records index themselves on save.
|
|
40
40
|
#
|
|
41
|
-
# bin/rails
|
|
41
|
+
# bin/rails open_loam:index:reindex
|
|
42
42
|
desc "Rebuild the custom-field read-model index for every model in every tenant"
|
|
43
43
|
task reindex: :environment do
|
|
44
44
|
Rails.application.eager_load!
|
|
45
|
-
models =
|
|
45
|
+
models = OpenLoam::TenantRecord.descendants.select do |model|
|
|
46
46
|
model.name.present? && model.respond_to?(:custom_field_definitions)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
tenants = 0
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
OpenLoam::Tenant.find_each do |tenant|
|
|
51
|
+
OpenLoam.as_tenant(tenant) { models.each { |model| OpenLoam::CustomFieldIndex.reindex(model) } }
|
|
52
52
|
tenants += 1
|
|
53
53
|
end
|
|
54
|
-
puts "
|
|
54
|
+
puts "open_loam:index:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s)."
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# Report custom-field index coverage (indexed vs expected) per model/field
|
|
58
58
|
# per tenant — the trust signal for whether the index is complete or drifting.
|
|
59
59
|
#
|
|
60
|
-
# bin/rails
|
|
60
|
+
# bin/rails open_loam:index:coverage
|
|
61
61
|
desc "Report custom-field index coverage per model/field per tenant"
|
|
62
62
|
task coverage: :environment do
|
|
63
63
|
Rails.application.eager_load!
|
|
64
|
-
models =
|
|
64
|
+
models = OpenLoam::TenantRecord.descendants.select do |model|
|
|
65
65
|
model.name.present? && model.respond_to?(:custom_field_definitions)
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
OpenLoam::Tenant.find_each do |tenant|
|
|
69
|
+
OpenLoam.as_tenant(tenant) do
|
|
70
70
|
models.each do |model|
|
|
71
71
|
model.custom_field_definitions.find_each do |definition|
|
|
72
|
-
c =
|
|
72
|
+
c = OpenLoam::CustomFieldIndex.coverage(model, definition.name)
|
|
73
73
|
flag = c[:complete] ? "ok" : "GAP"
|
|
74
74
|
puts " [#{flag}] #{tenant.slug} #{model.name}.#{definition.name}: #{c[:indexed]}/#{c[:expected]} indexed"
|
|
75
75
|
end
|
|
@@ -82,24 +82,24 @@ namespace :loam do
|
|
|
82
82
|
namespace :search do
|
|
83
83
|
# Rebuild the active driver's search index for every searchable model in
|
|
84
84
|
# every tenant. Needed once after switching to a driver that keeps an index
|
|
85
|
-
# (
|
|
85
|
+
# (OpenLoam::Search::TokenDriver): existing rows have no tokens until reindexed,
|
|
86
86
|
# while new and updated records index themselves on save. A no-op under the
|
|
87
87
|
# default LikeDriver (its reindex does nothing), so it is always safe to run.
|
|
88
88
|
#
|
|
89
|
-
# bin/rails
|
|
89
|
+
# bin/rails open_loam:search:reindex
|
|
90
90
|
desc "Rebuild the search index for every searchable model in every tenant"
|
|
91
91
|
task reindex: :environment do
|
|
92
92
|
Rails.application.eager_load!
|
|
93
|
-
models =
|
|
94
|
-
model.name.present? && model.respond_to?(:
|
|
93
|
+
models = OpenLoam::TenantRecord.descendants.select do |model|
|
|
94
|
+
model.name.present? && model.respond_to?(:open_loam_searchable?) && model.open_loam_searchable?
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
tenants = 0
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
OpenLoam::Tenant.find_each do |tenant|
|
|
99
|
+
OpenLoam.as_tenant(tenant) { models.each { |model| OpenLoam::Search.reindex(model) } }
|
|
100
100
|
tenants += 1
|
|
101
101
|
end
|
|
102
|
-
puts "
|
|
102
|
+
puts "open_loam:search:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s) using #{OpenLoam::Search.driver}."
|
|
103
103
|
end
|
|
104
104
|
end
|
|
105
105
|
|
|
@@ -110,20 +110,20 @@ namespace :loam do
|
|
|
110
110
|
# coexist, so this can run incrementally without downtime. Each record is an
|
|
111
111
|
# ordinary audited "[encrypted]" update.
|
|
112
112
|
#
|
|
113
|
-
# bin/rails
|
|
113
|
+
# bin/rails open_loam:encryption:rotate[Customer,42]
|
|
114
114
|
desc "Re-encrypt a model's encrypted fields for one tenant (rotation step)"
|
|
115
115
|
task :rotate, %i[model tenant_id] => :environment do |_task, args|
|
|
116
116
|
model = fetch_encryptable_model(args[:model])
|
|
117
|
-
tenant =
|
|
117
|
+
tenant = OpenLoam::Tenant.find(args[:tenant_id])
|
|
118
118
|
|
|
119
119
|
count = 0
|
|
120
|
-
|
|
120
|
+
OpenLoam.as_tenant(tenant) do
|
|
121
121
|
each_record(model) do |record|
|
|
122
|
-
record.
|
|
122
|
+
record.open_loam_reencrypt!
|
|
123
123
|
count += 1
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
|
-
puts "
|
|
126
|
+
puts "open_loam:encryption:rotate — re-encrypted #{count} #{model.name} record(s) in tenant #{tenant.slug}."
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
# Decrypt and print one tenant's encrypted fields, e.g. for a GDPR data
|
|
@@ -132,15 +132,15 @@ namespace :loam do
|
|
|
132
132
|
# a shell history that syncs), and only for a tenant you are authorized to
|
|
133
133
|
# export.
|
|
134
134
|
#
|
|
135
|
-
# bin/rails
|
|
135
|
+
# bin/rails open_loam:encryption:decrypt_dump[Customer,42]
|
|
136
136
|
desc "Print decrypted encrypted-field values for one tenant (GDPR export; handle with care)"
|
|
137
137
|
task :decrypt_dump, %i[model tenant_id] => :environment do |_task, args|
|
|
138
138
|
require "json"
|
|
139
139
|
model = fetch_encryptable_model(args[:model])
|
|
140
|
-
tenant =
|
|
141
|
-
fields = model.
|
|
140
|
+
tenant = OpenLoam::Tenant.find(args[:tenant_id])
|
|
141
|
+
fields = model.open_loam_encrypted_attributes
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
OpenLoam.as_tenant(tenant) do
|
|
144
144
|
each_record(model) do |record|
|
|
145
145
|
row = { id: record.id }.merge(fields.index_with { |field| record.public_send(field) })
|
|
146
146
|
puts row.to_json
|
|
@@ -150,15 +150,15 @@ namespace :loam do
|
|
|
150
150
|
end
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
# Resolve a model name to a class that actually uses
|
|
153
|
+
# Resolve a model name to a class that actually uses OpenLoam::Encryptable — a typo
|
|
154
154
|
# or a plain model should fail loudly, not silently dump/rotate nothing.
|
|
155
155
|
def fetch_encryptable_model(name)
|
|
156
|
-
# Force the app's classes (and
|
|
156
|
+
# Force the app's classes (and OpenLoam::TenantRecord, required lazily via the
|
|
157
157
|
# active_record on_load hook) to load before we constantize a model name.
|
|
158
158
|
Rails.application.eager_load!
|
|
159
159
|
model = name.to_s.constantize
|
|
160
|
-
unless model.respond_to?(:
|
|
161
|
-
abort "#{name} does not `include
|
|
160
|
+
unless model.respond_to?(:open_loam_encrypted_attributes) && model.open_loam_encrypted_attributes.any?
|
|
161
|
+
abort "#{name} does not `include OpenLoam::Encryptable` with any `encrypts` fields."
|
|
162
162
|
end
|
|
163
163
|
model
|
|
164
164
|
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
|