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.
Files changed (287) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +148 -8
  3. data/LICENSE +1 -1
  4. data/README.md +27 -25
  5. data/app/jobs/{loam → open_loam}/custom_field_reindex_job.rb +6 -6
  6. data/app/jobs/{loam → open_loam}/event_delivery_job.rb +8 -8
  7. data/app/jobs/open_loam/event_log_prune_job.rb +15 -0
  8. data/app/jobs/{loam → open_loam}/event_redelivery_sweep_job.rb +4 -4
  9. data/app/jobs/{loam → open_loam}/webhook_delivery_job.rb +17 -8
  10. data/app/models/open_loam/api_token.rb +63 -0
  11. data/app/models/{loam → open_loam}/audit_record.rb +3 -3
  12. data/app/models/{loam → open_loam}/auth_attempt.rb +5 -5
  13. data/app/models/{loam → open_loam}/business_rule.rb +10 -10
  14. data/app/models/{loam → open_loam}/business_rule_run.rb +5 -5
  15. data/app/models/{loam → open_loam}/comment.rb +9 -9
  16. data/app/models/{loam → open_loam}/config.rb +7 -7
  17. data/app/models/{loam → open_loam}/custom_field_value.rb +5 -5
  18. data/app/models/{loam → open_loam}/dashboard_widget.rb +5 -5
  19. data/app/models/open_loam/dictionary.rb +20 -0
  20. data/app/models/{loam → open_loam}/dictionary_entry.rb +7 -7
  21. data/app/models/{loam → open_loam}/event_delivery.rb +4 -4
  22. data/app/models/open_loam/event_record.rb +42 -0
  23. data/app/models/{loam → open_loam}/field_definition.rb +8 -8
  24. data/app/models/{loam → open_loam}/inbound_webhook_delivery.rb +4 -4
  25. data/app/models/{loam → open_loam}/inbound_webhook_source.rb +13 -13
  26. data/app/models/{loam → open_loam}/membership.rb +6 -6
  27. data/app/models/{loam → open_loam}/mfa_credential.rb +8 -8
  28. data/app/models/{loam → open_loam}/notification.rb +10 -10
  29. data/app/models/{loam → open_loam}/pending_action.rb +70 -26
  30. data/app/models/{loam → open_loam}/perspective.rb +5 -5
  31. data/app/models/{loam → open_loam}/progress_job.rb +7 -7
  32. data/app/models/{loam → open_loam}/record_lock.rb +5 -5
  33. data/app/models/{loam → open_loam}/scheduled_job.rb +7 -7
  34. data/app/models/open_loam/search_token.rb +9 -0
  35. data/app/models/{loam → open_loam}/sso_identity.rb +4 -4
  36. data/app/models/open_loam/sso_provider.rb +66 -0
  37. data/app/models/open_loam/tenant.rb +20 -0
  38. data/app/models/{loam → open_loam}/translation.rb +5 -5
  39. data/app/models/open_loam/webhook_endpoint.rb +39 -0
  40. data/app/views/{loam → open_loam}/attachments/_attachments.html.erb +1 -1
  41. data/app/views/{loam → open_loam}/comments/_comments.html.erb +1 -1
  42. data/app/views/{loam → open_loam}/custom_fields/_fields.html.erb +6 -2
  43. data/lib/generators/{loam → open_loam}/entity/entity_generator.rb +9 -9
  44. data/lib/generators/{loam → open_loam}/entity/templates/api_controller.rb +2 -1
  45. data/lib/generators/{loam → open_loam}/entity/templates/controller.rb +32 -22
  46. data/lib/generators/{loam → open_loam}/entity/templates/entity_test.rb +12 -12
  47. data/lib/generators/{loam → open_loam}/entity/templates/migration.rb +5 -5
  48. data/lib/generators/{loam → open_loam}/entity/templates/model.rb +10 -10
  49. data/lib/generators/{loam → open_loam}/entity/templates/policy.rb +1 -1
  50. data/lib/generators/{loam → open_loam}/entity/templates/views/_form.html.erb +8 -5
  51. data/lib/generators/{loam → open_loam}/entity/templates/views/deleted.html.erb +7 -7
  52. data/lib/generators/open_loam/entity/templates/views/edit.html.erb +3 -0
  53. data/lib/generators/open_loam/entity/templates/views/index.html.erb +94 -0
  54. data/lib/generators/open_loam/entity/templates/views/new.html.erb +3 -0
  55. data/lib/generators/open_loam/entity/templates/views/show.html.erb +38 -0
  56. data/lib/generators/{loam → open_loam}/install/install_generator.rb +58 -47
  57. data/lib/generators/open_loam/install/templates/AGENTS.md +345 -0
  58. data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_controller.rb +2 -2
  59. data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_index.html.erb +1 -1
  60. data/lib/generators/open_loam/install/templates/admin/api_tokens_controller.rb +48 -0
  61. data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_index.html.erb +23 -0
  62. data/lib/generators/{loam → open_loam}/install/templates/admin/base_controller.rb +101 -38
  63. data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_controller.rb +7 -7
  64. data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_form.html.erb +2 -2
  65. data/lib/generators/{loam → open_loam}/install/templates/admin/comments_controller.rb +4 -4
  66. data/lib/generators/{loam → open_loam}/install/templates/admin/configs_controller.rb +9 -9
  67. data/lib/generators/open_loam/install/templates/admin/dashboard_controller.rb +12 -0
  68. data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_controller.rb +5 -5
  69. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_controller.rb +5 -5
  70. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_form.html.erb +1 -1
  71. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionary_entries_controller.rb +2 -2
  72. data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_controller.rb +5 -5
  73. data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_index.html.erb +1 -1
  74. data/lib/generators/{loam → open_loam}/install/templates/admin/events_controller.rb +7 -5
  75. data/lib/generators/{loam → open_loam}/install/templates/admin/features_controller.rb +9 -9
  76. data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_controller.rb +5 -5
  77. data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_new.html.erb +2 -2
  78. data/lib/generators/open_loam/install/templates/admin/history_controller.rb +64 -0
  79. data/lib/generators/{loam → open_loam}/install/templates/admin/history_index.html.erb +2 -2
  80. data/lib/generators/{loam → open_loam}/install/templates/admin/imports_controller.rb +25 -13
  81. data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_controller.rb +7 -7
  82. data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_new.html.erb +2 -4
  83. data/lib/generators/open_loam/install/templates/admin/layout.html.erb +76 -0
  84. data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_controller.rb +11 -6
  85. data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_controller.rb +5 -3
  86. data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_controller.rb +3 -3
  87. data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_index.html.erb +2 -2
  88. data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_controller.rb +3 -3
  89. data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_controller.rb +13 -7
  90. data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_index.html.erb +1 -1
  91. data/lib/generators/open_loam/install/templates/admin/progress_jobs_controller.rb +23 -0
  92. data/lib/generators/{loam → open_loam}/install/templates/admin/progress_jobs_index.html.erb +1 -1
  93. data/lib/generators/{loam → open_loam}/install/templates/admin/record_locks_controller.rb +4 -4
  94. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_controller.rb +7 -7
  95. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_form.html.erb +1 -1
  96. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_index.html.erb +1 -1
  97. data/lib/generators/{loam → open_loam}/install/templates/admin/search_controller.rb +7 -5
  98. data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_controller.rb +33 -34
  99. data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_controller.rb +6 -6
  100. data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_form.html.erb +2 -2
  101. data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_index.html.erb +8 -1
  102. data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_controller.rb +7 -5
  103. data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_new.html.erb +1 -1
  104. data/lib/generators/{loam → open_loam}/install/templates/admin/translations_controller.rb +7 -7
  105. data/lib/generators/{loam → open_loam}/install/templates/admin/translations_index.html.erb +3 -3
  106. data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_controller.rb +4 -4
  107. data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_index.html.erb +1 -1
  108. data/lib/generators/{loam → open_loam}/install/templates/admin.css +1 -1
  109. data/lib/generators/open_loam/install/templates/api_base_controller.rb +127 -0
  110. data/lib/generators/{loam → open_loam}/install/templates/guardrails_test.rb +17 -17
  111. data/lib/generators/open_loam/install/templates/import_job.rb +38 -0
  112. data/lib/generators/{loam → open_loam}/install/templates/inbound_webhooks_controller.rb +4 -4
  113. data/lib/generators/{loam → open_loam}/install/templates/initializer.rb +87 -75
  114. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_api_tokens.rb +15 -0
  115. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_audit_records.rb +14 -0
  116. 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
  117. 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
  118. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_comments.rb +13 -0
  119. data/lib/generators/{loam/install/templates/migrations/create_loam_configs.rb → open_loam/install/templates/migrations/create_open_loam_configs.rb} +7 -7
  120. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_custom_field_values.rb +19 -0
  121. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dashboard_widgets.rb +12 -0
  122. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dictionaries.rb +11 -0
  123. 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
  124. 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
  125. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_event_records.rb +13 -0
  126. 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
  127. 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
  128. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_memberships.rb +11 -0
  129. 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
  130. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_notifications.rb +15 -0
  131. 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
  132. data/lib/generators/{loam/install/templates/migrations/create_loam_perspectives.rb → open_loam/install/templates/migrations/create_open_loam_perspectives.rb} +5 -5
  133. 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
  134. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_record_locks.rb +16 -0
  135. 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
  136. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_search_tokens.rb +18 -0
  137. 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
  138. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_tenants.rb +9 -0
  139. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_translations.rb +15 -0
  140. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_webhook_endpoints.rb +13 -0
  141. data/lib/generators/{loam → open_loam}/install/templates/migrations/create_users.rb +1 -1
  142. data/lib/generators/{loam → open_loam}/install/templates/user.rb +5 -5
  143. data/lib/generators/{loam → open_loam}/primary_key_options.rb +23 -23
  144. data/lib/open-loam.rb +2 -2
  145. data/lib/{loam → open_loam}/attachable.rb +4 -4
  146. data/lib/{loam → open_loam}/auditable.rb +23 -23
  147. data/lib/{loam → open_loam}/auth_throttle.rb +20 -12
  148. data/lib/{loam → open_loam}/base32.rb +1 -1
  149. data/lib/{loam → open_loam}/bulk.rb +7 -7
  150. data/lib/{loam → open_loam}/business_rules/actions.rb +7 -7
  151. data/lib/{loam → open_loam}/business_rules/condition.rb +5 -5
  152. data/lib/{loam → open_loam}/business_rules.rb +19 -19
  153. data/lib/{loam → open_loam}/commentable.rb +6 -6
  154. data/lib/{loam → open_loam}/configs.rb +19 -19
  155. data/lib/{loam → open_loam}/cron.rb +2 -2
  156. data/lib/{loam → open_loam}/csv.rb +2 -2
  157. data/lib/{loam → open_loam}/current.rb +5 -5
  158. data/lib/{loam → open_loam}/custom_field_index.rb +33 -30
  159. data/lib/{loam → open_loam}/custom_fields.rb +17 -17
  160. data/lib/{loam → open_loam}/dashboard.rb +5 -5
  161. data/lib/{loam → open_loam}/dictionaries.rb +12 -12
  162. data/lib/{loam → open_loam}/durable_events.rb +19 -19
  163. data/lib/{loam → open_loam}/encryptable.rb +39 -34
  164. data/lib/{loam → open_loam}/encryption/cipher.rb +3 -3
  165. data/lib/{loam → open_loam}/encryption/key_provider.rb +19 -3
  166. data/lib/{loam → open_loam}/encryption.rb +58 -15
  167. data/lib/open_loam/engine.rb +65 -0
  168. data/lib/{loam → open_loam}/enrichers.rb +5 -5
  169. data/lib/{loam → open_loam}/errors.rb +20 -10
  170. data/lib/{loam → open_loam}/eval.rb +2 -2
  171. data/lib/open_loam/event_log.rb +77 -0
  172. data/lib/{loam → open_loam}/event_stream.rb +14 -14
  173. data/lib/{loam → open_loam}/eventful.rb +12 -12
  174. data/lib/{loam → open_loam}/events.rb +5 -5
  175. data/lib/{loam → open_loam}/export.rb +12 -12
  176. data/lib/{loam → open_loam}/features.rb +15 -15
  177. data/lib/{loam → open_loam}/generated_key.rb +6 -6
  178. data/lib/{loam → open_loam}/import.rb +12 -15
  179. data/lib/{loam → open_loam}/inbound_webhooks.rb +19 -18
  180. data/lib/{loam → open_loam}/lifecycle.rb +54 -25
  181. data/lib/{loam/locales/loam.en.yml → open_loam/locales/open_loam.en.yml} +5 -5
  182. data/lib/{loam → open_loam}/mcp/server.rb +9 -9
  183. data/lib/{loam → open_loam}/mcp.rb +31 -22
  184. data/lib/{loam → open_loam}/notifications.rb +5 -5
  185. data/lib/{loam → open_loam}/open_api.rb +16 -16
  186. data/lib/open_loam/outbound_url.rb +100 -0
  187. data/lib/{loam → open_loam}/overrides.rb +10 -10
  188. data/lib/{loam → open_loam}/pending_actions.rb +9 -9
  189. data/lib/{loam → open_loam}/permissions.rb +8 -8
  190. data/lib/{loam → open_loam}/perspectives.rb +9 -9
  191. data/lib/{loam → open_loam}/policy.rb +21 -8
  192. data/lib/{loam → open_loam}/progress.rb +6 -6
  193. data/lib/{loam → open_loam}/record_locks.rb +9 -9
  194. data/lib/{loam → open_loam}/scheduler.rb +20 -20
  195. data/lib/{loam → open_loam}/search/driver.rb +3 -3
  196. data/lib/{loam → open_loam}/search/like_driver.rb +5 -5
  197. data/lib/{loam → open_loam}/search/token_driver.rb +16 -16
  198. data/lib/{loam → open_loam}/search.rb +5 -5
  199. data/lib/{loam → open_loam}/searchable.rb +22 -22
  200. data/lib/{loam → open_loam}/soft_deletable.rb +10 -10
  201. data/lib/{loam → open_loam}/sso/claims.rb +1 -1
  202. data/lib/{loam → open_loam}/sso/fake_provider.rb +1 -1
  203. data/lib/open_loam/sso/http_client.rb +51 -0
  204. data/lib/{loam → open_loam}/sso/oidc_provider.rb +2 -2
  205. data/lib/{loam → open_loam}/sso.rb +39 -18
  206. data/lib/{loam → open_loam}/telemetry.rb +6 -6
  207. data/lib/{loam → open_loam}/tenant_record.rb +10 -10
  208. data/lib/{loam → open_loam}/test_helpers.rb +4 -4
  209. data/lib/{loam → open_loam}/totp.rb +3 -3
  210. data/lib/{loam → open_loam}/translatable.rb +24 -24
  211. data/lib/{loam → open_loam}/undo.rb +11 -11
  212. data/lib/open_loam/version.rb +3 -0
  213. data/lib/{loam → open_loam}/webhooks.rb +4 -4
  214. data/lib/{loam → open_loam}/widgets.rb +9 -9
  215. data/lib/{loam → open_loam}/workflow.rb +45 -45
  216. data/lib/open_loam.rb +124 -0
  217. data/lib/tasks/open_loam.rake +203 -0
  218. data/lib/tasks/{loam_eval.rake → open_loam_eval.rake} +7 -7
  219. data/lib/tasks/open_loam_mcp.rake +20 -0
  220. metadata +247 -242
  221. data/app/models/loam/api_token.rb +0 -40
  222. data/app/models/loam/dictionary.rb +0 -20
  223. data/app/models/loam/search_token.rb +0 -9
  224. data/app/models/loam/sso_provider.rb +0 -35
  225. data/app/models/loam/tenant.rb +0 -20
  226. data/app/models/loam/webhook_endpoint.rb +0 -26
  227. data/lib/generators/loam/entity/templates/views/edit.html.erb +0 -3
  228. data/lib/generators/loam/entity/templates/views/index.html.erb +0 -90
  229. data/lib/generators/loam/entity/templates/views/new.html.erb +0 -3
  230. data/lib/generators/loam/entity/templates/views/show.html.erb +0 -36
  231. data/lib/generators/loam/install/templates/AGENTS.md +0 -341
  232. data/lib/generators/loam/install/templates/admin/api_tokens_controller.rb +0 -30
  233. data/lib/generators/loam/install/templates/admin/dashboard_controller.rb +0 -10
  234. data/lib/generators/loam/install/templates/admin/history_controller.rb +0 -38
  235. data/lib/generators/loam/install/templates/admin/layout.html.erb +0 -76
  236. data/lib/generators/loam/install/templates/admin/progress_jobs_controller.rb +0 -19
  237. data/lib/generators/loam/install/templates/api_base_controller.rb +0 -90
  238. data/lib/generators/loam/install/templates/import_job.rb +0 -25
  239. data/lib/generators/loam/install/templates/migrations/create_loam_api_tokens.rb +0 -15
  240. data/lib/generators/loam/install/templates/migrations/create_loam_audit_records.rb +0 -14
  241. data/lib/generators/loam/install/templates/migrations/create_loam_comments.rb +0 -13
  242. data/lib/generators/loam/install/templates/migrations/create_loam_custom_field_values.rb +0 -19
  243. data/lib/generators/loam/install/templates/migrations/create_loam_dashboard_widgets.rb +0 -12
  244. data/lib/generators/loam/install/templates/migrations/create_loam_dictionaries.rb +0 -11
  245. data/lib/generators/loam/install/templates/migrations/create_loam_memberships.rb +0 -11
  246. data/lib/generators/loam/install/templates/migrations/create_loam_notifications.rb +0 -15
  247. data/lib/generators/loam/install/templates/migrations/create_loam_record_locks.rb +0 -16
  248. data/lib/generators/loam/install/templates/migrations/create_loam_search_tokens.rb +0 -18
  249. data/lib/generators/loam/install/templates/migrations/create_loam_tenants.rb +0 -9
  250. data/lib/generators/loam/install/templates/migrations/create_loam_translations.rb +0 -15
  251. data/lib/generators/loam/install/templates/migrations/create_loam_webhook_endpoints.rb +0 -13
  252. data/lib/loam/engine.rb +0 -57
  253. data/lib/loam/sso/http_client.rb +0 -42
  254. data/lib/loam/version.rb +0 -3
  255. data/lib/loam.rb +0 -122
  256. data/lib/tasks/loam.rake +0 -171
  257. data/lib/tasks/loam_mcp.rake +0 -20
  258. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_edit.html.erb +0 -0
  259. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_index.html.erb +0 -0
  260. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_new.html.erb +0 -0
  261. /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_edit.html.erb +0 -0
  262. /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_index.html.erb +0 -0
  263. /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_index.html.erb +0 -0
  264. /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_index.html.erb +0 -0
  265. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_edit.html.erb +0 -0
  266. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_index.html.erb +0 -0
  267. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_new.html.erb +0 -0
  268. /data/lib/generators/{loam → open_loam}/install/templates/admin/features_index.html.erb +0 -0
  269. /data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_index.html.erb +0 -0
  270. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_new.html.erb +0 -0
  271. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_preview.html.erb +0 -0
  272. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_summary.html.erb +0 -0
  273. /data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_index.html.erb +0 -0
  274. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_activated.html.erb +0 -0
  275. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_new.html.erb +0 -0
  276. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_show.html.erb +0 -0
  277. /data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_index.html.erb +0 -0
  278. /data/lib/generators/{loam → open_loam}/install/templates/admin/pagination.rb +0 -0
  279. /data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_index.html.erb +0 -0
  280. /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_edit.html.erb +0 -0
  281. /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_new.html.erb +0 -0
  282. /data/lib/generators/{loam → open_loam}/install/templates/admin/search_index.html.erb +0 -0
  283. /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_mfa_challenge.html.erb +0 -0
  284. /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_new.html.erb +0 -0
  285. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_edit.html.erb +0 -0
  286. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_new.html.erb +0 -0
  287. /data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_new.html.erb +0 -0
data/lib/loam.rb DELETED
@@ -1,122 +0,0 @@
1
- require "loam/version"
2
- require "loam/errors"
3
- require "loam/current"
4
- require "loam/events"
5
- require "loam/policy"
6
- require "loam/lifecycle"
7
- require "loam/configs"
8
- require "loam/features"
9
- require "loam/auth_throttle"
10
- require "loam/dictionaries"
11
- require "loam/custom_field_index"
12
- require "loam/undo"
13
- require "loam/permissions"
14
- require "loam/telemetry"
15
- require "loam/eval"
16
- require "loam/mcp"
17
- require "loam/mcp/server"
18
- require "loam/progress"
19
- require "loam/cron"
20
- require "loam/scheduler"
21
- require "loam/csv"
22
- require "loam/export"
23
- require "loam/import"
24
- require "loam/bulk"
25
- require "loam/widgets"
26
- require "loam/dashboard"
27
- require "loam/overrides"
28
- require "loam/open_api"
29
- require "loam/encryption"
30
- require "loam/base32"
31
- require "loam/totp"
32
- require "loam/pending_actions"
33
- require "loam/perspectives"
34
- require "loam/record_locks"
35
- require "loam/event_stream"
36
- require "loam/enrichers"
37
- require "loam/search"
38
- require "loam/search/driver"
39
- require "loam/search/like_driver"
40
- require "loam/search/token_driver"
41
- require "loam/notifications"
42
- require "loam/sso"
43
- require "loam/business_rules"
44
- require "loam/webhooks"
45
- require "loam/inbound_webhooks"
46
- require "loam/durable_events"
47
- require "loam/engine" if defined?(Rails::Engine)
48
-
49
- module Loam
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
- # Loam::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 && Loam::Membership.find_by(user_id: Current.actor.id)&.role
70
- Loam::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
- # Loam::PendingActions.stage instead of committed. Loam 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 "loam/generated_key"
111
- require "loam/tenant_record"
112
- require "loam/auditable"
113
- require "loam/soft_deletable"
114
- require "loam/eventful"
115
- require "loam/custom_fields"
116
- require "loam/workflow"
117
- require "loam/searchable"
118
- require "loam/encryptable"
119
- require "loam/translatable"
120
- require "loam/commentable"
121
- require "loam/attachable"
122
- end
data/lib/tasks/loam.rake DELETED
@@ -1,171 +0,0 @@
1
- namespace :loam do
2
- desc "Re-run every Loam.on_tenant_created callback for every existing tenant (idempotent)"
3
- task sync: :environment do
4
- synced = Loam.sync_tenants!
5
- puts "loam:sync — ran #{Loam.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 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(Loam::OpenApi.document))
19
- File.write(File.join(dir, "openapi.md"), Loam::OpenApi.markdown)
20
- puts "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 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 Loam::ScheduledJob (run from cron)"
30
- task tick: :environment do
31
- fired = Loam::Scheduler.tick
32
- puts "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 (Loam::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 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 = Loam::TenantRecord.descendants.select do |model|
46
- model.name.present? && model.respond_to?(:custom_field_definitions)
47
- end
48
-
49
- tenants = 0
50
- Loam::Tenant.find_each do |tenant|
51
- Loam.as_tenant(tenant) { models.each { |model| Loam::CustomFieldIndex.reindex(model) } }
52
- tenants += 1
53
- end
54
- puts "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 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 = Loam::TenantRecord.descendants.select do |model|
65
- model.name.present? && model.respond_to?(:custom_field_definitions)
66
- end
67
-
68
- Loam::Tenant.find_each do |tenant|
69
- Loam.as_tenant(tenant) do
70
- models.each do |model|
71
- model.custom_field_definitions.find_each do |definition|
72
- c = Loam::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
- # (Loam::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 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 = Loam::TenantRecord.descendants.select do |model|
94
- model.name.present? && model.respond_to?(:loam_searchable?) && model.loam_searchable?
95
- end
96
-
97
- tenants = 0
98
- Loam::Tenant.find_each do |tenant|
99
- Loam.as_tenant(tenant) { models.each { |model| Loam::Search.reindex(model) } }
100
- tenants += 1
101
- end
102
- puts "loam:search:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s) using #{Loam::Search.driver}."
103
- end
104
- end
105
-
106
- namespace :encryption do
107
- # Rotate a tenant's encrypted data under the current key: read each record's
108
- # encrypted fields (old key) and re-seal them (new key), one record at a
109
- # time. The version tag in the stored format means old and new ciphertext
110
- # coexist, so this can run incrementally without downtime. Each record is an
111
- # ordinary audited "[encrypted]" update.
112
- #
113
- # bin/rails loam:encryption:rotate[Customer,42]
114
- desc "Re-encrypt a model's encrypted fields for one tenant (rotation step)"
115
- task :rotate, %i[model tenant_id] => :environment do |_task, args|
116
- model = fetch_encryptable_model(args[:model])
117
- tenant = Loam::Tenant.find(args[:tenant_id])
118
-
119
- count = 0
120
- Loam.as_tenant(tenant) do
121
- each_record(model) do |record|
122
- record.loam_reencrypt!
123
- count += 1
124
- end
125
- end
126
- puts "loam:encryption:rotate — re-encrypted #{count} #{model.name} record(s) in tenant #{tenant.slug}."
127
- end
128
-
129
- # Decrypt and print one tenant's encrypted fields, e.g. for a GDPR data
130
- # export or a migration. OPERATIONAL CAUTION: this prints plaintext PII to
131
- # stdout — run it only where that output is safe (never into shared logs or
132
- # a shell history that syncs), and only for a tenant you are authorized to
133
- # export.
134
- #
135
- # bin/rails loam:encryption:decrypt_dump[Customer,42]
136
- desc "Print decrypted encrypted-field values for one tenant (GDPR export; handle with care)"
137
- task :decrypt_dump, %i[model tenant_id] => :environment do |_task, args|
138
- require "json"
139
- model = fetch_encryptable_model(args[:model])
140
- tenant = Loam::Tenant.find(args[:tenant_id])
141
- fields = model.loam_encrypted_attributes
142
-
143
- Loam.as_tenant(tenant) do
144
- each_record(model) do |record|
145
- row = { id: record.id }.merge(fields.index_with { |field| record.public_send(field) })
146
- puts row.to_json
147
- end
148
- end
149
- end
150
- end
151
- end
152
-
153
- # Resolve a model name to a class that actually uses Loam::Encryptable — a typo
154
- # or a plain model should fail loudly, not silently dump/rotate nothing.
155
- def fetch_encryptable_model(name)
156
- # Force the app's classes (and Loam::TenantRecord, required lazily via the
157
- # active_record on_load hook) to load before we constantize a model name.
158
- Rails.application.eager_load!
159
- model = name.to_s.constantize
160
- unless model.respond_to?(:loam_encrypted_attributes) && model.loam_encrypted_attributes.any?
161
- abort "#{name} does not `include Loam::Encryptable` with any `encrypts` fields."
162
- end
163
- model
164
- end
165
-
166
- # Iterate every record, soft-deleted ones included (a GDPR export must not miss
167
- # data hidden in the recycle bin), staying inside the current tenant scope.
168
- def each_record(model, &block)
169
- scope = model.respond_to?(:with_deleted) ? model.with_deleted : model.all
170
- scope.find_each(&block)
171
- end
@@ -1,20 +0,0 @@
1
- require "logger"
2
-
3
- namespace :loam do
4
- namespace :mcp do
5
- # Serve the Loam MCP server over stdio. Point an MCP client (Claude Code,
6
- # Cursor, Codex) at `bin/rails loam:mcp:serve` with LOAM_MCP_TOKEN set to a
7
- # Loam 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 Loam MCP server over stdio (auth via 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
- Loam::Mcp::Server.new.run
18
- end
19
- end
20
- end