lcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1676) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/skills/lcp-custom-field/SKILL.md +205 -0
  3. data/.claude/skills/lcp-getting-started/SKILL.md +332 -0
  4. data/.claude/skills/lcp-host-binding/SKILL.md +287 -0
  5. data/.claude/skills/lcp-model/SKILL.md +185 -0
  6. data/.claude/skills/lcp-permissions/SKILL.md +176 -0
  7. data/.claude/skills/lcp-presenter/SKILL.md +194 -0
  8. data/.claude/skills/lcp-workflow/SKILL.md +281 -0
  9. data/CHANGELOG.md +69 -0
  10. data/MIT-LICENSE +20 -0
  11. data/README.md +28 -0
  12. data/Rakefile +17 -0
  13. data/app/assets/javascripts/lcp_ruby/application.js +58 -0
  14. data/app/assets/javascripts/lcp_ruby/controllers/advanced_filter_controller.js +1521 -0
  15. data/app/assets/javascripts/lcp_ruby/controllers/approval_actions_controller.js +24 -0
  16. data/app/assets/javascripts/lcp_ruby/controllers/array_input_controller.js +156 -0
  17. data/app/assets/javascripts/lcp_ruby/controllers/batch_select_controller.js +405 -0
  18. data/app/assets/javascripts/lcp_ruby/controllers/cascading_selects_controller.js +436 -0
  19. data/app/assets/javascripts/lcp_ruby/controllers/char_counter_controller.js +28 -0
  20. data/app/assets/javascripts/lcp_ruby/controllers/clipboard_controller.js +62 -0
  21. data/app/assets/javascripts/lcp_ruby/controllers/conditional_rendering_controller.js +178 -0
  22. data/app/assets/javascripts/lcp_ruby/controllers/confirm_dialog_controller.js +131 -0
  23. data/app/assets/javascripts/lcp_ruby/controllers/custom_fields_manage_controller.js +80 -0
  24. data/app/assets/javascripts/lcp_ruby/controllers/dialog_controller.js +421 -0
  25. data/app/assets/javascripts/lcp_ruby/controllers/dialog_nested_controller.js +182 -0
  26. data/app/assets/javascripts/lcp_ruby/controllers/direct_upload_controller.js +100 -0
  27. data/app/assets/javascripts/lcp_ruby/controllers/drawer_controller.js +205 -0
  28. data/app/assets/javascripts/lcp_ruby/controllers/dropdown_controller.js +160 -0
  29. data/app/assets/javascripts/lcp_ruby/controllers/export_dialog_controller.js +15 -0
  30. data/app/assets/javascripts/lcp_ruby/controllers/field_picker_controller.js +290 -0
  31. data/app/assets/javascripts/lcp_ruby/controllers/file_upload_controller.js +135 -0
  32. data/app/assets/javascripts/lcp_ruby/controllers/filter_auto_submit_controller.js +46 -0
  33. data/app/assets/javascripts/lcp_ruby/controllers/filter_dirty_controller.js +94 -0
  34. data/app/assets/javascripts/lcp_ruby/controllers/form_actions_controller.js +68 -0
  35. data/app/assets/javascripts/lcp_ruby/controllers/form_handling_controller.js +67 -0
  36. data/app/assets/javascripts/lcp_ruby/controllers/import_dialog_controller.js +142 -0
  37. data/app/assets/javascripts/lcp_ruby/controllers/import_mapper_controller.js +322 -0
  38. data/app/assets/javascripts/lcp_ruby/controllers/index_sortable_controller.js +388 -0
  39. data/app/assets/javascripts/lcp_ruby/controllers/inline_create_controller.js +137 -0
  40. data/app/assets/javascripts/lcp_ruby/controllers/kanban_board_controller.js +290 -0
  41. data/app/assets/javascripts/lcp_ruby/controllers/menu_controller.js +19 -0
  42. data/app/assets/javascripts/lcp_ruby/controllers/nested_forms_controller.js +261 -0
  43. data/app/assets/javascripts/lcp_ruby/controllers/responsive_sidebar_controller.js +161 -0
  44. data/app/assets/javascripts/lcp_ruby/controllers/responsive_top_nav_controller.js +394 -0
  45. data/app/assets/javascripts/lcp_ruby/controllers/saved_filters_controller.js +129 -0
  46. data/app/assets/javascripts/lcp_ruby/controllers/search_controller.js +82 -0
  47. data/app/assets/javascripts/lcp_ruby/controllers/selection_controller.js +33 -0
  48. data/app/assets/javascripts/lcp_ruby/controllers/sidebar_controller.js +83 -0
  49. data/app/assets/javascripts/lcp_ruby/controllers/sidebar_toggle_controller.js +66 -0
  50. data/app/assets/javascripts/lcp_ruby/controllers/slider_controller.js +26 -0
  51. data/app/assets/javascripts/lcp_ruby/controllers/submenu_controller.js +55 -0
  52. data/app/assets/javascripts/lcp_ruby/controllers/tom_select_controller.js +168 -0
  53. data/app/assets/javascripts/lcp_ruby/controllers/tree_index_controller.js +106 -0
  54. data/app/assets/javascripts/lcp_ruby/controllers/tree_reparent_controller.js +182 -0
  55. data/app/assets/javascripts/lcp_ruby/controllers/tree_select_controller.js +119 -0
  56. data/app/assets/javascripts/lcp_ruby/controllers/ui_components_controller.js +135 -0
  57. data/app/assets/javascripts/lcp_ruby/controllers/zone_tabs_controller.js +66 -0
  58. data/app/assets/javascripts/lcp_ruby/dev_toolbar.js +494 -0
  59. data/app/assets/javascripts/lcp_ruby/i18n.js.erb +29 -0
  60. data/app/assets/javascripts/lcp_ruby/lucide_init.js +24 -0
  61. data/app/assets/javascripts/lcp_ruby/stimulus_bootstrap.js +7 -0
  62. data/app/assets/javascripts/lcp_ruby/utils.js +119 -0
  63. data/app/assets/javascripts/lcp_ruby/xhr_fetch.js +411 -0
  64. data/app/assets/stylesheets/lcp_ruby/application.css +1940 -0
  65. data/app/assets/stylesheets/lcp_ruby/dev_toolbar.css +355 -0
  66. data/app/controllers/concerns/lcp_ruby/dialog_rendering.rb +167 -0
  67. data/app/controllers/concerns/lcp_ruby/form_action_execution.rb +249 -0
  68. data/app/controllers/concerns/lcp_ruby/page_authorization.rb +105 -0
  69. data/app/controllers/concerns/lcp_ruby/zone_resolution.rb +199 -0
  70. data/app/controllers/lcp_ruby/actions_controller.rb +481 -0
  71. data/app/controllers/lcp_ruby/application_controller.rb +59 -0
  72. data/app/controllers/lcp_ruby/approval_tasks_controller.rb +98 -0
  73. data/app/controllers/lcp_ruby/auth/base_controller.rb +58 -0
  74. data/app/controllers/lcp_ruby/auth/callbacks_controller.rb +103 -0
  75. data/app/controllers/lcp_ruby/auth/passwords_controller.rb +15 -0
  76. data/app/controllers/lcp_ruby/auth/registrations_controller.rb +37 -0
  77. data/app/controllers/lcp_ruby/auth/sessions_controller.rb +112 -0
  78. data/app/controllers/lcp_ruby/custom_fields_controller.rb +370 -0
  79. data/app/controllers/lcp_ruby/dev_toolbar_controller.rb +197 -0
  80. data/app/controllers/lcp_ruby/dialogs_controller.rb +199 -0
  81. data/app/controllers/lcp_ruby/health_controller.rb +23 -0
  82. data/app/controllers/lcp_ruby/impersonation_controller.rb +32 -0
  83. data/app/controllers/lcp_ruby/landing_controller.rb +49 -0
  84. data/app/controllers/lcp_ruby/metrics_controller.rb +17 -0
  85. data/app/controllers/lcp_ruby/resources_controller.rb +2218 -0
  86. data/app/controllers/lcp_ruby/saved_filters_controller.rb +221 -0
  87. data/app/helpers/lcp_ruby/condition_helper.rb +87 -0
  88. data/app/helpers/lcp_ruby/dashboard_helper.rb +45 -0
  89. data/app/helpers/lcp_ruby/dev_toolbar_helper.rb +17 -0
  90. data/app/helpers/lcp_ruby/dialog_helper.rb +27 -0
  91. data/app/helpers/lcp_ruby/display/card_helper.rb +317 -0
  92. data/app/helpers/lcp_ruby/display_helper.rb +63 -0
  93. data/app/helpers/lcp_ruby/display_template_helper.rb +100 -0
  94. data/app/helpers/lcp_ruby/form_helper.rb +1020 -0
  95. data/app/helpers/lcp_ruby/grouped_query_helper.rb +107 -0
  96. data/app/helpers/lcp_ruby/i18n_payload_helper.rb +197 -0
  97. data/app/helpers/lcp_ruby/layout_helper.rb +832 -0
  98. data/app/helpers/lcp_ruby/link_through_helper.rb +29 -0
  99. data/app/helpers/lcp_ruby/oidc_button_helper.rb +59 -0
  100. data/app/helpers/lcp_ruby/search_helper.rb +31 -0
  101. data/app/helpers/lcp_ruby/tree_helper.rb +140 -0
  102. data/app/helpers/lcp_ruby/view_slot_helper.rb +33 -0
  103. data/app/models/lcp_ruby/user.rb +61 -0
  104. data/app/views/layouts/lcp_ruby/application.html.erb +168 -0
  105. data/app/views/layouts/lcp_ruby/auth.html.erb +170 -0
  106. data/app/views/lcp_ruby/auth/callbacks/failure.html.erb +18 -0
  107. data/app/views/lcp_ruby/auth/mailer/reset_password_instructions.html.erb +9 -0
  108. data/app/views/lcp_ruby/auth/passwords/edit.html.erb +34 -0
  109. data/app/views/lcp_ruby/auth/passwords/new.html.erb +24 -0
  110. data/app/views/lcp_ruby/auth/registrations/edit.html.erb +48 -0
  111. data/app/views/lcp_ruby/auth/registrations/new.html.erb +46 -0
  112. data/app/views/lcp_ruby/auth/sessions/new.html.erb +55 -0
  113. data/app/views/lcp_ruby/auth/shared/_links.html.erb +13 -0
  114. data/app/views/lcp_ruby/custom_fields/_manage_row.html.erb +82 -0
  115. data/app/views/lcp_ruby/custom_fields/manage.html.erb +47 -0
  116. data/app/views/lcp_ruby/dialogs/_dialog_composite_frame.html.erb +87 -0
  117. data/app/views/lcp_ruby/dialogs/_dialog_frame.html.erb +60 -0
  118. data/app/views/lcp_ruby/dialogs/_dialog_show_frame.html.erb +14 -0
  119. data/app/views/lcp_ruby/dialogs/_show_secret.html.erb +10 -0
  120. data/app/views/lcp_ruby/dialogs/_success.html.erb +1 -0
  121. data/app/views/lcp_ruby/errors/not_found.html.erb +5 -0
  122. data/app/views/lcp_ruby/menu_renderers/_user_menu.html.erb +51 -0
  123. data/app/views/lcp_ruby/menu_renderers/_user_menu_panel.html.erb +32 -0
  124. data/app/views/lcp_ruby/navigation/_auto_top.html.erb +16 -0
  125. data/app/views/lcp_ruby/navigation/_both_sidebar.html.erb +1 -0
  126. data/app/views/lcp_ruby/navigation/_both_top.html.erb +1 -0
  127. data/app/views/lcp_ruby/navigation/_impersonation_banner.html.erb +14 -0
  128. data/app/views/lcp_ruby/navigation/_item_content.html.erb +23 -0
  129. data/app/views/lcp_ruby/navigation/_link_or_button.html.erb +51 -0
  130. data/app/views/lcp_ruby/navigation/_mobile_header.html.erb +23 -0
  131. data/app/views/lcp_ruby/navigation/_panel_item.html.erb +32 -0
  132. data/app/views/lcp_ruby/navigation/_sidebar.html.erb +38 -0
  133. data/app/views/lcp_ruby/navigation/_sidebar_item.html.erb +38 -0
  134. data/app/views/lcp_ruby/navigation/_sidebar_toggle.html.erb +32 -0
  135. data/app/views/lcp_ruby/navigation/_top.html.erb +26 -0
  136. data/app/views/lcp_ruby/navigation/_top_item.html.erb +112 -0
  137. data/app/views/lcp_ruby/navigation/_widget_item.html.erb +14 -0
  138. data/app/views/lcp_ruby/resources/_action_button.html.erb +138 -0
  139. data/app/views/lcp_ruby/resources/_advanced_filter.html.erb +55 -0
  140. data/app/views/lcp_ruby/resources/_api_status_banner.html.erb +11 -0
  141. data/app/views/lcp_ruby/resources/_association_list.html.erb +132 -0
  142. data/app/views/lcp_ruby/resources/_audit_history.html.erb +66 -0
  143. data/app/views/lcp_ruby/resources/_batch_toolbar.html.erb +54 -0
  144. data/app/views/lcp_ruby/resources/_filter_form.html.erb +57 -0
  145. data/app/views/lcp_ruby/resources/_form.html.erb +73 -0
  146. data/app/views/lcp_ruby/resources/_form_action_button.html.erb +20 -0
  147. data/app/views/lcp_ruby/resources/_form_action_dropdown_item.html.erb +17 -0
  148. data/app/views/lcp_ruby/resources/_form_actions.html.erb +38 -0
  149. data/app/views/lcp_ruby/resources/_form_section.html.erb +235 -0
  150. data/app/views/lcp_ruby/resources/_grid_page.html.erb +17 -0
  151. data/app/views/lcp_ruby/resources/_grouped_index.html.erb +61 -0
  152. data/app/views/lcp_ruby/resources/_inline_create_form.html.erb +50 -0
  153. data/app/views/lcp_ruby/resources/_json_items_list.html.erb +77 -0
  154. data/app/views/lcp_ruby/resources/_json_nested_fields.html.erb +30 -0
  155. data/app/views/lcp_ruby/resources/_kanban_card.html.erb +31 -0
  156. data/app/views/lcp_ruby/resources/_kanban_card_body.html.erb +17 -0
  157. data/app/views/lcp_ruby/resources/_kanban_column.html.erb +33 -0
  158. data/app/views/lcp_ruby/resources/_kanban_column_header.html.erb +10 -0
  159. data/app/views/lcp_ruby/resources/_kanban_index.html.erb +17 -0
  160. data/app/views/lcp_ruby/resources/_nested_field_cell.html.erb +33 -0
  161. data/app/views/lcp_ruby/resources/_nested_fields.html.erb +26 -0
  162. data/app/views/lcp_ruby/resources/_nested_row_content.html.erb +65 -0
  163. data/app/views/lcp_ruby/resources/_scope_filters.html.erb +71 -0
  164. data/app/views/lcp_ruby/resources/_semantic_index_page.html.erb +162 -0
  165. data/app/views/lcp_ruby/resources/_semantic_page.html.erb +121 -0
  166. data/app/views/lcp_ruby/resources/_show_sections.html.erb +128 -0
  167. data/app/views/lcp_ruby/resources/_table_index.html.erb +169 -0
  168. data/app/views/lcp_ruby/resources/_tile_card.html.erb +26 -0
  169. data/app/views/lcp_ruby/resources/_tile_card_body.html.erb +19 -0
  170. data/app/views/lcp_ruby/resources/_tiles_index.html.erb +15 -0
  171. data/app/views/lcp_ruby/resources/_transition_button.html.erb +33 -0
  172. data/app/views/lcp_ruby/resources/_tree_index.html.erb +61 -0
  173. data/app/views/lcp_ruby/resources/_view_switcher.html.erb +24 -0
  174. data/app/views/lcp_ruby/resources/edit.html.erb +9 -0
  175. data/app/views/lcp_ruby/resources/index.html.erb +80 -0
  176. data/app/views/lcp_ruby/resources/new.html.erb +9 -0
  177. data/app/views/lcp_ruby/resources/show.html.erb +37 -0
  178. data/app/views/lcp_ruby/shared/_breadcrumbs.html.erb +15 -0
  179. data/app/views/lcp_ruby/shared/_custom_partial_error.html.erb +3 -0
  180. data/app/views/lcp_ruby/shared/_flash_messages.html.erb +19 -0
  181. data/app/views/lcp_ruby/slots/index/_advanced_filter.html.erb +3 -0
  182. data/app/views/lcp_ruby/slots/index/_collection_actions.html.erb +50 -0
  183. data/app/views/lcp_ruby/slots/index/_manage_all.html.erb +4 -0
  184. data/app/views/lcp_ruby/slots/index/_pagination_footer.html.erb +71 -0
  185. data/app/views/lcp_ruby/slots/index/_predefined_filters.html.erb +8 -0
  186. data/app/views/lcp_ruby/slots/index/_saved_filters.html.erb +87 -0
  187. data/app/views/lcp_ruby/slots/index/_search.html.erb +52 -0
  188. data/app/views/lcp_ruby/slots/index/_search_parameter.html.erb +72 -0
  189. data/app/views/lcp_ruby/slots/index/_sort_dropdown.html.erb +21 -0
  190. data/app/views/lcp_ruby/slots/index/_summary_bar.html.erb +22 -0
  191. data/app/views/lcp_ruby/slots/index/_view_switcher.html.erb +1 -0
  192. data/app/views/lcp_ruby/slots/show/_approval_status.html.erb +8 -0
  193. data/app/views/lcp_ruby/slots/show/_back_to_list.html.erb +1 -0
  194. data/app/views/lcp_ruby/slots/show/_copy_url.html.erb +5 -0
  195. data/app/views/lcp_ruby/slots/show/_single_actions.html.erb +4 -0
  196. data/app/views/lcp_ruby/slots/show/_view_switcher.html.erb +1 -0
  197. data/app/views/lcp_ruby/widgets/_approval_status.html.erb +150 -0
  198. data/app/views/lcp_ruby/widgets/_chart.html.erb +36 -0
  199. data/app/views/lcp_ruby/widgets/_embed.html.erb +13 -0
  200. data/app/views/lcp_ruby/widgets/_kpi_card.html.erb +29 -0
  201. data/app/views/lcp_ruby/widgets/_list.html.erb +17 -0
  202. data/app/views/lcp_ruby/widgets/_presenter_zone.html.erb +84 -0
  203. data/app/views/lcp_ruby/widgets/_record_show_zone.html.erb +11 -0
  204. data/app/views/lcp_ruby/widgets/_text.html.erb +3 -0
  205. data/app/views/lcp_ruby/widgets/_workflow_graph.html.erb +32 -0
  206. data/app/views/lcp_ruby/zones/_custom_zone.html.erb +16 -0
  207. data/app/views/lcp_ruby/zones/_error.html.erb +5 -0
  208. data/app/views/lcp_ruby/zones/_zone_frame.html.erb +25 -0
  209. data/app/views/lcp_ruby/zones/_zone_search.html.erb +20 -0
  210. data/config/locales/cs.yml +859 -0
  211. data/config/locales/en.yml +731 -0
  212. data/config/routes.rb +119 -0
  213. data/docs/README.md +225 -0
  214. data/docs/architecture.md +212 -0
  215. data/docs/feature-catalog.md +763 -0
  216. data/docs/feature-catalog.yml +20911 -0
  217. data/docs/getting-started.md +1187 -0
  218. data/docs/guides/action-buttons.md +537 -0
  219. data/docs/guides/adding-locale.md +353 -0
  220. data/docs/guides/api-backed-models.md +478 -0
  221. data/docs/guides/attachments.md +399 -0
  222. data/docs/guides/auditing.md +333 -0
  223. data/docs/guides/batch-actions.md +342 -0
  224. data/docs/guides/composite-pages.md +1290 -0
  225. data/docs/guides/computed-fields.md +350 -0
  226. data/docs/guides/conditional-rendering.md +832 -0
  227. data/docs/guides/custom-actions.md +238 -0
  228. data/docs/guides/custom-fields.md +439 -0
  229. data/docs/guides/custom-renderers.md +234 -0
  230. data/docs/guides/custom-types.md +274 -0
  231. data/docs/guides/dashboards.md +504 -0
  232. data/docs/guides/debugging/README.md +38 -0
  233. data/docs/guides/debugging/controllers.md +147 -0
  234. data/docs/guides/debugging/data.md +165 -0
  235. data/docs/guides/debugging/metadata.md +143 -0
  236. data/docs/guides/debugging/models.md +126 -0
  237. data/docs/guides/debugging/permissions.md +147 -0
  238. data/docs/guides/debugging/presenters.md +151 -0
  239. data/docs/guides/developer-tools.md +418 -0
  240. data/docs/guides/dialogs.md +392 -0
  241. data/docs/guides/display-types.md +1430 -0
  242. data/docs/guides/eager-loading.md +230 -0
  243. data/docs/guides/event-handlers.md +135 -0
  244. data/docs/guides/export.md +305 -0
  245. data/docs/guides/extensibility.md +761 -0
  246. data/docs/guides/groups.md +220 -0
  247. data/docs/guides/hierarchical-authorization.md +427 -0
  248. data/docs/guides/host-application.md +556 -0
  249. data/docs/guides/host-controller-integration.md +473 -0
  250. data/docs/guides/impersonation.md +83 -0
  251. data/docs/guides/import.md +165 -0
  252. data/docs/guides/inherited-permissions.md +459 -0
  253. data/docs/guides/menu.md +373 -0
  254. data/docs/guides/monitoring.md +254 -0
  255. data/docs/guides/oidc-setup.md +399 -0
  256. data/docs/guides/permission-source.md +205 -0
  257. data/docs/guides/permissions.md +364 -0
  258. data/docs/guides/presenters.md +2324 -0
  259. data/docs/guides/record-aliases.md +303 -0
  260. data/docs/guides/rendering-extension-points.md +280 -0
  261. data/docs/guides/role-source.md +288 -0
  262. data/docs/guides/selectbox.md +516 -0
  263. data/docs/guides/sequences.md +291 -0
  264. data/docs/guides/soft-delete.md +460 -0
  265. data/docs/guides/theming.md +129 -0
  266. data/docs/guides/tiles.md +383 -0
  267. data/docs/guides/tree-structures.md +297 -0
  268. data/docs/guides/userstamps.md +288 -0
  269. data/docs/guides/view-groups.md +259 -0
  270. data/docs/guides/view-slots.md +352 -0
  271. data/docs/guides/virtual-columns.md +810 -0
  272. data/docs/guides/workflow.md +692 -0
  273. data/docs/reference/api-backed-models.md +404 -0
  274. data/docs/reference/api-tokens.md +128 -0
  275. data/docs/reference/auditing.md +277 -0
  276. data/docs/reference/boot_lifecycle.md +188 -0
  277. data/docs/reference/cascading_selects.md +189 -0
  278. data/docs/reference/condition-operators.md +445 -0
  279. data/docs/reference/custom-fields.md +483 -0
  280. data/docs/reference/dialogs.md +286 -0
  281. data/docs/reference/doctor.md +168 -0
  282. data/docs/reference/dynamic-references.md +95 -0
  283. data/docs/reference/eager-loading.md +192 -0
  284. data/docs/reference/engine-configuration.md +989 -0
  285. data/docs/reference/export.md +309 -0
  286. data/docs/reference/forms.md +68 -0
  287. data/docs/reference/groups.md +176 -0
  288. data/docs/reference/host-controller-integration.md +342 -0
  289. data/docs/reference/i18n.md +497 -0
  290. data/docs/reference/i18n_check.md +351 -0
  291. data/docs/reference/import.md +260 -0
  292. data/docs/reference/invariant_check.md +216 -0
  293. data/docs/reference/menu.md +985 -0
  294. data/docs/reference/model-dsl.md +1157 -0
  295. data/docs/reference/models.md +2972 -0
  296. data/docs/reference/monitoring.md +222 -0
  297. data/docs/reference/oidc-bearer.md +269 -0
  298. data/docs/reference/oidc.md +407 -0
  299. data/docs/reference/page_filters.md +328 -0
  300. data/docs/reference/pages.md +1375 -0
  301. data/docs/reference/permission-source.md +185 -0
  302. data/docs/reference/permissions.md +715 -0
  303. data/docs/reference/presenter-dsl.md +1719 -0
  304. data/docs/reference/presenters.md +3627 -0
  305. data/docs/reference/role-source.md +227 -0
  306. data/docs/reference/theme-variables.md +139 -0
  307. data/docs/reference/tree-structures.md +374 -0
  308. data/docs/reference/types.md +470 -0
  309. data/docs/reference/view-groups.md +347 -0
  310. data/docs/reference/view-slots.md +228 -0
  311. data/docs/reference/virtual_forms.md +196 -0
  312. data/docs/reference/workflow-approvals.md +387 -0
  313. data/docs/reference/workflow.md +651 -0
  314. data/examples/crm/Gemfile +9 -0
  315. data/examples/crm/Gemfile.lock +417 -0
  316. data/examples/crm/Rakefile +2 -0
  317. data/examples/crm/app/actions/activity/complete.rb +20 -0
  318. data/examples/crm/app/actions/deal/close_won.rb +20 -0
  319. data/examples/crm/app/assets/config/manifest.js +3 -0
  320. data/examples/crm/app/controllers/application_controller.rb +9 -0
  321. data/examples/crm/app/event_handlers/deal/on_stage_change.rb +17 -0
  322. data/examples/crm/app/lcp_services/computed/weighted_deal_value.rb +13 -0
  323. data/examples/crm/app/lcp_services/data_providers/active_contacts_count.rb +14 -0
  324. data/examples/crm/app/lcp_services/data_providers/open_deals_count.rb +14 -0
  325. data/examples/crm/app/lcp_services/data_providers/pending_activities_count.rb +15 -0
  326. data/examples/crm/app/lcp_services/data_providers/pipeline_value.rb +27 -0
  327. data/examples/crm/app/lcp_services/data_providers/won_deals_count.rb +14 -0
  328. data/examples/crm/app/lcp_services/defaults/thirty_days_out.rb +11 -0
  329. data/examples/crm/app/lcp_services/transforms/titlecase.rb +11 -0
  330. data/examples/crm/app/lcp_services/validators/deal_credit_limit.rb +19 -0
  331. data/examples/crm/app/lcp_services/validators/deal_documents_required.rb +17 -0
  332. data/examples/crm/app/renderers/conditional_badge.rb +39 -0
  333. data/examples/crm/bin/rails +4 -0
  334. data/examples/crm/bin/rake +4 -0
  335. data/examples/crm/config/application.rb +31 -0
  336. data/examples/crm/config/boot.rb +2 -0
  337. data/examples/crm/config/database.yml +12 -0
  338. data/examples/crm/config/environment.rb +2 -0
  339. data/examples/crm/config/initializers/lcp_ruby.rb +45 -0
  340. data/examples/crm/config/lcp_ruby/menu.yml +53 -0
  341. data/examples/crm/config/lcp_ruby/models/activity.rb +43 -0
  342. data/examples/crm/config/lcp_ruby/models/city.rb +19 -0
  343. data/examples/crm/config/lcp_ruby/models/company.rb +65 -0
  344. data/examples/crm/config/lcp_ruby/models/contact.rb +62 -0
  345. data/examples/crm/config/lcp_ruby/models/country.rb +22 -0
  346. data/examples/crm/config/lcp_ruby/models/custom_field_definition.rb +60 -0
  347. data/examples/crm/config/lcp_ruby/models/deal.rb +85 -0
  348. data/examples/crm/config/lcp_ruby/models/deal_category.rb +15 -0
  349. data/examples/crm/config/lcp_ruby/models/gapfree_sequence.rb +17 -0
  350. data/examples/crm/config/lcp_ruby/models/region.rb +15 -0
  351. data/examples/crm/config/lcp_ruby/models/saved_filter.rb +50 -0
  352. data/examples/crm/config/lcp_ruby/pages/activity_quick_log.yml +19 -0
  353. data/examples/crm/config/lcp_ruby/pages/company_detail.yml +127 -0
  354. data/examples/crm/config/lcp_ruby/pages/deals_overview.yml +65 -0
  355. data/examples/crm/config/lcp_ruby/permissions/activity.yml +40 -0
  356. data/examples/crm/config/lcp_ruby/permissions/custom_field_definition.yml +16 -0
  357. data/examples/crm/config/lcp_ruby/permissions/deal.yml +54 -0
  358. data/examples/crm/config/lcp_ruby/permissions/default.yml +16 -0
  359. data/examples/crm/config/lcp_ruby/permissions/gapfree_sequence.yml +6 -0
  360. data/examples/crm/config/lcp_ruby/permissions/saved_filter.yml +27 -0
  361. data/examples/crm/config/lcp_ruby/presenters/activity.rb +140 -0
  362. data/examples/crm/config/lcp_ruby/presenters/activity_quick_form.rb +36 -0
  363. data/examples/crm/config/lcp_ruby/presenters/activity_short.rb +16 -0
  364. data/examples/crm/config/lcp_ruby/presenters/activity_tiles.rb +35 -0
  365. data/examples/crm/config/lcp_ruby/presenters/city.rb +53 -0
  366. data/examples/crm/config/lcp_ruby/presenters/company.rb +147 -0
  367. data/examples/crm/config/lcp_ruby/presenters/company_activities_zone.rb +26 -0
  368. data/examples/crm/config/lcp_ruby/presenters/company_archive.rb +37 -0
  369. data/examples/crm/config/lcp_ruby/presenters/company_contacts_zone.rb +22 -0
  370. data/examples/crm/config/lcp_ruby/presenters/company_deals_zone.rb +36 -0
  371. data/examples/crm/config/lcp_ruby/presenters/company_short.rb +21 -0
  372. data/examples/crm/config/lcp_ruby/presenters/company_show_zone.rb +38 -0
  373. data/examples/crm/config/lcp_ruby/presenters/company_sidebar.rb +15 -0
  374. data/examples/crm/config/lcp_ruby/presenters/company_tiles.rb +35 -0
  375. data/examples/crm/config/lcp_ruby/presenters/contact.rb +120 -0
  376. data/examples/crm/config/lcp_ruby/presenters/contact_quick_form.rb +17 -0
  377. data/examples/crm/config/lcp_ruby/presenters/contact_short.rb +20 -0
  378. data/examples/crm/config/lcp_ruby/presenters/contact_tiles.rb +34 -0
  379. data/examples/crm/config/lcp_ruby/presenters/country.rb +44 -0
  380. data/examples/crm/config/lcp_ruby/presenters/custom_fields.rb +124 -0
  381. data/examples/crm/config/lcp_ruby/presenters/deal.rb +181 -0
  382. data/examples/crm/config/lcp_ruby/presenters/deal_category.rb +46 -0
  383. data/examples/crm/config/lcp_ruby/presenters/deal_overview.rb +6 -0
  384. data/examples/crm/config/lcp_ruby/presenters/deal_pipeline.rb +18 -0
  385. data/examples/crm/config/lcp_ruby/presenters/deal_short.rb +25 -0
  386. data/examples/crm/config/lcp_ruby/presenters/deal_tiles.rb +48 -0
  387. data/examples/crm/config/lcp_ruby/presenters/region.rb +42 -0
  388. data/examples/crm/config/lcp_ruby/presenters/save_filter_dialog.rb +17 -0
  389. data/examples/crm/config/lcp_ruby/presenters/saved_filters.rb +93 -0
  390. data/examples/crm/config/lcp_ruby/views/activities.yml +16 -0
  391. data/examples/crm/config/lcp_ruby/views/cities.yml +10 -0
  392. data/examples/crm/config/lcp_ruby/views/companies.yml +14 -0
  393. data/examples/crm/config/lcp_ruby/views/contacts.yml +16 -0
  394. data/examples/crm/config/lcp_ruby/views/countries.yml +8 -0
  395. data/examples/crm/config/lcp_ruby/views/custom_fields.rb +9 -0
  396. data/examples/crm/config/lcp_ruby/views/deal_categories.yml +8 -0
  397. data/examples/crm/config/lcp_ruby/views/deals.yml +19 -0
  398. data/examples/crm/config/lcp_ruby/views/pipeline.yml +10 -0
  399. data/examples/crm/config/lcp_ruby/views/regions.yml +10 -0
  400. data/examples/crm/config/lcp_ruby/views/saved_filters.yml +7 -0
  401. data/examples/crm/config/locales/cs.yml +338 -0
  402. data/examples/crm/config/locales/en.yml +353 -0
  403. data/examples/crm/config/routes.rb +4 -0
  404. data/examples/crm/config/storage.yml +3 -0
  405. data/examples/crm/config.ru +2 -0
  406. data/examples/crm/db/migrate/20260219104942_create_active_storage_tables.active_storage.rb +57 -0
  407. data/examples/crm/db/schema.rb +245 -0
  408. data/examples/crm/db/seeds.rb +1111 -0
  409. data/examples/crm/erd.md +163 -0
  410. data/examples/hr/Gemfile +9 -0
  411. data/examples/hr/Gemfile.lock +419 -0
  412. data/examples/hr/Rakefile +6 -0
  413. data/examples/hr/app/actions/asset/assign_asset.rb +20 -0
  414. data/examples/hr/app/actions/asset/return_asset.rb +20 -0
  415. data/examples/hr/app/actions/candidate/advance.rb +32 -0
  416. data/examples/hr/app/actions/candidate/hire.rb +20 -0
  417. data/examples/hr/app/actions/candidate/reject_candidate.rb +20 -0
  418. data/examples/hr/app/actions/expense_claim/approve.rb +21 -0
  419. data/examples/hr/app/actions/expense_claim/reject.rb +21 -0
  420. data/examples/hr/app/actions/expense_claim/submit.rb +20 -0
  421. data/examples/hr/app/actions/interview/complete_interview.rb +20 -0
  422. data/examples/hr/app/actions/leave_request/approve.rb +21 -0
  423. data/examples/hr/app/actions/leave_request/cancel.rb +20 -0
  424. data/examples/hr/app/actions/leave_request/reject.rb +21 -0
  425. data/examples/hr/app/assets/config/manifest.js +1 -0
  426. data/examples/hr/app/assets/stylesheets/application.css +10 -0
  427. data/examples/hr/app/condition_services/is_own_org_unit.rb +14 -0
  428. data/examples/hr/app/condition_services/is_own_record.rb +20 -0
  429. data/examples/hr/app/controllers/application_controller.rb +15 -0
  430. data/examples/hr/app/event_handlers/asset_assignment/on_create.rb +24 -0
  431. data/examples/hr/app/event_handlers/candidate/on_status_change.rb +18 -0
  432. data/examples/hr/app/event_handlers/leave_request/on_status_change.rb +45 -0
  433. data/examples/hr/app/helpers/application_helper.rb +2 -0
  434. data/examples/hr/app/javascript/application.js +1 -0
  435. data/examples/hr/app/jobs/application_job.rb +7 -0
  436. data/examples/hr/app/lcp_services/computed/employee_tenure.rb +28 -0
  437. data/examples/hr/app/lcp_services/computed/leave_remaining.rb +13 -0
  438. data/examples/hr/app/lcp_services/data_providers/headcount_text.rb +14 -0
  439. data/examples/hr/app/lcp_services/data_providers/open_positions_count.rb +14 -0
  440. data/examples/hr/app/lcp_services/data_providers/pending_expenses_count.rb +14 -0
  441. data/examples/hr/app/lcp_services/data_providers/pending_leaves_count.rb +14 -0
  442. data/examples/hr/app/lcp_services/defaults/current_year.rb +11 -0
  443. data/examples/hr/app/lcp_services/transforms/titlecase.rb +11 -0
  444. data/examples/hr/app/lcp_services/validators/expense_receipt_required.rb +17 -0
  445. data/examples/hr/app/lcp_services/validators/leave_balance_check.rb +37 -0
  446. data/examples/hr/app/models/application_record.rb +3 -0
  447. data/examples/hr/app/views/layouts/application.html.erb +29 -0
  448. data/examples/hr/app/views/pwa/manifest.json.erb +22 -0
  449. data/examples/hr/app/views/pwa/service-worker.js +26 -0
  450. data/examples/hr/bin/brakeman +7 -0
  451. data/examples/hr/bin/bundler-audit +6 -0
  452. data/examples/hr/bin/ci +6 -0
  453. data/examples/hr/bin/dev +2 -0
  454. data/examples/hr/bin/docker-entrypoint +8 -0
  455. data/examples/hr/bin/importmap +4 -0
  456. data/examples/hr/bin/jobs +6 -0
  457. data/examples/hr/bin/kamal +27 -0
  458. data/examples/hr/bin/rails +4 -0
  459. data/examples/hr/bin/rake +4 -0
  460. data/examples/hr/bin/rubocop +8 -0
  461. data/examples/hr/bin/setup +35 -0
  462. data/examples/hr/bin/thrust +5 -0
  463. data/examples/hr/config/application.rb +31 -0
  464. data/examples/hr/config/boot.rb +2 -0
  465. data/examples/hr/config/bundler-audit.yml +5 -0
  466. data/examples/hr/config/cache.yml +16 -0
  467. data/examples/hr/config/ci.rb +20 -0
  468. data/examples/hr/config/credentials.yml.enc +1 -0
  469. data/examples/hr/config/database.yml +36 -0
  470. data/examples/hr/config/deploy.yml +119 -0
  471. data/examples/hr/config/environment.rb +5 -0
  472. data/examples/hr/config/environments/development.rb +66 -0
  473. data/examples/hr/config/environments/production.rb +74 -0
  474. data/examples/hr/config/environments/test.rb +45 -0
  475. data/examples/hr/config/importmap.rb +3 -0
  476. data/examples/hr/config/initializers/assets.rb +7 -0
  477. data/examples/hr/config/initializers/content_security_policy.rb +29 -0
  478. data/examples/hr/config/initializers/filter_parameter_logging.rb +8 -0
  479. data/examples/hr/config/initializers/inflections.rb +16 -0
  480. data/examples/hr/config/initializers/lcp_ruby.rb +18 -0
  481. data/examples/hr/config/lcp_ruby/menu.yml +86 -0
  482. data/examples/hr/config/lcp_ruby/models/announcement.rb +33 -0
  483. data/examples/hr/config/lcp_ruby/models/asset.rb +73 -0
  484. data/examples/hr/config/lcp_ruby/models/asset_assignment.rb +39 -0
  485. data/examples/hr/config/lcp_ruby/models/audit_log.yml +57 -0
  486. data/examples/hr/config/lcp_ruby/models/candidate.rb +68 -0
  487. data/examples/hr/config/lcp_ruby/models/custom_field_definition.rb +60 -0
  488. data/examples/hr/config/lcp_ruby/models/dashboard.rb +17 -0
  489. data/examples/hr/config/lcp_ruby/models/document.rb +38 -0
  490. data/examples/hr/config/lcp_ruby/models/employee.rb +128 -0
  491. data/examples/hr/config/lcp_ruby/models/employee_skill.rb +29 -0
  492. data/examples/hr/config/lcp_ruby/models/expense_claim.rb +70 -0
  493. data/examples/hr/config/lcp_ruby/models/goal.rb +48 -0
  494. data/examples/hr/config/lcp_ruby/models/group.rb +37 -0
  495. data/examples/hr/config/lcp_ruby/models/group_membership.rb +26 -0
  496. data/examples/hr/config/lcp_ruby/models/interview.rb +54 -0
  497. data/examples/hr/config/lcp_ruby/models/job_posting.rb +67 -0
  498. data/examples/hr/config/lcp_ruby/models/leave_balance.rb +31 -0
  499. data/examples/hr/config/lcp_ruby/models/leave_request.rb +52 -0
  500. data/examples/hr/config/lcp_ruby/models/leave_type.rb +35 -0
  501. data/examples/hr/config/lcp_ruby/models/organization_unit.rb +42 -0
  502. data/examples/hr/config/lcp_ruby/models/performance_review.rb +59 -0
  503. data/examples/hr/config/lcp_ruby/models/position.rb +43 -0
  504. data/examples/hr/config/lcp_ruby/models/skill.rb +27 -0
  505. data/examples/hr/config/lcp_ruby/models/training_course.rb +53 -0
  506. data/examples/hr/config/lcp_ruby/models/training_enrollment.rb +35 -0
  507. data/examples/hr/config/lcp_ruby/pages/dashboard.yml +101 -0
  508. data/examples/hr/config/lcp_ruby/permissions/announcement.yml +25 -0
  509. data/examples/hr/config/lcp_ruby/permissions/asset.yml +35 -0
  510. data/examples/hr/config/lcp_ruby/permissions/audit_log.yml +28 -0
  511. data/examples/hr/config/lcp_ruby/permissions/candidate.yml +25 -0
  512. data/examples/hr/config/lcp_ruby/permissions/custom_field_definition.yml +28 -0
  513. data/examples/hr/config/lcp_ruby/permissions/dashboard.yml +25 -0
  514. data/examples/hr/config/lcp_ruby/permissions/default.yml +25 -0
  515. data/examples/hr/config/lcp_ruby/permissions/document.yml +37 -0
  516. data/examples/hr/config/lcp_ruby/permissions/employee.yml +55 -0
  517. data/examples/hr/config/lcp_ruby/permissions/expense_claim.yml +45 -0
  518. data/examples/hr/config/lcp_ruby/permissions/group.yml +27 -0
  519. data/examples/hr/config/lcp_ruby/permissions/job_posting.yml +34 -0
  520. data/examples/hr/config/lcp_ruby/permissions/leave_request.yml +45 -0
  521. data/examples/hr/config/lcp_ruby/permissions/performance_review.yml +42 -0
  522. data/examples/hr/config/lcp_ruby/presenters/announcement.rb +47 -0
  523. data/examples/hr/config/lcp_ruby/presenters/asset.rb +69 -0
  524. data/examples/hr/config/lcp_ruby/presenters/asset_assignment.rb +47 -0
  525. data/examples/hr/config/lcp_ruby/presenters/audit_logs.yml +43 -0
  526. data/examples/hr/config/lcp_ruby/presenters/candidate.rb +71 -0
  527. data/examples/hr/config/lcp_ruby/presenters/custom_fields.rb +124 -0
  528. data/examples/hr/config/lcp_ruby/presenters/dashboard.rb +37 -0
  529. data/examples/hr/config/lcp_ruby/presenters/document.rb +46 -0
  530. data/examples/hr/config/lcp_ruby/presenters/employee.rb +167 -0
  531. data/examples/hr/config/lcp_ruby/presenters/employee_archive.rb +38 -0
  532. data/examples/hr/config/lcp_ruby/presenters/employee_directory.rb +27 -0
  533. data/examples/hr/config/lcp_ruby/presenters/employee_skill.rb +57 -0
  534. data/examples/hr/config/lcp_ruby/presenters/expense_claim.rb +76 -0
  535. data/examples/hr/config/lcp_ruby/presenters/goal.rb +60 -0
  536. data/examples/hr/config/lcp_ruby/presenters/group.rb +48 -0
  537. data/examples/hr/config/lcp_ruby/presenters/interview.rb +59 -0
  538. data/examples/hr/config/lcp_ruby/presenters/job_posting.rb +73 -0
  539. data/examples/hr/config/lcp_ruby/presenters/leave_balance.rb +50 -0
  540. data/examples/hr/config/lcp_ruby/presenters/leave_request.rb +89 -0
  541. data/examples/hr/config/lcp_ruby/presenters/leave_type.rb +52 -0
  542. data/examples/hr/config/lcp_ruby/presenters/organization_unit.rb +56 -0
  543. data/examples/hr/config/lcp_ruby/presenters/performance_review.rb +87 -0
  544. data/examples/hr/config/lcp_ruby/presenters/position.rb +54 -0
  545. data/examples/hr/config/lcp_ruby/presenters/skill.rb +45 -0
  546. data/examples/hr/config/lcp_ruby/presenters/training_course.rb +61 -0
  547. data/examples/hr/config/lcp_ruby/presenters/training_enrollment.rb +49 -0
  548. data/examples/hr/config/lcp_ruby/views/announcements.yml +8 -0
  549. data/examples/hr/config/lcp_ruby/views/asset_assignments.yml +10 -0
  550. data/examples/hr/config/lcp_ruby/views/assets.yml +8 -0
  551. data/examples/hr/config/lcp_ruby/views/audit_logs.yml +8 -0
  552. data/examples/hr/config/lcp_ruby/views/candidates.yml +8 -0
  553. data/examples/hr/config/lcp_ruby/views/custom_fields.yml +8 -0
  554. data/examples/hr/config/lcp_ruby/views/dashboard.yml +6 -0
  555. data/examples/hr/config/lcp_ruby/views/documents.yml +10 -0
  556. data/examples/hr/config/lcp_ruby/views/employee_skills.yml +10 -0
  557. data/examples/hr/config/lcp_ruby/views/employees.yml +14 -0
  558. data/examples/hr/config/lcp_ruby/views/expense_claims.yml +10 -0
  559. data/examples/hr/config/lcp_ruby/views/goals.yml +10 -0
  560. data/examples/hr/config/lcp_ruby/views/groups.yml +8 -0
  561. data/examples/hr/config/lcp_ruby/views/interviews.yml +8 -0
  562. data/examples/hr/config/lcp_ruby/views/job_postings.yml +6 -0
  563. data/examples/hr/config/lcp_ruby/views/leave_balances.yml +10 -0
  564. data/examples/hr/config/lcp_ruby/views/leave_requests.yml +10 -0
  565. data/examples/hr/config/lcp_ruby/views/leave_types.yml +8 -0
  566. data/examples/hr/config/lcp_ruby/views/organization_units.yml +8 -0
  567. data/examples/hr/config/lcp_ruby/views/performance_reviews.yml +10 -0
  568. data/examples/hr/config/lcp_ruby/views/positions.yml +8 -0
  569. data/examples/hr/config/lcp_ruby/views/skills.yml +8 -0
  570. data/examples/hr/config/lcp_ruby/views/training_courses.yml +8 -0
  571. data/examples/hr/config/lcp_ruby/views/training_enrollments.yml +10 -0
  572. data/examples/hr/config/locales/cs.yml +496 -0
  573. data/examples/hr/config/locales/en.yml +740 -0
  574. data/examples/hr/config/locales/sk.yml +496 -0
  575. data/examples/hr/config/puma.rb +42 -0
  576. data/examples/hr/config/queue.yml +18 -0
  577. data/examples/hr/config/recurring.yml +15 -0
  578. data/examples/hr/config/routes.rb +4 -0
  579. data/examples/hr/config/storage.yml +27 -0
  580. data/examples/hr/config.ru +6 -0
  581. data/examples/hr/db/cache_schema.rb +12 -0
  582. data/examples/hr/db/migrate/20260303202825_create_active_storage_tables.active_storage.rb +57 -0
  583. data/examples/hr/db/queue_schema.rb +129 -0
  584. data/examples/hr/db/schema.rb +588 -0
  585. data/examples/hr/db/seeds.rb +932 -0
  586. data/examples/hr/erd.md +396 -0
  587. data/examples/hr/public/400.html +135 -0
  588. data/examples/hr/public/404.html +135 -0
  589. data/examples/hr/public/406-unsupported-browser.html +135 -0
  590. data/examples/hr/public/422.html +135 -0
  591. data/examples/hr/public/500.html +135 -0
  592. data/examples/hr/public/icon.svg +3 -0
  593. data/examples/hr/public/robots.txt +1 -0
  594. data/examples/showcase/Gemfile +15 -0
  595. data/examples/showcase/Gemfile.lock +425 -0
  596. data/examples/showcase/Rakefile +2 -0
  597. data/examples/showcase/app/actions/showcase_batch_task/assign_batch.rb +20 -0
  598. data/examples/showcase/app/actions/showcase_batch_task/close_task.rb +21 -0
  599. data/examples/showcase/app/actions/showcase_condition/approve.rb +20 -0
  600. data/examples/showcase/app/actions/showcase_permission/lock.rb +20 -0
  601. data/examples/showcase/app/assets/config/manifest.js +3 -0
  602. data/examples/showcase/app/assets/stylesheets/application.css +27 -0
  603. data/examples/showcase/app/condition_services/budget_threshold.rb +16 -0
  604. data/examples/showcase/app/condition_services/overdue_check.rb +11 -0
  605. data/examples/showcase/app/controllers/application_controller.rb +2 -0
  606. data/examples/showcase/app/controllers/docs_controller.rb +48 -0
  607. data/examples/showcase/app/controllers/host_inventory_items_managed_controller.rb +90 -0
  608. data/examples/showcase/app/controllers/host_inventory_items_report_controller.rb +39 -0
  609. data/examples/showcase/app/controllers/host_inventory_items_wizard_controller.rb +50 -0
  610. data/examples/showcase/app/data_providers/showcase_amount_provider.rb +52 -0
  611. data/examples/showcase/app/data_providers/weather_station_provider.rb +140 -0
  612. data/examples/showcase/app/event_handlers/showcase_model/on_status_change.rb +17 -0
  613. data/examples/showcase/app/event_handlers/showcase_permission/on_status_change.rb +17 -0
  614. data/examples/showcase/app/event_handlers/showcase_workflow/log_review_exit.rb +16 -0
  615. data/examples/showcase/app/event_handlers/showcase_workflow/notify_reviewers.rb +15 -0
  616. data/examples/showcase/app/event_handlers/showcase_workflow/request_submitted.rb +15 -0
  617. data/examples/showcase/app/lcp_metrics/showcase_metrics.rb +31 -0
  618. data/examples/showcase/app/lcp_services/computed/showcase_score.rb +18 -0
  619. data/examples/showcase/app/lcp_services/computed/showcase_total.rb +13 -0
  620. data/examples/showcase/app/lcp_services/defaults/one_week_from_now.rb +11 -0
  621. data/examples/showcase/app/lcp_services/menu_items/recent_announcements.rb +36 -0
  622. data/examples/showcase/app/lcp_services/virtual_columns/project_health.rb +26 -0
  623. data/examples/showcase/app/model_extensions/lcp_error_log_extension.rb +12 -0
  624. data/examples/showcase/app/models/host_inventory_item.rb +20 -0
  625. data/examples/showcase/app/models/platform_profile.rb +27 -0
  626. data/examples/showcase/app/models/platform_user.rb +5 -0
  627. data/examples/showcase/app/views/docs/show.html.erb +19 -0
  628. data/examples/showcase/app/views/host_inventory_items_report/index.html.erb +61 -0
  629. data/examples/showcase/app/views/host_inventory_items_report/show.html.erb +39 -0
  630. data/examples/showcase/app/views/layouts/docs.html.erb +46 -0
  631. data/examples/showcase/app/views/showcase/menu_renderers/_status_pill.html.erb +17 -0
  632. data/examples/showcase/app/views/showcase_custom/_activity_timeline.html.erb +37 -0
  633. data/examples/showcase/app/views/showcase_custom/_card_index.html.erb +74 -0
  634. data/examples/showcase/app/views/showcase_custom/_detail_show.html.erb +115 -0
  635. data/examples/showcase/app/views/showcase_custom/_location_map.html.erb +29 -0
  636. data/examples/showcase/app/views/showcase_custom/_location_view.html.erb +34 -0
  637. data/examples/showcase/app/views/showcase_custom/_quick_stats.html.erb +50 -0
  638. data/examples/showcase/app/views/showcase_custom/_stats_sidebar.html.erb +42 -0
  639. data/examples/showcase/app/views/showcase_custom/_tags_editor.html.erb +48 -0
  640. data/examples/showcase/bin/rails +4 -0
  641. data/examples/showcase/bin/rake +4 -0
  642. data/examples/showcase/config/application.rb +37 -0
  643. data/examples/showcase/config/boot.rb +2 -0
  644. data/examples/showcase/config/database.yml +12 -0
  645. data/examples/showcase/config/environment.rb +2 -0
  646. data/examples/showcase/config/initializers/devise.rb +5 -0
  647. data/examples/showcase/config/initializers/lcp_ruby.rb +175 -0
  648. data/examples/showcase/config/lcp_ruby/auth.yml +60 -0
  649. data/examples/showcase/config/lcp_ruby/jobs/data_import.yml +7 -0
  650. data/examples/showcase/config/lcp_ruby/jobs/showcase_cleanup.yml +11 -0
  651. data/examples/showcase/config/lcp_ruby/jobs/showcase_event_triggered.yml +11 -0
  652. data/examples/showcase/config/lcp_ruby/jobs/showcase_multi_step.yml +9 -0
  653. data/examples/showcase/config/lcp_ruby/jobs/showcase_webhook.yml +13 -0
  654. data/examples/showcase/config/lcp_ruby/menu.yml +249 -0
  655. data/examples/showcase/config/lcp_ruby/models/_base_document.rb +26 -0
  656. data/examples/showcase/config/lcp_ruby/models/_categorized_document.rb +19 -0
  657. data/examples/showcase/config/lcp_ruby/models/_contactable.rb +20 -0
  658. data/examples/showcase/config/lcp_ruby/models/api_token.rb +23 -0
  659. data/examples/showcase/config/lcp_ruby/models/article.rb +49 -0
  660. data/examples/showcase/config/lcp_ruby/models/article_tag.rb +10 -0
  661. data/examples/showcase/config/lcp_ruby/models/author.rb +16 -0
  662. data/examples/showcase/config/lcp_ruby/models/batch_operation.yml +79 -0
  663. data/examples/showcase/config/lcp_ruby/models/batch_operation_item.yml +45 -0
  664. data/examples/showcase/config/lcp_ruby/models/category.rb +23 -0
  665. data/examples/showcase/config/lcp_ruby/models/comment.rb +21 -0
  666. data/examples/showcase/config/lcp_ruby/models/custom_field_definition.rb +59 -0
  667. data/examples/showcase/config/lcp_ruby/models/department.rb +32 -0
  668. data/examples/showcase/config/lcp_ruby/models/employee.rb +52 -0
  669. data/examples/showcase/config/lcp_ruby/models/employee_emergency_contact.rb +24 -0
  670. data/examples/showcase/config/lcp_ruby/models/employee_profile.rb +18 -0
  671. data/examples/showcase/config/lcp_ruby/models/employee_skill.rb +10 -0
  672. data/examples/showcase/config/lcp_ruby/models/export_log.yml +27 -0
  673. data/examples/showcase/config/lcp_ruby/models/export_profile.yml +37 -0
  674. data/examples/showcase/config/lcp_ruby/models/feature.rb +76 -0
  675. data/examples/showcase/config/lcp_ruby/models/gapfree_sequence.rb +17 -0
  676. data/examples/showcase/config/lcp_ruby/models/group.rb +26 -0
  677. data/examples/showcase/config/lcp_ruby/models/group_membership.rb +21 -0
  678. data/examples/showcase/config/lcp_ruby/models/group_role_mapping.rb +14 -0
  679. data/examples/showcase/config/lcp_ruby/models/host_inventory_item.yml +111 -0
  680. data/examples/showcase/config/lcp_ruby/models/import_profile.rb +30 -0
  681. data/examples/showcase/config/lcp_ruby/models/import_row.rb +32 -0
  682. data/examples/showcase/config/lcp_ruby/models/ingredient_def.rb +11 -0
  683. data/examples/showcase/config/lcp_ruby/models/lcp_error_log.yml +61 -0
  684. data/examples/showcase/config/lcp_ruby/models/page_config.rb +19 -0
  685. data/examples/showcase/config/lcp_ruby/models/permission_config.rb +21 -0
  686. data/examples/showcase/config/lcp_ruby/models/pipeline.rb +15 -0
  687. data/examples/showcase/config/lcp_ruby/models/pipeline_stage.rb +17 -0
  688. data/examples/showcase/config/lcp_ruby/models/platform_profile.rb +104 -0
  689. data/examples/showcase/config/lcp_ruby/models/profile_setting.rb +17 -0
  690. data/examples/showcase/config/lcp_ruby/models/profile_tag.rb +19 -0
  691. data/examples/showcase/config/lcp_ruby/models/project.rb +23 -0
  692. data/examples/showcase/config/lcp_ruby/models/role.rb +24 -0
  693. data/examples/showcase/config/lcp_ruby/models/saved_filter.rb +50 -0
  694. data/examples/showcase/config/lcp_ruby/models/showcase_aggregate.rb +93 -0
  695. data/examples/showcase/config/lcp_ruby/models/showcase_aggregate_company.rb +14 -0
  696. data/examples/showcase/config/lcp_ruby/models/showcase_aggregate_item.rb +25 -0
  697. data/examples/showcase/config/lcp_ruby/models/showcase_announcement.rb +20 -0
  698. data/examples/showcase/config/lcp_ruby/models/showcase_array.rb +45 -0
  699. data/examples/showcase/config/lcp_ruby/models/showcase_attachment.rb +49 -0
  700. data/examples/showcase/config/lcp_ruby/models/showcase_audit_log.yml +44 -0
  701. data/examples/showcase/config/lcp_ruby/models/showcase_audited_record.rb +20 -0
  702. data/examples/showcase/config/lcp_ruby/models/showcase_batch_task.rb +27 -0
  703. data/examples/showcase/config/lcp_ruby/models/showcase_business_unit.rb +26 -0
  704. data/examples/showcase/config/lcp_ruby/models/showcase_condition.rb +24 -0
  705. data/examples/showcase/config/lcp_ruby/models/showcase_condition_category.rb +16 -0
  706. data/examples/showcase/config/lcp_ruby/models/showcase_condition_task.rb +16 -0
  707. data/examples/showcase/config/lcp_ruby/models/showcase_condition_threshold.rb +13 -0
  708. data/examples/showcase/config/lcp_ruby/models/showcase_contact.rb +22 -0
  709. data/examples/showcase/config/lcp_ruby/models/showcase_custom_render.rb +38 -0
  710. data/examples/showcase/config/lcp_ruby/models/showcase_delete_reason.rb +11 -0
  711. data/examples/showcase/config/lcp_ruby/models/showcase_division.rb +31 -0
  712. data/examples/showcase/config/lcp_ruby/models/showcase_extensibility.rb +25 -0
  713. data/examples/showcase/config/lcp_ruby/models/showcase_field.rb +53 -0
  714. data/examples/showcase/config/lcp_ruby/models/showcase_form.rb +23 -0
  715. data/examples/showcase/config/lcp_ruby/models/showcase_form_action.rb +38 -0
  716. data/examples/showcase/config/lcp_ruby/models/showcase_grade.rb +18 -0
  717. data/examples/showcase/config/lcp_ruby/models/showcase_hr_employee.rb +90 -0
  718. data/examples/showcase/config/lcp_ruby/models/showcase_item_class.rb +31 -0
  719. data/examples/showcase/config/lcp_ruby/models/showcase_job_execution.rb +49 -0
  720. data/examples/showcase/config/lcp_ruby/models/showcase_memo.rb +23 -0
  721. data/examples/showcase/config/lcp_ruby/models/showcase_model.rb +74 -0
  722. data/examples/showcase/config/lcp_ruby/models/showcase_organization.rb +31 -0
  723. data/examples/showcase/config/lcp_ruby/models/showcase_permission.rb +30 -0
  724. data/examples/showcase/config/lcp_ruby/models/showcase_person.rb +23 -0
  725. data/examples/showcase/config/lcp_ruby/models/showcase_positioning.rb +19 -0
  726. data/examples/showcase/config/lcp_ruby/models/showcase_quick_note.rb +13 -0
  727. data/examples/showcase/config/lcp_ruby/models/showcase_recipe.rb +17 -0
  728. data/examples/showcase/config/lcp_ruby/models/showcase_report.rb +32 -0
  729. data/examples/showcase/config/lcp_ruby/models/showcase_school_class.rb +17 -0
  730. data/examples/showcase/config/lcp_ruby/models/showcase_search.rb +84 -0
  731. data/examples/showcase/config/lcp_ruby/models/showcase_sequence.rb +46 -0
  732. data/examples/showcase/config/lcp_ruby/models/showcase_soft_delete.rb +30 -0
  733. data/examples/showcase/config/lcp_ruby/models/showcase_soft_delete_item.rb +21 -0
  734. data/examples/showcase/config/lcp_ruby/models/showcase_student.rb +17 -0
  735. data/examples/showcase/config/lcp_ruby/models/showcase_type_default.rb +49 -0
  736. data/examples/showcase/config/lcp_ruby/models/showcase_userstamps.rb +26 -0
  737. data/examples/showcase/config/lcp_ruby/models/showcase_virtual_field.rb +68 -0
  738. data/examples/showcase/config/lcp_ruby/models/showcase_workflow.rb +54 -0
  739. data/examples/showcase/config/lcp_ruby/models/skill.rb +22 -0
  740. data/examples/showcase/config/lcp_ruby/models/tag.rb +16 -0
  741. data/examples/showcase/config/lcp_ruby/models/user.rb +54 -0
  742. data/examples/showcase/config/lcp_ruby/models/weather_station.rb +20 -0
  743. data/examples/showcase/config/lcp_ruby/models/workflow_approval_request.yml +77 -0
  744. data/examples/showcase/config/lcp_ruby/models/workflow_approval_step.yml +56 -0
  745. data/examples/showcase/config/lcp_ruby/models/workflow_approval_task.yml +51 -0
  746. data/examples/showcase/config/lcp_ruby/models/workflow_audit_log.yml +74 -0
  747. data/examples/showcase/config/lcp_ruby/pages/article_detail.yml +32 -0
  748. data/examples/showcase/config/lcp_ruby/pages/author_detail.yml +27 -0
  749. data/examples/showcase/config/lcp_ruby/pages/category_detail.yml +24 -0
  750. data/examples/showcase/config/lcp_ruby/pages/chart_showcase.yml +151 -0
  751. data/examples/showcase/config/lcp_ruby/pages/department_detail.yml +55 -0
  752. data/examples/showcase/config/lcp_ruby/pages/department_explorer.yml +60 -0
  753. data/examples/showcase/config/lcp_ruby/pages/employee_overview.yml +106 -0
  754. data/examples/showcase/config/lcp_ruby/pages/employee_transfer_dialog.yml +24 -0
  755. data/examples/showcase/config/lcp_ruby/pages/hr_turnover_dashboard.yml +288 -0
  756. data/examples/showcase/config/lcp_ruby/pages/main_dashboard.yml +142 -0
  757. data/examples/showcase/config/lcp_ruby/pages/monitoring_dashboard.yml +58 -0
  758. data/examples/showcase/config/lcp_ruby/pages/pipeline_detail.yml +16 -0
  759. data/examples/showcase/config/lcp_ruby/pages/showcase_custom_zones.yml +39 -0
  760. data/examples/showcase/config/lcp_ruby/pages/showcase_form_action_dialog.yml +11 -0
  761. data/examples/showcase/config/lcp_ruby/pages/workflow_request_detail.yml +34 -0
  762. data/examples/showcase/config/lcp_ruby/permissions/api_token.yml +26 -0
  763. data/examples/showcase/config/lcp_ruby/permissions/batch_operation.yml +36 -0
  764. data/examples/showcase/config/lcp_ruby/permissions/custom_field_definition.yml +15 -0
  765. data/examples/showcase/config/lcp_ruby/permissions/default.yml +28 -0
  766. data/examples/showcase/config/lcp_ruby/permissions/export_log.yml +23 -0
  767. data/examples/showcase/config/lcp_ruby/permissions/export_profile.yml +25 -0
  768. data/examples/showcase/config/lcp_ruby/permissions/gapfree_sequence.yml +6 -0
  769. data/examples/showcase/config/lcp_ruby/permissions/group.yml +20 -0
  770. data/examples/showcase/config/lcp_ruby/permissions/group_membership.yml +20 -0
  771. data/examples/showcase/config/lcp_ruby/permissions/group_role_mapping.yml +20 -0
  772. data/examples/showcase/config/lcp_ruby/permissions/host_inventory_item.yml +34 -0
  773. data/examples/showcase/config/lcp_ruby/permissions/import_profile.yml +29 -0
  774. data/examples/showcase/config/lcp_ruby/permissions/import_row.yml +17 -0
  775. data/examples/showcase/config/lcp_ruby/permissions/lcp_error_log.yml +8 -0
  776. data/examples/showcase/config/lcp_ruby/permissions/page_config.yml +15 -0
  777. data/examples/showcase/config/lcp_ruby/permissions/permission_config.yml +15 -0
  778. data/examples/showcase/config/lcp_ruby/permissions/platform_profile.yml +23 -0
  779. data/examples/showcase/config/lcp_ruby/permissions/profile_setting.yml +23 -0
  780. data/examples/showcase/config/lcp_ruby/permissions/profile_tag.yml +23 -0
  781. data/examples/showcase/config/lcp_ruby/permissions/role.yml +20 -0
  782. data/examples/showcase/config/lcp_ruby/permissions/saved_filter.yml +39 -0
  783. data/examples/showcase/config/lcp_ruby/permissions/showcase_announcement.yml +22 -0
  784. data/examples/showcase/config/lcp_ruby/permissions/showcase_audit_log.yml +15 -0
  785. data/examples/showcase/config/lcp_ruby/permissions/showcase_audited_record.yml +15 -0
  786. data/examples/showcase/config/lcp_ruby/permissions/showcase_batch_task.yml +31 -0
  787. data/examples/showcase/config/lcp_ruby/permissions/showcase_condition.yml +54 -0
  788. data/examples/showcase/config/lcp_ruby/permissions/showcase_contact.yml +21 -0
  789. data/examples/showcase/config/lcp_ruby/permissions/showcase_custom_render.yml +21 -0
  790. data/examples/showcase/config/lcp_ruby/permissions/showcase_delete_reason.yml +12 -0
  791. data/examples/showcase/config/lcp_ruby/permissions/showcase_form_action.yml +26 -0
  792. data/examples/showcase/config/lcp_ruby/permissions/showcase_grade.yml +33 -0
  793. data/examples/showcase/config/lcp_ruby/permissions/showcase_job_execution.yml +23 -0
  794. data/examples/showcase/config/lcp_ruby/permissions/showcase_permission.yml +47 -0
  795. data/examples/showcase/config/lcp_ruby/permissions/showcase_quick_note.yml +12 -0
  796. data/examples/showcase/config/lcp_ruby/permissions/showcase_school_class.yml +37 -0
  797. data/examples/showcase/config/lcp_ruby/permissions/showcase_student.yml +43 -0
  798. data/examples/showcase/config/lcp_ruby/permissions/showcase_workflow.yml +34 -0
  799. data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_request.yml +18 -0
  800. data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_step.yml +18 -0
  801. data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_task.yml +18 -0
  802. data/examples/showcase/config/lcp_ruby/permissions/workflow_audit_log.yml +19 -0
  803. data/examples/showcase/config/lcp_ruby/presenters/announcements.rb +59 -0
  804. data/examples/showcase/config/lcp_ruby/presenters/approval_requests.rb +69 -0
  805. data/examples/showcase/config/lcp_ruby/presenters/approval_steps.rb +59 -0
  806. data/examples/showcase/config/lcp_ruby/presenters/approval_tasks.rb +65 -0
  807. data/examples/showcase/config/lcp_ruby/presenters/article_comments_zone.rb +12 -0
  808. data/examples/showcase/config/lcp_ruby/presenters/article_related_zone.rb +15 -0
  809. data/examples/showcase/config/lcp_ruby/presenters/articles.rb +149 -0
  810. data/examples/showcase/config/lcp_ruby/presenters/articles_tiles.rb +30 -0
  811. data/examples/showcase/config/lcp_ruby/presenters/author_articles_zone.rb +12 -0
  812. data/examples/showcase/config/lcp_ruby/presenters/author_show_zone.rb +12 -0
  813. data/examples/showcase/config/lcp_ruby/presenters/authors.rb +39 -0
  814. data/examples/showcase/config/lcp_ruby/presenters/batch_operation_items.yml +45 -0
  815. data/examples/showcase/config/lcp_ruby/presenters/batch_operations.yml +66 -0
  816. data/examples/showcase/config/lcp_ruby/presenters/categories.rb +50 -0
  817. data/examples/showcase/config/lcp_ruby/presenters/category_articles_zone.rb +20 -0
  818. data/examples/showcase/config/lcp_ruby/presenters/category_children_zone.rb +10 -0
  819. data/examples/showcase/config/lcp_ruby/presenters/comment_quick_add_dialog.rb +15 -0
  820. data/examples/showcase/config/lcp_ruby/presenters/custom_fields.rb +124 -0
  821. data/examples/showcase/config/lcp_ruby/presenters/dashboard_employees.rb +16 -0
  822. data/examples/showcase/config/lcp_ruby/presenters/delete_reason_dialog.rb +13 -0
  823. data/examples/showcase/config/lcp_ruby/presenters/departments.rb +55 -0
  824. data/examples/showcase/config/lcp_ruby/presenters/dept_add_employee_dialog.rb +19 -0
  825. data/examples/showcase/config/lcp_ruby/presenters/dept_children_zone.rb +10 -0
  826. data/examples/showcase/config/lcp_ruby/presenters/dept_detail_zone.rb +14 -0
  827. data/examples/showcase/config/lcp_ruby/presenters/dept_employees_zone.rb +16 -0
  828. data/examples/showcase/config/lcp_ruby/presenters/dept_list_selection_zone.rb +19 -0
  829. data/examples/showcase/config/lcp_ruby/presenters/employee_overview_index_zone.rb +36 -0
  830. data/examples/showcase/config/lcp_ruby/presenters/employee_quick_add_dialog.rb +14 -0
  831. data/examples/showcase/config/lcp_ruby/presenters/employee_show_zone.rb +20 -0
  832. data/examples/showcase/config/lcp_ruby/presenters/employee_transfer_form_zone.rb +19 -0
  833. data/examples/showcase/config/lcp_ruby/presenters/employees.rb +165 -0
  834. data/examples/showcase/config/lcp_ruby/presenters/employees_tiles.rb +33 -0
  835. data/examples/showcase/config/lcp_ruby/presenters/export_logs.yml +58 -0
  836. data/examples/showcase/config/lcp_ruby/presenters/export_profiles.yml +70 -0
  837. data/examples/showcase/config/lcp_ruby/presenters/extensibility_quick_edit_dialog.rb +13 -0
  838. data/examples/showcase/config/lcp_ruby/presenters/feature_kanban.rb +30 -0
  839. data/examples/showcase/config/lcp_ruby/presenters/features_card.rb +179 -0
  840. data/examples/showcase/config/lcp_ruby/presenters/features_hub.rb +44 -0
  841. data/examples/showcase/config/lcp_ruby/presenters/features_table.rb +37 -0
  842. data/examples/showcase/config/lcp_ruby/presenters/features_tiles.rb +48 -0
  843. data/examples/showcase/config/lcp_ruby/presenters/group_memberships.rb +54 -0
  844. data/examples/showcase/config/lcp_ruby/presenters/group_role_mappings.rb +48 -0
  845. data/examples/showcase/config/lcp_ruby/presenters/groups.rb +74 -0
  846. data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items.rb +99 -0
  847. data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_managed.rb +84 -0
  848. data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_report.rb +40 -0
  849. data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_wizard.rb +76 -0
  850. data/examples/showcase/config/lcp_ruby/presenters/import_profiles.rb +61 -0
  851. data/examples/showcase/config/lcp_ruby/presenters/import_rows.rb +39 -0
  852. data/examples/showcase/config/lcp_ruby/presenters/lcp_error_logs.yml +46 -0
  853. data/examples/showcase/config/lcp_ruby/presenters/my_api_tokens.rb +35 -0
  854. data/examples/showcase/config/lcp_ruby/presenters/my_api_tokens_create_dialog.rb +27 -0
  855. data/examples/showcase/config/lcp_ruby/presenters/my_employee_profile.rb +24 -0
  856. data/examples/showcase/config/lcp_ruby/presenters/my_settings.rb +50 -0
  857. data/examples/showcase/config/lcp_ruby/presenters/page_configs.rb +56 -0
  858. data/examples/showcase/config/lcp_ruby/presenters/permission_configs.rb +58 -0
  859. data/examples/showcase/config/lcp_ruby/presenters/pipeline_edit_zone.rb +11 -0
  860. data/examples/showcase/config/lcp_ruby/presenters/pipeline_stages.rb +51 -0
  861. data/examples/showcase/config/lcp_ruby/presenters/pipeline_stages_zone.rb +11 -0
  862. data/examples/showcase/config/lcp_ruby/presenters/pipelines.rb +40 -0
  863. data/examples/showcase/config/lcp_ruby/presenters/platform_profiles.rb +90 -0
  864. data/examples/showcase/config/lcp_ruby/presenters/projects.rb +58 -0
  865. data/examples/showcase/config/lcp_ruby/presenters/quick_note_dialog.rb +14 -0
  866. data/examples/showcase/config/lcp_ruby/presenters/roles.rb +60 -0
  867. data/examples/showcase/config/lcp_ruby/presenters/save_filter_dialog.rb +17 -0
  868. data/examples/showcase/config/lcp_ruby/presenters/saved_filters.rb +94 -0
  869. data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregate_items.rb +61 -0
  870. data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregates.rb +115 -0
  871. data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregates_tiles.rb +44 -0
  872. data/examples/showcase/config/lcp_ruby/presenters/showcase_amount_kanban.rb +31 -0
  873. data/examples/showcase/config/lcp_ruby/presenters/showcase_arrays.rb +140 -0
  874. data/examples/showcase/config/lcp_ruby/presenters/showcase_attachments.rb +66 -0
  875. data/examples/showcase/config/lcp_ruby/presenters/showcase_audit_logs.rb +46 -0
  876. data/examples/showcase/config/lcp_ruby/presenters/showcase_audited_records.rb +58 -0
  877. data/examples/showcase/config/lcp_ruby/presenters/showcase_batch_tasks.rb +97 -0
  878. data/examples/showcase/config/lcp_ruby/presenters/showcase_batch_tasks_archive.rb +52 -0
  879. data/examples/showcase/config/lcp_ruby/presenters/showcase_business_units.rb +43 -0
  880. data/examples/showcase/config/lcp_ruby/presenters/showcase_conditions.rb +195 -0
  881. data/examples/showcase/config/lcp_ruby/presenters/showcase_contacts.rb +82 -0
  882. data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_render_with.rb +50 -0
  883. data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_sections.rb +88 -0
  884. data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_zones_main.rb +75 -0
  885. data/examples/showcase/config/lcp_ruby/presenters/showcase_divisions.rb +53 -0
  886. data/examples/showcase/config/lcp_ruby/presenters/showcase_extensibility.rb +48 -0
  887. data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_card.rb +34 -0
  888. data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_table.rb +128 -0
  889. data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_tiles.rb +42 -0
  890. data/examples/showcase/config/lcp_ruby/presenters/showcase_form_action_dialog.rb +27 -0
  891. data/examples/showcase/config/lcp_ruby/presenters/showcase_form_actions.rb +132 -0
  892. data/examples/showcase/config/lcp_ruby/presenters/showcase_form_actions_overflow.rb +76 -0
  893. data/examples/showcase/config/lcp_ruby/presenters/showcase_forms.rb +110 -0
  894. data/examples/showcase/config/lcp_ruby/presenters/showcase_grades.rb +38 -0
  895. data/examples/showcase/config/lcp_ruby/presenters/showcase_hr_employees.rb +84 -0
  896. data/examples/showcase/config/lcp_ruby/presenters/showcase_item_classes.rb +120 -0
  897. data/examples/showcase/config/lcp_ruby/presenters/showcase_job_executions.rb +150 -0
  898. data/examples/showcase/config/lcp_ruby/presenters/showcase_memos.rb +96 -0
  899. data/examples/showcase/config/lcp_ruby/presenters/showcase_models.rb +112 -0
  900. data/examples/showcase/config/lcp_ruby/presenters/showcase_organizations.rb +106 -0
  901. data/examples/showcase/config/lcp_ruby/presenters/showcase_people.rb +97 -0
  902. data/examples/showcase/config/lcp_ruby/presenters/showcase_permissions.rb +84 -0
  903. data/examples/showcase/config/lcp_ruby/presenters/showcase_positioning.rb +61 -0
  904. data/examples/showcase/config/lcp_ruby/presenters/showcase_recipes.rb +105 -0
  905. data/examples/showcase/config/lcp_ruby/presenters/showcase_recipes_raw.rb +32 -0
  906. data/examples/showcase/config/lcp_ruby/presenters/showcase_reports.rb +109 -0
  907. data/examples/showcase/config/lcp_ruby/presenters/showcase_school_classes.rb +34 -0
  908. data/examples/showcase/config/lcp_ruby/presenters/showcase_searches.rb +226 -0
  909. data/examples/showcase/config/lcp_ruby/presenters/showcase_sequences.rb +67 -0
  910. data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete.rb +88 -0
  911. data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete_archive.rb +52 -0
  912. data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete_items.rb +47 -0
  913. data/examples/showcase/config/lcp_ruby/presenters/showcase_students.rb +33 -0
  914. data/examples/showcase/config/lcp_ruby/presenters/showcase_type_defaults.rb +92 -0
  915. data/examples/showcase/config/lcp_ruby/presenters/showcase_userstamps.rb +76 -0
  916. data/examples/showcase/config/lcp_ruby/presenters/showcase_virtual_fields.rb +104 -0
  917. data/examples/showcase/config/lcp_ruby/presenters/showcase_workflow_admin.rb +24 -0
  918. data/examples/showcase/config/lcp_ruby/presenters/showcase_workflow_kanban.rb +36 -0
  919. data/examples/showcase/config/lcp_ruby/presenters/showcase_workflows.rb +103 -0
  920. data/examples/showcase/config/lcp_ruby/presenters/tags.rb +35 -0
  921. data/examples/showcase/config/lcp_ruby/presenters/users.rb +61 -0
  922. data/examples/showcase/config/lcp_ruby/presenters/weather_stations.rb +60 -0
  923. data/examples/showcase/config/lcp_ruby/presenters/workflow_audit_logs.rb +76 -0
  924. data/examples/showcase/config/lcp_ruby/presenters/workflow_request_audit_zone.rb +28 -0
  925. data/examples/showcase/config/lcp_ruby/theme.yml +2 -0
  926. data/examples/showcase/config/lcp_ruby/types/currency.yml +15 -0
  927. data/examples/showcase/config/lcp_ruby/types/percentage.yml +16 -0
  928. data/examples/showcase/config/lcp_ruby/types/rating.yml +20 -0
  929. data/examples/showcase/config/lcp_ruby/views/announcements.yml +7 -0
  930. data/examples/showcase/config/lcp_ruby/views/approval_requests.yml +7 -0
  931. data/examples/showcase/config/lcp_ruby/views/approval_steps.yml +7 -0
  932. data/examples/showcase/config/lcp_ruby/views/approval_tasks.yml +7 -0
  933. data/examples/showcase/config/lcp_ruby/views/articles.yml +12 -0
  934. data/examples/showcase/config/lcp_ruby/views/authors.yml +7 -0
  935. data/examples/showcase/config/lcp_ruby/views/batch_operation_items.yml +6 -0
  936. data/examples/showcase/config/lcp_ruby/views/batch_operations.yml +10 -0
  937. data/examples/showcase/config/lcp_ruby/views/categories.yml +9 -0
  938. data/examples/showcase/config/lcp_ruby/views/custom_fields.rb +8 -0
  939. data/examples/showcase/config/lcp_ruby/views/dashboard.yml +10 -0
  940. data/examples/showcase/config/lcp_ruby/views/department_explorer.yml +7 -0
  941. data/examples/showcase/config/lcp_ruby/views/departments.yml +9 -0
  942. data/examples/showcase/config/lcp_ruby/views/employee_overview.yml +7 -0
  943. data/examples/showcase/config/lcp_ruby/views/employees.yml +12 -0
  944. data/examples/showcase/config/lcp_ruby/views/export_logs.yml +7 -0
  945. data/examples/showcase/config/lcp_ruby/views/export_profiles.yml +7 -0
  946. data/examples/showcase/config/lcp_ruby/views/features.yml +19 -0
  947. data/examples/showcase/config/lcp_ruby/views/group_memberships.yml +7 -0
  948. data/examples/showcase/config/lcp_ruby/views/group_role_mappings.yml +7 -0
  949. data/examples/showcase/config/lcp_ruby/views/groups.yml +7 -0
  950. data/examples/showcase/config/lcp_ruby/views/host_inventory_items.yml +16 -0
  951. data/examples/showcase/config/lcp_ruby/views/hr_turnover_dashboard.yml +7 -0
  952. data/examples/showcase/config/lcp_ruby/views/import_profiles.yml +7 -0
  953. data/examples/showcase/config/lcp_ruby/views/import_rows.yml +7 -0
  954. data/examples/showcase/config/lcp_ruby/views/lcp_error_logs.yml +10 -0
  955. data/examples/showcase/config/lcp_ruby/views/monitoring.yml +7 -0
  956. data/examples/showcase/config/lcp_ruby/views/my_api_tokens.rb +9 -0
  957. data/examples/showcase/config/lcp_ruby/views/page_configs.yml +11 -0
  958. data/examples/showcase/config/lcp_ruby/views/permission_configs.yml +11 -0
  959. data/examples/showcase/config/lcp_ruby/views/pipeline_stages.yml +7 -0
  960. data/examples/showcase/config/lcp_ruby/views/pipelines.yml +7 -0
  961. data/examples/showcase/config/lcp_ruby/views/platform_profiles.yml +7 -0
  962. data/examples/showcase/config/lcp_ruby/views/projects.yml +9 -0
  963. data/examples/showcase/config/lcp_ruby/views/roles.yml +7 -0
  964. data/examples/showcase/config/lcp_ruby/views/saved_filters.yml +7 -0
  965. data/examples/showcase/config/lcp_ruby/views/showcase_aggregate_items.yml +7 -0
  966. data/examples/showcase/config/lcp_ruby/views/showcase_aggregates.yml +10 -0
  967. data/examples/showcase/config/lcp_ruby/views/showcase_arrays.yml +7 -0
  968. data/examples/showcase/config/lcp_ruby/views/showcase_attachments.yml +7 -0
  969. data/examples/showcase/config/lcp_ruby/views/showcase_audit_logs.yml +11 -0
  970. data/examples/showcase/config/lcp_ruby/views/showcase_audited_records.yml +10 -0
  971. data/examples/showcase/config/lcp_ruby/views/showcase_batch_tasks.yml +10 -0
  972. data/examples/showcase/config/lcp_ruby/views/showcase_business_units.yml +7 -0
  973. data/examples/showcase/config/lcp_ruby/views/showcase_conditions.yml +7 -0
  974. data/examples/showcase/config/lcp_ruby/views/showcase_contacts.yml +7 -0
  975. data/examples/showcase/config/lcp_ruby/views/showcase_custom_render_with.yml +7 -0
  976. data/examples/showcase/config/lcp_ruby/views/showcase_custom_sections.yml +7 -0
  977. data/examples/showcase/config/lcp_ruby/views/showcase_custom_zones.yml +7 -0
  978. data/examples/showcase/config/lcp_ruby/views/showcase_divisions.yml +9 -0
  979. data/examples/showcase/config/lcp_ruby/views/showcase_extensibility.yml +7 -0
  980. data/examples/showcase/config/lcp_ruby/views/showcase_fields.yml +13 -0
  981. data/examples/showcase/config/lcp_ruby/views/showcase_form_actions.yml +10 -0
  982. data/examples/showcase/config/lcp_ruby/views/showcase_forms.yml +7 -0
  983. data/examples/showcase/config/lcp_ruby/views/showcase_grades.yml +9 -0
  984. data/examples/showcase/config/lcp_ruby/views/showcase_hr_employees.yml +9 -0
  985. data/examples/showcase/config/lcp_ruby/views/showcase_item_classes.yml +7 -0
  986. data/examples/showcase/config/lcp_ruby/views/showcase_job_executions.yml +9 -0
  987. data/examples/showcase/config/lcp_ruby/views/showcase_memos.yml +7 -0
  988. data/examples/showcase/config/lcp_ruby/views/showcase_models.yml +7 -0
  989. data/examples/showcase/config/lcp_ruby/views/showcase_organizations.yml +7 -0
  990. data/examples/showcase/config/lcp_ruby/views/showcase_people.yml +7 -0
  991. data/examples/showcase/config/lcp_ruby/views/showcase_permissions.yml +7 -0
  992. data/examples/showcase/config/lcp_ruby/views/showcase_positioning.yml +7 -0
  993. data/examples/showcase/config/lcp_ruby/views/showcase_recipes.yml +10 -0
  994. data/examples/showcase/config/lcp_ruby/views/showcase_reports.yml +7 -0
  995. data/examples/showcase/config/lcp_ruby/views/showcase_school_classes.yml +7 -0
  996. data/examples/showcase/config/lcp_ruby/views/showcase_searches.yml +7 -0
  997. data/examples/showcase/config/lcp_ruby/views/showcase_sequences.yml +7 -0
  998. data/examples/showcase/config/lcp_ruby/views/showcase_soft_delete.yml +10 -0
  999. data/examples/showcase/config/lcp_ruby/views/showcase_soft_delete_items.yml +8 -0
  1000. data/examples/showcase/config/lcp_ruby/views/showcase_students.yml +9 -0
  1001. data/examples/showcase/config/lcp_ruby/views/showcase_userstamps.yml +7 -0
  1002. data/examples/showcase/config/lcp_ruby/views/showcase_virtual_fields.yml +7 -0
  1003. data/examples/showcase/config/lcp_ruby/views/showcase_workflows.yml +16 -0
  1004. data/examples/showcase/config/lcp_ruby/views/tags.yml +7 -0
  1005. data/examples/showcase/config/lcp_ruby/views/users.yml +7 -0
  1006. data/examples/showcase/config/lcp_ruby/views/weather_stations.yml +7 -0
  1007. data/examples/showcase/config/lcp_ruby/views/workflow_audit_logs.yml +9 -0
  1008. data/examples/showcase/config/lcp_ruby/workflows/showcase_form_action.rb +48 -0
  1009. data/examples/showcase/config/lcp_ruby/workflows/showcase_workflow.rb +199 -0
  1010. data/examples/showcase/config/locales/cs.yml +2818 -0
  1011. data/examples/showcase/config/locales/en.yml +67 -0
  1012. data/examples/showcase/config/locales/lcp_ruby/api_tokens.cs.yml +46 -0
  1013. data/examples/showcase/config/locales/lcp_ruby/api_tokens.en.yml +49 -0
  1014. data/examples/showcase/config/routes.rb +21 -0
  1015. data/examples/showcase/config/storage.yml +3 -0
  1016. data/examples/showcase/config.ru +2 -0
  1017. data/examples/showcase/db/migrate/20260219124321_create_active_storage_tables.active_storage.rb +57 -0
  1018. data/examples/showcase/db/migrate/20260220072723_create_lcp_ruby_users.rb +42 -0
  1019. data/examples/showcase/db/migrate/20260406120000_create_host_inventory_items.rb +32 -0
  1020. data/examples/showcase/db/migrate/20260428134542_add_oidc_columns_to_lcp_ruby_users.rb +13 -0
  1021. data/examples/showcase/db/migrate/20260502120000_create_platform_profiles.rb +19 -0
  1022. data/examples/showcase/db/schema.rb +1222 -0
  1023. data/examples/showcase/db/seeds.rb +3085 -0
  1024. data/examples/showcase/erd.md +567 -0
  1025. data/examples/showcase/test/fixtures/import_articles.csv +4 -0
  1026. data/examples/showcase/test/fixtures/import_employees.csv +4 -0
  1027. data/examples/todo/Gemfile +8 -0
  1028. data/examples/todo/Gemfile.lock +415 -0
  1029. data/examples/todo/Rakefile +2 -0
  1030. data/examples/todo/app/assets/config/manifest.js +1 -0
  1031. data/examples/todo/app/controllers/application_controller.rb +6 -0
  1032. data/examples/todo/app/lcp_services/defaults/one_week_from_now.rb +11 -0
  1033. data/examples/todo/bin/rails +4 -0
  1034. data/examples/todo/bin/rake +4 -0
  1035. data/examples/todo/config/application.rb +31 -0
  1036. data/examples/todo/config/boot.rb +2 -0
  1037. data/examples/todo/config/database.yml +12 -0
  1038. data/examples/todo/config/environment.rb +2 -0
  1039. data/examples/todo/config/lcp_ruby/models/todo_item.yml +67 -0
  1040. data/examples/todo/config/lcp_ruby/models/todo_list.yml +49 -0
  1041. data/examples/todo/config/lcp_ruby/permissions/default.yml +10 -0
  1042. data/examples/todo/config/lcp_ruby/permissions/todo_item.yml +21 -0
  1043. data/examples/todo/config/lcp_ruby/presenters/todo_item.yml +75 -0
  1044. data/examples/todo/config/lcp_ruby/presenters/todo_list.yml +68 -0
  1045. data/examples/todo/config/lcp_ruby/views/todo_items.yml +11 -0
  1046. data/examples/todo/config/lcp_ruby/views/todo_lists.yml +9 -0
  1047. data/examples/todo/config/routes.rb +4 -0
  1048. data/examples/todo/config/storage.yml +3 -0
  1049. data/examples/todo/config.ru +2 -0
  1050. data/examples/todo/db/migrate/20260219103416_create_active_storage_tables.active_storage.rb +57 -0
  1051. data/examples/todo/db/schema.rb +63 -0
  1052. data/examples/todo/db/seeds.rb +24 -0
  1053. data/examples/todo/erd.md +21 -0
  1054. data/exe/lcp +33 -0
  1055. data/lib/generators/lcp_ruby/agent_setup_generator.rb +102 -0
  1056. data/lib/generators/lcp_ruby/api_tokens_generator.rb +102 -0
  1057. data/lib/generators/lcp_ruby/auditing_generator.rb +54 -0
  1058. data/lib/generators/lcp_ruby/background_jobs_generator.rb +61 -0
  1059. data/lib/generators/lcp_ruby/batch_operations_generator.rb +62 -0
  1060. data/lib/generators/lcp_ruby/claude_skills_generator.rb +47 -0
  1061. data/lib/generators/lcp_ruby/custom_fields_generator.rb +54 -0
  1062. data/lib/generators/lcp_ruby/dsl_to_yaml.rb +72 -0
  1063. data/lib/generators/lcp_ruby/entity/color_palette.rb +22 -0
  1064. data/lib/generators/lcp_ruby/entity/field_descriptor.rb +24 -0
  1065. data/lib/generators/lcp_ruby/entity/field_token_parser.rb +101 -0
  1066. data/lib/generators/lcp_ruby/entity/role_discovery.rb +45 -0
  1067. data/lib/generators/lcp_ruby/entity_generator.rb +1104 -0
  1068. data/lib/generators/lcp_ruby/export_generator.rb +71 -0
  1069. data/lib/generators/lcp_ruby/format_support.rb +56 -0
  1070. data/lib/generators/lcp_ruby/gapfree_sequences_generator.rb +64 -0
  1071. data/lib/generators/lcp_ruby/groups_generator.rb +94 -0
  1072. data/lib/generators/lcp_ruby/host_controller_generator.rb +202 -0
  1073. data/lib/generators/lcp_ruby/import_generator.rb +96 -0
  1074. data/lib/generators/lcp_ruby/install_auth_generator.rb +432 -0
  1075. data/lib/generators/lcp_ruby/install_generator.rb +319 -0
  1076. data/lib/generators/lcp_ruby/monitoring_generator.rb +58 -0
  1077. data/lib/generators/lcp_ruby/oidc_role_mappings_generator.rb +60 -0
  1078. data/lib/generators/lcp_ruby/pages_generator.rb +66 -0
  1079. data/lib/generators/lcp_ruby/permission_source_generator.rb +66 -0
  1080. data/lib/generators/lcp_ruby/role_model_generator.rb +73 -0
  1081. data/lib/generators/lcp_ruby/saved_filters_generator.rb +62 -0
  1082. data/lib/generators/lcp_ruby/templates/add_oidc_columns_to_lcp_ruby_users.rb.erb +13 -0
  1083. data/lib/generators/lcp_ruby/templates/agent_setup/agents_md.md +3 -0
  1084. data/lib/generators/lcp_ruby/templates/agent_setup/claude_md.md +12 -0
  1085. data/lib/generators/lcp_ruby/templates/api_tokens/create_dialog.rb +31 -0
  1086. data/lib/generators/lcp_ruby/templates/api_tokens/locales.en.yml +43 -0
  1087. data/lib/generators/lcp_ruby/templates/api_tokens/model.rb +23 -0
  1088. data/lib/generators/lcp_ruby/templates/api_tokens/permissions.yml +30 -0
  1089. data/lib/generators/lcp_ruby/templates/api_tokens/presenter.rb +38 -0
  1090. data/lib/generators/lcp_ruby/templates/api_tokens/view_group.rb +13 -0
  1091. data/lib/generators/lcp_ruby/templates/auditing/model.rb +34 -0
  1092. data/lib/generators/lcp_ruby/templates/auditing/permissions.yml +19 -0
  1093. data/lib/generators/lcp_ruby/templates/auditing/presenter.rb +41 -0
  1094. data/lib/generators/lcp_ruby/templates/auditing/view_group.rb +10 -0
  1095. data/lib/generators/lcp_ruby/templates/background_jobs/model.rb +59 -0
  1096. data/lib/generators/lcp_ruby/templates/background_jobs/permissions.yml +22 -0
  1097. data/lib/generators/lcp_ruby/templates/background_jobs/presenter.rb +82 -0
  1098. data/lib/generators/lcp_ruby/templates/background_jobs/view_group.rb +9 -0
  1099. data/lib/generators/lcp_ruby/templates/batch_operations/item_model.rb +28 -0
  1100. data/lib/generators/lcp_ruby/templates/batch_operations/item_presenter.rb +43 -0
  1101. data/lib/generators/lcp_ruby/templates/batch_operations/model.rb +42 -0
  1102. data/lib/generators/lcp_ruby/templates/batch_operations/permissions.yml +44 -0
  1103. data/lib/generators/lcp_ruby/templates/batch_operations/presenter.rb +61 -0
  1104. data/lib/generators/lcp_ruby/templates/batch_operations/view_group.rb +9 -0
  1105. data/lib/generators/lcp_ruby/templates/create_lcp_ruby_users.rb.erb +50 -0
  1106. data/lib/generators/lcp_ruby/templates/custom_fields/model.rb +60 -0
  1107. data/lib/generators/lcp_ruby/templates/custom_fields/permissions.yml +19 -0
  1108. data/lib/generators/lcp_ruby/templates/custom_fields/presenter.rb +128 -0
  1109. data/lib/generators/lcp_ruby/templates/custom_fields/view_group.rb +9 -0
  1110. data/lib/generators/lcp_ruby/templates/entity/model.rb +42 -0
  1111. data/lib/generators/lcp_ruby/templates/entity/permissions.yml +20 -0
  1112. data/lib/generators/lcp_ruby/templates/entity/presenter.rb +55 -0
  1113. data/lib/generators/lcp_ruby/templates/entity/view_group.rb +8 -0
  1114. data/lib/generators/lcp_ruby/templates/export/export_log_model.rb +30 -0
  1115. data/lib/generators/lcp_ruby/templates/export/export_log_permissions.yml +24 -0
  1116. data/lib/generators/lcp_ruby/templates/export/export_logs_presenter.rb +51 -0
  1117. data/lib/generators/lcp_ruby/templates/export/export_profile_model.rb +28 -0
  1118. data/lib/generators/lcp_ruby/templates/export/export_profile_permissions.yml +26 -0
  1119. data/lib/generators/lcp_ruby/templates/export/export_profiles_presenter.rb +59 -0
  1120. data/lib/generators/lcp_ruby/templates/gapfree_sequences/model.rb +18 -0
  1121. data/lib/generators/lcp_ruby/templates/gapfree_sequences/permissions.yml +19 -0
  1122. data/lib/generators/lcp_ruby/templates/gapfree_sequences/presenter.rb +51 -0
  1123. data/lib/generators/lcp_ruby/templates/gapfree_sequences/view_group.rb +9 -0
  1124. data/lib/generators/lcp_ruby/templates/groups/group_membership_model.rb +17 -0
  1125. data/lib/generators/lcp_ruby/templates/groups/group_model.rb +28 -0
  1126. data/lib/generators/lcp_ruby/templates/groups/group_permissions.yml +19 -0
  1127. data/lib/generators/lcp_ruby/templates/groups/group_presenter.rb +53 -0
  1128. data/lib/generators/lcp_ruby/templates/groups/group_role_mapping_model.rb +15 -0
  1129. data/lib/generators/lcp_ruby/templates/groups/group_view_group.rb +9 -0
  1130. data/lib/generators/lcp_ruby/templates/host_controller/controller.rb.erb +131 -0
  1131. data/lib/generators/lcp_ruby/templates/import/data_import_job.yml +7 -0
  1132. data/lib/generators/lcp_ruby/templates/import/import_profile_model.rb +30 -0
  1133. data/lib/generators/lcp_ruby/templates/import/import_profile_permissions.yml +29 -0
  1134. data/lib/generators/lcp_ruby/templates/import/import_profiles_presenter.rb +57 -0
  1135. data/lib/generators/lcp_ruby/templates/import/import_row_model.rb +32 -0
  1136. data/lib/generators/lcp_ruby/templates/import/import_row_permissions.yml +11 -0
  1137. data/lib/generators/lcp_ruby/templates/import/import_rows_presenter.rb +35 -0
  1138. data/lib/generators/lcp_ruby/templates/install/default_permissions.yml +26 -0
  1139. data/lib/generators/lcp_ruby/templates/install/menu.yml.tt +71 -0
  1140. data/lib/generators/lcp_ruby/templates/install/model.rb +20 -0
  1141. data/lib/generators/lcp_ruby/templates/install/permissions.yml +25 -0
  1142. data/lib/generators/lcp_ruby/templates/install/presenter.rb +44 -0
  1143. data/lib/generators/lcp_ruby/templates/install/view_group.rb +10 -0
  1144. data/lib/generators/lcp_ruby/templates/install_auth/oidc/entra.yml.erb +46 -0
  1145. data/lib/generators/lcp_ruby/templates/install_auth/oidc/generic.yml.erb +55 -0
  1146. data/lib/generators/lcp_ruby/templates/install_auth/oidc/google.yml.erb +42 -0
  1147. data/lib/generators/lcp_ruby/templates/install_auth/oidc/keycloak.yml.erb +45 -0
  1148. data/lib/generators/lcp_ruby/templates/install_auth/oidc/okta.yml.erb +45 -0
  1149. data/lib/generators/lcp_ruby/templates/install_auth/user.rb +36 -0
  1150. data/lib/generators/lcp_ruby/templates/monitoring/model.rb +34 -0
  1151. data/lib/generators/lcp_ruby/templates/monitoring/model_extension.rb +12 -0
  1152. data/lib/generators/lcp_ruby/templates/monitoring/page.yml +49 -0
  1153. data/lib/generators/lcp_ruby/templates/monitoring/permissions.yml +8 -0
  1154. data/lib/generators/lcp_ruby/templates/monitoring/presenter.rb +44 -0
  1155. data/lib/generators/lcp_ruby/templates/oidc_role_mappings/locales.en.yml +15 -0
  1156. data/lib/generators/lcp_ruby/templates/oidc_role_mappings/model.rb +32 -0
  1157. data/lib/generators/lcp_ruby/templates/oidc_role_mappings/permissions.yml +21 -0
  1158. data/lib/generators/lcp_ruby/templates/oidc_role_mappings/presenter.rb +41 -0
  1159. data/lib/generators/lcp_ruby/templates/pages/model.rb +19 -0
  1160. data/lib/generators/lcp_ruby/templates/pages/permissions.yml +19 -0
  1161. data/lib/generators/lcp_ruby/templates/pages/presenter.rb +51 -0
  1162. data/lib/generators/lcp_ruby/templates/pages/view_group.rb +10 -0
  1163. data/lib/generators/lcp_ruby/templates/permission_source/model.rb +21 -0
  1164. data/lib/generators/lcp_ruby/templates/permission_source/permissions.yml +19 -0
  1165. data/lib/generators/lcp_ruby/templates/permission_source/presenter.rb +51 -0
  1166. data/lib/generators/lcp_ruby/templates/permission_source/view_group.rb +10 -0
  1167. data/lib/generators/lcp_ruby/templates/role_model/model.rb +24 -0
  1168. data/lib/generators/lcp_ruby/templates/role_model/permissions.yml +19 -0
  1169. data/lib/generators/lcp_ruby/templates/role_model/presenter.rb +62 -0
  1170. data/lib/generators/lcp_ruby/templates/role_model/view_group.rb +10 -0
  1171. data/lib/generators/lcp_ruby/templates/saved_filters/model.rb +51 -0
  1172. data/lib/generators/lcp_ruby/templates/saved_filters/permissions.yml +44 -0
  1173. data/lib/generators/lcp_ruby/templates/saved_filters/presenter.rb +96 -0
  1174. data/lib/generators/lcp_ruby/templates/saved_filters/save_dialog_presenter.rb +19 -0
  1175. data/lib/generators/lcp_ruby/templates/workflow_approvals/request_model.rb +50 -0
  1176. data/lib/generators/lcp_ruby/templates/workflow_approvals/request_permissions.yml +10 -0
  1177. data/lib/generators/lcp_ruby/templates/workflow_approvals/request_presenter.rb +44 -0
  1178. data/lib/generators/lcp_ruby/templates/workflow_approvals/request_view_group.rb +10 -0
  1179. data/lib/generators/lcp_ruby/templates/workflow_approvals/step_model.rb +36 -0
  1180. data/lib/generators/lcp_ruby/templates/workflow_approvals/step_permissions.yml +10 -0
  1181. data/lib/generators/lcp_ruby/templates/workflow_approvals/task_model.rb +34 -0
  1182. data/lib/generators/lcp_ruby/templates/workflow_approvals/task_permissions.yml +10 -0
  1183. data/lib/generators/lcp_ruby/templates/workflow_approvals/task_presenter.rb +39 -0
  1184. data/lib/generators/lcp_ruby/templates/workflow_approvals/task_view_group.rb +10 -0
  1185. data/lib/generators/lcp_ruby/templates/workflow_audit_log/model.rb +48 -0
  1186. data/lib/generators/lcp_ruby/templates/workflow_audit_log/permissions.yml +10 -0
  1187. data/lib/generators/lcp_ruby/templates/workflow_audit_log/presenter.rb +44 -0
  1188. data/lib/generators/lcp_ruby/templates/workflow_audit_log/view_group.rb +10 -0
  1189. data/lib/generators/lcp_ruby/templates/workflow_definition/model.rb +43 -0
  1190. data/lib/generators/lcp_ruby/templates/workflow_definition/permissions.yml +19 -0
  1191. data/lib/generators/lcp_ruby/templates/workflow_definition/presenter.rb +70 -0
  1192. data/lib/generators/lcp_ruby/templates/workflow_definition/view_group.rb +10 -0
  1193. data/lib/generators/lcp_ruby/workflow_approvals_generator.rb +93 -0
  1194. data/lib/generators/lcp_ruby/workflow_audit_log_generator.rb +54 -0
  1195. data/lib/generators/lcp_ruby/workflow_definition_generator.rb +77 -0
  1196. data/lib/lcp.rb +6 -0
  1197. data/lib/lcp_ruby/actions/action_executor.rb +66 -0
  1198. data/lib/lcp_ruby/actions/action_registry.rb +48 -0
  1199. data/lib/lcp_ruby/actions/api_tokens/revoke.rb +13 -0
  1200. data/lib/lcp_ruby/actions/base_action.rb +79 -0
  1201. data/lib/lcp_ruby/actions/form_action_pipeline.rb +138 -0
  1202. data/lib/lcp_ruby/aggregates/query_builder.rb +6 -0
  1203. data/lib/lcp_ruby/api_tokens/model_extension.rb +41 -0
  1204. data/lib/lcp_ruby/api_tokens/resolver_registry.rb +53 -0
  1205. data/lib/lcp_ruby/api_tokens/token_generator.rb +27 -0
  1206. data/lib/lcp_ruby/api_tokens/verifier.rb +38 -0
  1207. data/lib/lcp_ruby/app_template.rb +181 -0
  1208. data/lib/lcp_ruby/array_query.rb +120 -0
  1209. data/lib/lcp_ruby/asset_copier.rb +62 -0
  1210. data/lib/lcp_ruby/association_fk_type.rb +191 -0
  1211. data/lib/lcp_ruby/association_join_column.rb +28 -0
  1212. data/lib/lcp_ruby/association_options_builder.rb +231 -0
  1213. data/lib/lcp_ruby/auditing/audit_writer.rb +258 -0
  1214. data/lib/lcp_ruby/auditing/contract_validator.rb +95 -0
  1215. data/lib/lcp_ruby/auditing/registry.rb +29 -0
  1216. data/lib/lcp_ruby/auditing/setup.rb +49 -0
  1217. data/lib/lcp_ruby/authentication/audit_subscriber.rb +51 -0
  1218. data/lib/lcp_ruby/authentication/bearer_jwt_verifier.rb +139 -0
  1219. data/lib/lcp_ruby/authentication/devise_setup.rb +47 -0
  1220. data/lib/lcp_ruby/authentication/errors.rb +27 -0
  1221. data/lib/lcp_ruby/authentication/http_fetcher.rb +36 -0
  1222. data/lib/lcp_ruby/authentication/jwks_cache.rb +91 -0
  1223. data/lib/lcp_ruby/authentication/oidc_bearer_resolver.rb +84 -0
  1224. data/lib/lcp_ruby/authentication/omniauth_builder.rb +147 -0
  1225. data/lib/lcp_ruby/authentication/provider.rb +108 -0
  1226. data/lib/lcp_ruby/authentication/provider_registry.rb +227 -0
  1227. data/lib/lcp_ruby/authentication/role_mapper.rb +94 -0
  1228. data/lib/lcp_ruby/authentication/test_support.rb +257 -0
  1229. data/lib/lcp_ruby/authentication/user_resolver.rb +169 -0
  1230. data/lib/lcp_ruby/authentication.rb +40 -0
  1231. data/lib/lcp_ruby/authorization/association_lookup.rb +56 -0
  1232. data/lib/lcp_ruby/authorization/authorization_error.rb +12 -0
  1233. data/lib/lcp_ruby/authorization/cache.rb +89 -0
  1234. data/lib/lcp_ruby/authorization/codes.rb +17 -0
  1235. data/lib/lcp_ruby/authorization/impersonated_user.rb +29 -0
  1236. data/lib/lcp_ruby/authorization/includes_hint.rb +110 -0
  1237. data/lib/lcp_ruby/authorization/inherited_parent_validator.rb +142 -0
  1238. data/lib/lcp_ruby/authorization/invariant_check/configuration.rb +132 -0
  1239. data/lib/lcp_ruby/authorization/invariant_error.rb +15 -0
  1240. data/lib/lcp_ruby/authorization/misconfigured_page_error.rb +30 -0
  1241. data/lib/lcp_ruby/authorization/page_gate.rb +57 -0
  1242. data/lib/lcp_ruby/authorization/permission_evaluator.rb +343 -0
  1243. data/lib/lcp_ruby/authorization/policy_factory.rb +91 -0
  1244. data/lib/lcp_ruby/authorization/runtime_invariant_validator.rb +421 -0
  1245. data/lib/lcp_ruby/authorization/scope_builder.rb +227 -0
  1246. data/lib/lcp_ruby/authorization/scope_resolver.rb +28 -0
  1247. data/lib/lcp_ruby/authorized_controller.rb +44 -0
  1248. data/lib/lcp_ruby/background_jobs/base_handler.rb +113 -0
  1249. data/lib/lcp_ruby/background_jobs/change_handler.rb +17 -0
  1250. data/lib/lcp_ruby/background_jobs/contract.rb +16 -0
  1251. data/lib/lcp_ruby/background_jobs/contract_validator.rb +112 -0
  1252. data/lib/lcp_ruby/background_jobs/declarative/base_action.rb +11 -0
  1253. data/lib/lcp_ruby/background_jobs/declarative/call_webhook_action.rb +174 -0
  1254. data/lib/lcp_ruby/background_jobs/declarative/fire_event_action.rb +24 -0
  1255. data/lib/lcp_ruby/background_jobs/declarative/registry.rb +34 -0
  1256. data/lib/lcp_ruby/background_jobs/declarative/run_scope_action.rb +98 -0
  1257. data/lib/lcp_ruby/background_jobs/declarative/send_notification_action.rb +13 -0
  1258. data/lib/lcp_ruby/background_jobs/definition.rb +134 -0
  1259. data/lib/lcp_ruby/background_jobs/enqueue.rb +83 -0
  1260. data/lib/lcp_ruby/background_jobs/errors.rb +9 -0
  1261. data/lib/lcp_ruby/background_jobs/executor_job.rb +111 -0
  1262. data/lib/lcp_ruby/background_jobs/handler_factory.rb +46 -0
  1263. data/lib/lcp_ruby/background_jobs/host_source.rb +33 -0
  1264. data/lib/lcp_ruby/background_jobs/model_source.rb +93 -0
  1265. data/lib/lcp_ruby/background_jobs/registry.rb +81 -0
  1266. data/lib/lcp_ruby/background_jobs/resolver.rb +29 -0
  1267. data/lib/lcp_ruby/background_jobs/schedule_adapter.rb +14 -0
  1268. data/lib/lcp_ruby/background_jobs/setup.rb +145 -0
  1269. data/lib/lcp_ruby/background_jobs/static_source.rb +19 -0
  1270. data/lib/lcp_ruby/background_jobs/steps_executor.rb +52 -0
  1271. data/lib/lcp_ruby/background_jobs/triggers/event_trigger.rb +97 -0
  1272. data/lib/lcp_ruby/background_jobs/triggers/trigger_installer.rb +20 -0
  1273. data/lib/lcp_ruby/background_jobs/unique_key_builder.rb +31 -0
  1274. data/lib/lcp_ruby/batch_actions/base_service.rb +70 -0
  1275. data/lib/lcp_ruby/batch_actions/batch_action_handler.rb +200 -0
  1276. data/lib/lcp_ruby/batch_actions/custom_action_dispatcher.rb +133 -0
  1277. data/lib/lcp_ruby/batch_actions/destroy_service.rb +37 -0
  1278. data/lib/lcp_ruby/batch_actions/permanently_destroy_service.rb +33 -0
  1279. data/lib/lcp_ruby/batch_actions/restore_service.rb +33 -0
  1280. data/lib/lcp_ruby/batch_actions.rb +5 -0
  1281. data/lib/lcp_ruby/bulk_updater.rb +25 -0
  1282. data/lib/lcp_ruby/cli/docs_command.rb +29 -0
  1283. data/lib/lcp_ruby/cli/examples_command.rb +29 -0
  1284. data/lib/lcp_ruby/cli/new_command.rb +509 -0
  1285. data/lib/lcp_ruby/cli/run_command.rb +155 -0
  1286. data/lib/lcp_ruby/cli/skills_command.rb +54 -0
  1287. data/lib/lcp_ruby/cli.rb +74 -0
  1288. data/lib/lcp_ruby/condition_evaluator.rb +366 -0
  1289. data/lib/lcp_ruby/condition_service_registry.rb +58 -0
  1290. data/lib/lcp_ruby/condition_services/current_user_role.rb +28 -0
  1291. data/lib/lcp_ruby/condition_services/feature_flag.rb +63 -0
  1292. data/lib/lcp_ruby/condition_services/impersonating.rb +24 -0
  1293. data/lib/lcp_ruby/conditions/validator.rb +35 -0
  1294. data/lib/lcp_ruby/configuration.rb +431 -0
  1295. data/lib/lcp_ruby/controller/authentication.rb +118 -0
  1296. data/lib/lcp_ruby/controller/authorization.rb +198 -0
  1297. data/lib/lcp_ruby/controller/bearer_authentication.rb +76 -0
  1298. data/lib/lcp_ruby/controller/crud_helpers.rb +233 -0
  1299. data/lib/lcp_ruby/controller/error_handling.rb +94 -0
  1300. data/lib/lcp_ruby/controller/impersonation.rb +70 -0
  1301. data/lib/lcp_ruby/controller/locale_binding.rb +62 -0
  1302. data/lib/lcp_ruby/controller/path_helpers.rb +125 -0
  1303. data/lib/lcp_ruby/controller/presenter_setup.rb +89 -0
  1304. data/lib/lcp_ruby/controller/search.rb +321 -0
  1305. data/lib/lcp_ruby/controller/view_helpers.rb +105 -0
  1306. data/lib/lcp_ruby/current.rb +13 -0
  1307. data/lib/lcp_ruby/custom_fields/applicator.rb +194 -0
  1308. data/lib/lcp_ruby/custom_fields/contract_validator.rb +77 -0
  1309. data/lib/lcp_ruby/custom_fields/definition_change_handler.rb +21 -0
  1310. data/lib/lcp_ruby/custom_fields/query.rb +112 -0
  1311. data/lib/lcp_ruby/custom_fields/registry.rb +70 -0
  1312. data/lib/lcp_ruby/custom_fields/setup.rb +58 -0
  1313. data/lib/lcp_ruby/custom_fields/utils.rb +40 -0
  1314. data/lib/lcp_ruby/custom_fields.rb +9 -0
  1315. data/lib/lcp_ruby/data_source/api_error_placeholder.rb +47 -0
  1316. data/lib/lcp_ruby/data_source/api_filter_translator.rb +72 -0
  1317. data/lib/lcp_ruby/data_source/api_model_concern.rb +131 -0
  1318. data/lib/lcp_ruby/data_source/api_preloader.rb +44 -0
  1319. data/lib/lcp_ruby/data_source/base.rb +85 -0
  1320. data/lib/lcp_ruby/data_source/cached_wrapper.rb +107 -0
  1321. data/lib/lcp_ruby/data_source/host.rb +71 -0
  1322. data/lib/lcp_ruby/data_source/registry.rb +39 -0
  1323. data/lib/lcp_ruby/data_source/resilient_wrapper.rb +67 -0
  1324. data/lib/lcp_ruby/data_source/rest_json.rb +247 -0
  1325. data/lib/lcp_ruby/data_source/setup.rb +57 -0
  1326. data/lib/lcp_ruby/dev_toolbar.rb +8 -0
  1327. data/lib/lcp_ruby/display/base_renderer.rb +21 -0
  1328. data/lib/lcp_ruby/display/count_badge.rb +11 -0
  1329. data/lib/lcp_ruby/display/icon_badge.rb +17 -0
  1330. data/lib/lcp_ruby/display/renderer_registry.rb +138 -0
  1331. data/lib/lcp_ruby/display/renderers/attachment_link.rb +26 -0
  1332. data/lib/lcp_ruby/display/renderers/attachment_list.rb +32 -0
  1333. data/lib/lcp_ruby/display/renderers/attachment_preview.rb +26 -0
  1334. data/lib/lcp_ruby/display/renderers/avatar.rb +14 -0
  1335. data/lib/lcp_ruby/display/renderers/badge.rb +43 -0
  1336. data/lib/lcp_ruby/display/renderers/boolean_icon.rb +54 -0
  1337. data/lib/lcp_ruby/display/renderers/code.rb +39 -0
  1338. data/lib/lcp_ruby/display/renderers/collection.rb +34 -0
  1339. data/lib/lcp_ruby/display/renderers/color_swatch.rb +25 -0
  1340. data/lib/lcp_ruby/display/renderers/concerns/attachment_helpers.rb +73 -0
  1341. data/lib/lcp_ruby/display/renderers/concerns/workflow_helpers.rb +35 -0
  1342. data/lib/lcp_ruby/display/renderers/copy_code.rb +33 -0
  1343. data/lib/lcp_ruby/display/renderers/currency.rb +14 -0
  1344. data/lib/lcp_ruby/display/renderers/date.rb +17 -0
  1345. data/lib/lcp_ruby/display/renderers/datetime.rb +17 -0
  1346. data/lib/lcp_ruby/display/renderers/email_link.rb +15 -0
  1347. data/lib/lcp_ruby/display/renderers/file_size.rb +11 -0
  1348. data/lib/lcp_ruby/display/renderers/heading.rb +11 -0
  1349. data/lib/lcp_ruby/display/renderers/image.rb +17 -0
  1350. data/lib/lcp_ruby/display/renderers/internal_link.rb +23 -0
  1351. data/lib/lcp_ruby/display/renderers/link.rb +15 -0
  1352. data/lib/lcp_ruby/display/renderers/link_list.rb +90 -0
  1353. data/lib/lcp_ruby/display/renderers/markdown.rb +33 -0
  1354. data/lib/lcp_ruby/display/renderers/number.rb +14 -0
  1355. data/lib/lcp_ruby/display/renderers/percentage.rb +12 -0
  1356. data/lib/lcp_ruby/display/renderers/phone_link.rb +15 -0
  1357. data/lib/lcp_ruby/display/renderers/progress_bar.rb +15 -0
  1358. data/lib/lcp_ruby/display/renderers/rating.rb +15 -0
  1359. data/lib/lcp_ruby/display/renderers/record_link.rb +101 -0
  1360. data/lib/lcp_ruby/display/renderers/relative_date.rb +15 -0
  1361. data/lib/lcp_ruby/display/renderers/rich_text.rb +15 -0
  1362. data/lib/lcp_ruby/display/renderers/text.rb +12 -0
  1363. data/lib/lcp_ruby/display/renderers/truncate.rb +17 -0
  1364. data/lib/lcp_ruby/display/renderers/url_link.rb +22 -0
  1365. data/lib/lcp_ruby/display/renderers/workflow_badge.rb +37 -0
  1366. data/lib/lcp_ruby/display/renderers/workflow_timeline.rb +173 -0
  1367. data/lib/lcp_ruby/display/renderers.rb +3 -0
  1368. data/lib/lcp_ruby/display/text_badge.rb +15 -0
  1369. data/lib/lcp_ruby/dsl/condition_builder.rb +190 -0
  1370. data/lib/lcp_ruby/dsl/dsl_loader.rb +365 -0
  1371. data/lib/lcp_ruby/dsl/field_builder.rb +35 -0
  1372. data/lib/lcp_ruby/dsl/job_builder.rb +92 -0
  1373. data/lib/lcp_ruby/dsl/model_builder.rb +544 -0
  1374. data/lib/lcp_ruby/dsl/presenter_builder.rb +1272 -0
  1375. data/lib/lcp_ruby/dsl/source_location_capture.rb +52 -0
  1376. data/lib/lcp_ruby/dsl/type_builder.rb +88 -0
  1377. data/lib/lcp_ruby/dsl/view_group_builder.rb +92 -0
  1378. data/lib/lcp_ruby/dsl/workflow_builder.rb +319 -0
  1379. data/lib/lcp_ruby/dynamic.rb +7 -0
  1380. data/lib/lcp_ruby/dynamic_references/resolver.rb +154 -0
  1381. data/lib/lcp_ruby/dynamic_references/validator.rb +92 -0
  1382. data/lib/lcp_ruby/embed_providers/base.rb +18 -0
  1383. data/lib/lcp_ruby/embed_providers/grafana.rb +38 -0
  1384. data/lib/lcp_ruby/embed_providers/metabase.rb +37 -0
  1385. data/lib/lcp_ruby/engine.rb +680 -0
  1386. data/lib/lcp_ruby/events/async_handler_job.rb +21 -0
  1387. data/lib/lcp_ruby/events/dispatcher.rb +52 -0
  1388. data/lib/lcp_ruby/events/handler_base.rb +51 -0
  1389. data/lib/lcp_ruby/events/handler_registry.rb +49 -0
  1390. data/lib/lcp_ruby/export/data_generator.rb +158 -0
  1391. data/lib/lcp_ruby/export/export_handler.rb +315 -0
  1392. data/lib/lcp_ruby/export/field_tree_builder.rb +219 -0
  1393. data/lib/lcp_ruby/export/setup.rb +94 -0
  1394. data/lib/lcp_ruby/export/value_formatter.rb +223 -0
  1395. data/lib/lcp_ruby/export.rb +9 -0
  1396. data/lib/lcp_ruby/gem_paths.rb +51 -0
  1397. data/lib/lcp_ruby/generators/entity_menu_writer.rb +258 -0
  1398. data/lib/lcp_ruby/generators/feature_registry.rb +208 -0
  1399. data/lib/lcp_ruby/generators/prerequisites.rb +90 -0
  1400. data/lib/lcp_ruby/grouped_query/builder.rb +206 -0
  1401. data/lib/lcp_ruby/grouped_query/result_wrapper.rb +72 -0
  1402. data/lib/lcp_ruby/grouped_query/row.rb +31 -0
  1403. data/lib/lcp_ruby/groups/change_handler.rb +18 -0
  1404. data/lib/lcp_ruby/groups/contract.rb +42 -0
  1405. data/lib/lcp_ruby/groups/contract_validator.rb +110 -0
  1406. data/lib/lcp_ruby/groups/host_loader.rb +54 -0
  1407. data/lib/lcp_ruby/groups/model_loader.rb +186 -0
  1408. data/lib/lcp_ruby/groups/registry.rb +113 -0
  1409. data/lib/lcp_ruby/groups/setup.rb +129 -0
  1410. data/lib/lcp_ruby/groups/yaml_loader.rb +97 -0
  1411. data/lib/lcp_ruby/hash_utils.rb +42 -0
  1412. data/lib/lcp_ruby/i18n_check/configuration.rb +104 -0
  1413. data/lib/lcp_ruby/i18n_check/heuristics.rb +26 -0
  1414. data/lib/lcp_ruby/i18n_check/key_deriver.rb +136 -0
  1415. data/lib/lcp_ruby/i18n_check/offense.rb +29 -0
  1416. data/lib/lcp_ruby/i18n_check/registry_walker.rb +621 -0
  1417. data/lib/lcp_ruby/i18n_check/reporter.rb +96 -0
  1418. data/lib/lcp_ruby/i18n_check/runner.rb +46 -0
  1419. data/lib/lcp_ruby/i18n_check.rb +15 -0
  1420. data/lib/lcp_ruby/i18n_lint.rb +145 -0
  1421. data/lib/lcp_ruby/import/auto_mapper.rb +98 -0
  1422. data/lib/lcp_ruby/import/field_tree_builder.rb +178 -0
  1423. data/lib/lcp_ruby/import/file_parser.rb +223 -0
  1424. data/lib/lcp_ruby/import/import_dialog_handler.rb +410 -0
  1425. data/lib/lcp_ruby/import/import_job_handler.rb +224 -0
  1426. data/lib/lcp_ruby/import/row_processor.rb +281 -0
  1427. data/lib/lcp_ruby/import/setup.rb +277 -0
  1428. data/lib/lcp_ruby/import/value_coercer.rb +143 -0
  1429. data/lib/lcp_ruby/import.rb +14 -0
  1430. data/lib/lcp_ruby/json_item_wrapper.rb +152 -0
  1431. data/lib/lcp_ruby/kanban/board.rb +28 -0
  1432. data/lib/lcp_ruby/kanban/column.rb +28 -0
  1433. data/lib/lcp_ruby/kanban/default_provider.rb +376 -0
  1434. data/lib/lcp_ruby/kanban/host_provider.rb +94 -0
  1435. data/lib/lcp_ruby/kanban/move_result.rb +52 -0
  1436. data/lib/lcp_ruby/kanban/provider_test_harness.rb +54 -0
  1437. data/lib/lcp_ruby/kanban/swimlane.rb +21 -0
  1438. data/lib/lcp_ruby/menu.rb +46 -0
  1439. data/lib/lcp_ruby/metadata/aggregate_definition.rb +6 -0
  1440. data/lib/lcp_ruby/metadata/association_definition.rb +196 -0
  1441. data/lib/lcp_ruby/metadata/auth_validator.rb +222 -0
  1442. data/lib/lcp_ruby/metadata/configuration_validator.rb +7958 -0
  1443. data/lib/lcp_ruby/metadata/contract_result.rb +9 -0
  1444. data/lib/lcp_ruby/metadata/display_template_definition.rb +77 -0
  1445. data/lib/lcp_ruby/metadata/enum_label_resolver.rb +27 -0
  1446. data/lib/lcp_ruby/metadata/erd_generator.rb +274 -0
  1447. data/lib/lcp_ruby/metadata/event_definition.rb +55 -0
  1448. data/lib/lcp_ruby/metadata/field_definition.rb +267 -0
  1449. data/lib/lcp_ruby/metadata/group_definition.rb +31 -0
  1450. data/lib/lcp_ruby/metadata/i18n_label.rb +29 -0
  1451. data/lib/lcp_ruby/metadata/loader.rb +916 -0
  1452. data/lib/lcp_ruby/metadata/menu_definition.rb +116 -0
  1453. data/lib/lcp_ruby/metadata/menu_item.rb +792 -0
  1454. data/lib/lcp_ruby/metadata/menu_item_resolver.rb +105 -0
  1455. data/lib/lcp_ruby/metadata/model_definition.rb +612 -0
  1456. data/lib/lcp_ruby/metadata/model_hash_merger.rb +88 -0
  1457. data/lib/lcp_ruby/metadata/model_inheritance_resolver.rb +165 -0
  1458. data/lib/lcp_ruby/metadata/page_definition.rb +245 -0
  1459. data/lib/lcp_ruby/metadata/path_template.rb +231 -0
  1460. data/lib/lcp_ruby/metadata/permission_definition.rb +237 -0
  1461. data/lib/lcp_ruby/metadata/permission_merger.rb +81 -0
  1462. data/lib/lcp_ruby/metadata/presenter_definition.rb +689 -0
  1463. data/lib/lcp_ruby/metadata/reserved_names.rb +79 -0
  1464. data/lib/lcp_ruby/metadata/responsive_policy.rb +95 -0
  1465. data/lib/lcp_ruby/metadata/schema_validator.rb +172 -0
  1466. data/lib/lcp_ruby/metadata/validation_definition.rb +69 -0
  1467. data/lib/lcp_ruby/metadata/view_group_definition.rb +208 -0
  1468. data/lib/lcp_ruby/metadata/virtual_column_definition.rb +154 -0
  1469. data/lib/lcp_ruby/metadata/zone_definition.rb +423 -0
  1470. data/lib/lcp_ruby/metrics/collector.rb +123 -0
  1471. data/lib/lcp_ruby/metrics/collector_registry.rb +57 -0
  1472. data/lib/lcp_ruby/metrics/error_recorder.rb +70 -0
  1473. data/lib/lcp_ruby/metrics/fingerprint.rb +33 -0
  1474. data/lib/lcp_ruby/metrics/json_query.rb +47 -0
  1475. data/lib/lcp_ruby/metrics/metric_definitions.rb +105 -0
  1476. data/lib/lcp_ruby/metrics/prometheus_check.rb +9 -0
  1477. data/lib/lcp_ruby/metrics/rate_limiter.rb +99 -0
  1478. data/lib/lcp_ruby/metrics/setup.rb +71 -0
  1479. data/lib/lcp_ruby/metrics/subscriber.rb +126 -0
  1480. data/lib/lcp_ruby/model_factory/aggregate_applicator.rb +14 -0
  1481. data/lib/lcp_ruby/model_factory/api_association_applicator.rb +119 -0
  1482. data/lib/lcp_ruby/model_factory/api_builder.rb +85 -0
  1483. data/lib/lcp_ruby/model_factory/array_type.rb +78 -0
  1484. data/lib/lcp_ruby/model_factory/array_type_applicator.rb +33 -0
  1485. data/lib/lcp_ruby/model_factory/association_applicator.rb +201 -0
  1486. data/lib/lcp_ruby/model_factory/attachment_applicator.rb +160 -0
  1487. data/lib/lcp_ruby/model_factory/auditing_applicator.rb +72 -0
  1488. data/lib/lcp_ruby/model_factory/builder.rb +235 -0
  1489. data/lib/lcp_ruby/model_factory/callback_applicator.rb +63 -0
  1490. data/lib/lcp_ruby/model_factory/computed_applicator.rb +55 -0
  1491. data/lib/lcp_ruby/model_factory/default_applicator.rb +85 -0
  1492. data/lib/lcp_ruby/model_factory/enum_applicator.rb +24 -0
  1493. data/lib/lcp_ruby/model_factory/inherited_parent_validator_applicator.rb +39 -0
  1494. data/lib/lcp_ruby/model_factory/label_method_builder.rb +82 -0
  1495. data/lib/lcp_ruby/model_factory/managed_tracking.rb +71 -0
  1496. data/lib/lcp_ruby/model_factory/positioning_applicator.rb +23 -0
  1497. data/lib/lcp_ruby/model_factory/ransack_applicator.rb +66 -0
  1498. data/lib/lcp_ruby/model_factory/registry.rb +33 -0
  1499. data/lib/lcp_ruby/model_factory/schema_manager.rb +655 -0
  1500. data/lib/lcp_ruby/model_factory/scope_applicator.rb +87 -0
  1501. data/lib/lcp_ruby/model_factory/sequence_applicator.rb +173 -0
  1502. data/lib/lcp_ruby/model_factory/service_accessor_applicator.rb +40 -0
  1503. data/lib/lcp_ruby/model_factory/soft_delete_applicator.rb +141 -0
  1504. data/lib/lcp_ruby/model_factory/transform_applicator.rb +51 -0
  1505. data/lib/lcp_ruby/model_factory/tree_applicator.rb +239 -0
  1506. data/lib/lcp_ruby/model_factory/userstamps_applicator.rb +73 -0
  1507. data/lib/lcp_ruby/model_factory/validation_applicator.rb +319 -0
  1508. data/lib/lcp_ruby/model_factory/virtual_column_applicator.rb +79 -0
  1509. data/lib/lcp_ruby/model_factory/workflow_applicator.rb +141 -0
  1510. data/lib/lcp_ruby/pages/change_handler.rb +15 -0
  1511. data/lib/lcp_ruby/pages/contract_validator.rb +74 -0
  1512. data/lib/lcp_ruby/pages/definition_validator.rb +42 -0
  1513. data/lib/lcp_ruby/pages/filter_form.rb +200 -0
  1514. data/lib/lcp_ruby/pages/filter_form_validator.rb +636 -0
  1515. data/lib/lcp_ruby/pages/registry.rb +133 -0
  1516. data/lib/lcp_ruby/pages/resolver.rb +32 -0
  1517. data/lib/lcp_ruby/pages/scope_context_resolver.rb +37 -0
  1518. data/lib/lcp_ruby/pages/scope_filter_set.rb +57 -0
  1519. data/lib/lcp_ruby/pages/setup.rb +46 -0
  1520. data/lib/lcp_ruby/path_utils.rb +12 -0
  1521. data/lib/lcp_ruby/permissions/change_handler.rb +22 -0
  1522. data/lib/lcp_ruby/permissions/contract_validator.rb +74 -0
  1523. data/lib/lcp_ruby/permissions/definition_validator.rb +119 -0
  1524. data/lib/lcp_ruby/permissions/registry.rb +135 -0
  1525. data/lib/lcp_ruby/permissions/setup.rb +51 -0
  1526. data/lib/lcp_ruby/permissions/source_resolver.rb +56 -0
  1527. data/lib/lcp_ruby/presenter/action_set.rb +236 -0
  1528. data/lib/lcp_ruby/presenter/breadcrumb_builder.rb +183 -0
  1529. data/lib/lcp_ruby/presenter/breadcrumb_path_helper.rb +17 -0
  1530. data/lib/lcp_ruby/presenter/column_set.rb +268 -0
  1531. data/lib/lcp_ruby/presenter/enrichment.rb +136 -0
  1532. data/lib/lcp_ruby/presenter/field_value_resolver.rb +237 -0
  1533. data/lib/lcp_ruby/presenter/includes_resolver/association_dependency.rb +59 -0
  1534. data/lib/lcp_ruby/presenter/includes_resolver/dependency_collector.rb +394 -0
  1535. data/lib/lcp_ruby/presenter/includes_resolver/loading_strategy.rb +70 -0
  1536. data/lib/lcp_ruby/presenter/includes_resolver/strategy_resolver.rb +123 -0
  1537. data/lib/lcp_ruby/presenter/includes_resolver.rb +42 -0
  1538. data/lib/lcp_ruby/presenter/layout_builder.rb +467 -0
  1539. data/lib/lcp_ruby/presenter/link_resolver.rb +65 -0
  1540. data/lib/lcp_ruby/presenter/metadata_lookup.rb +28 -0
  1541. data/lib/lcp_ruby/presenter/resolver.rb +25 -0
  1542. data/lib/lcp_ruby/record_aliases/metadata_checker.rb +213 -0
  1543. data/lib/lcp_ruby/record_aliases/setup.rb +212 -0
  1544. data/lib/lcp_ruby/reserved_route_segments.rb +37 -0
  1545. data/lib/lcp_ruby/roles/change_handler.rb +11 -0
  1546. data/lib/lcp_ruby/roles/contract_validator.rb +67 -0
  1547. data/lib/lcp_ruby/roles/registry.rb +89 -0
  1548. data/lib/lcp_ruby/roles/setup.rb +50 -0
  1549. data/lib/lcp_ruby/routing/presenter_routes.rb +104 -0
  1550. data/lib/lcp_ruby/saved_filters/change_handler.rb +13 -0
  1551. data/lib/lcp_ruby/saved_filters/contract_validator.rb +85 -0
  1552. data/lib/lcp_ruby/saved_filters/registry.rb +36 -0
  1553. data/lib/lcp_ruby/saved_filters/resolver.rb +108 -0
  1554. data/lib/lcp_ruby/saved_filters/setup.rb +42 -0
  1555. data/lib/lcp_ruby/saved_filters/stale_field_validator.rb +84 -0
  1556. data/lib/lcp_ruby/schemas/auth.json +208 -0
  1557. data/lib/lcp_ruby/schemas/menu.json +338 -0
  1558. data/lib/lcp_ruby/schemas/model.json +1161 -0
  1559. data/lib/lcp_ruby/schemas/page.json +877 -0
  1560. data/lib/lcp_ruby/schemas/permission.json +454 -0
  1561. data/lib/lcp_ruby/schemas/presenter.json +2274 -0
  1562. data/lib/lcp_ruby/schemas/theme.json +62 -0
  1563. data/lib/lcp_ruby/schemas/type.json +146 -0
  1564. data/lib/lcp_ruby/schemas/view_group.json +163 -0
  1565. data/lib/lcp_ruby/search/custom_field_filter.rb +171 -0
  1566. data/lib/lcp_ruby/search/custom_filter_interceptor.rb +40 -0
  1567. data/lib/lcp_ruby/search/filter_metadata_builder.rb +409 -0
  1568. data/lib/lcp_ruby/search/filter_param_builder.rb +177 -0
  1569. data/lib/lcp_ruby/search/operator_registry.rb +79 -0
  1570. data/lib/lcp_ruby/search/param_sanitizer.rb +25 -0
  1571. data/lib/lcp_ruby/search/parameter_definition.rb +187 -0
  1572. data/lib/lcp_ruby/search/parameterized_scope_applicator.rb +129 -0
  1573. data/lib/lcp_ruby/search/query_builder.rb +143 -0
  1574. data/lib/lcp_ruby/search/query_language_parser.rb +549 -0
  1575. data/lib/lcp_ruby/search/query_language_serializer.rb +193 -0
  1576. data/lib/lcp_ruby/search/quick_search.rb +162 -0
  1577. data/lib/lcp_ruby/search/relative_date_expander.rb +57 -0
  1578. data/lib/lcp_ruby/search_result.rb +70 -0
  1579. data/lib/lcp_ruby/sequences/sequence_manager.rb +51 -0
  1580. data/lib/lcp_ruby/services/accessors/json_field.rb +23 -0
  1581. data/lib/lcp_ruby/services/built_in_accessors.rb +17 -0
  1582. data/lib/lcp_ruby/services/built_in_defaults.rb +22 -0
  1583. data/lib/lcp_ruby/services/built_in_transforms.rb +20 -0
  1584. data/lib/lcp_ruby/services/checker.rb +133 -0
  1585. data/lib/lcp_ruby/services/registry.rb +83 -0
  1586. data/lib/lcp_ruby/skills_installer.rb +73 -0
  1587. data/lib/lcp_ruby/sort/enum_sort_order.rb +38 -0
  1588. data/lib/lcp_ruby/tasks/destroy_order_resolver.rb +57 -0
  1589. data/lib/lcp_ruby/tasks/doctor.rb +294 -0
  1590. data/lib/lcp_ruby/tasks/permission_resolve_formatter.rb +245 -0
  1591. data/lib/lcp_ruby/types/built_in_types.rb +157 -0
  1592. data/lib/lcp_ruby/types/transforms/base_transform.rb +11 -0
  1593. data/lib/lcp_ruby/types/transforms/downcase.rb +11 -0
  1594. data/lib/lcp_ruby/types/transforms/normalize_phone.rb +19 -0
  1595. data/lib/lcp_ruby/types/transforms/normalize_url.rb +16 -0
  1596. data/lib/lcp_ruby/types/transforms/strip.rb +11 -0
  1597. data/lib/lcp_ruby/types/type_definition.rb +112 -0
  1598. data/lib/lcp_ruby/types/type_registry.rb +75 -0
  1599. data/lib/lcp_ruby/url_safety.rb +97 -0
  1600. data/lib/lcp_ruby/user_snapshot.rb +15 -0
  1601. data/lib/lcp_ruby/version.rb +3 -0
  1602. data/lib/lcp_ruby/view_slots/registry.rb +71 -0
  1603. data/lib/lcp_ruby/view_slots/slot_component.rb +22 -0
  1604. data/lib/lcp_ruby/view_slots/slot_context.rb +20 -0
  1605. data/lib/lcp_ruby/virtual_columns/builder.rb +234 -0
  1606. data/lib/lcp_ruby/virtual_columns/collector.rb +186 -0
  1607. data/lib/lcp_ruby/virtual_columns.rb +4 -0
  1608. data/lib/lcp_ruby/virtual_fields/synthetic_marker.rb +17 -0
  1609. data/lib/lcp_ruby/virtual_fields/types/array_of.rb +49 -0
  1610. data/lib/lcp_ruby/virtual_fields/virtual_field.rb +107 -0
  1611. data/lib/lcp_ruby/virtual_fields/virtual_form.rb +144 -0
  1612. data/lib/lcp_ruby/widgets/chart_palette.rb +25 -0
  1613. data/lib/lcp_ruby/widgets/chartkick_check.rb +9 -0
  1614. data/lib/lcp_ruby/widgets/data_resolver.rb +676 -0
  1615. data/lib/lcp_ruby/widgets/date_grouper.rb +54 -0
  1616. data/lib/lcp_ruby/widgets/presenter_zone_resolver.rb +170 -0
  1617. data/lib/lcp_ruby/widgets/record_source_resolver.rb +56 -0
  1618. data/lib/lcp_ruby/widgets/scope_applicator.rb +187 -0
  1619. data/lib/lcp_ruby/workflow/approval/activation_handler.rb +39 -0
  1620. data/lib/lcp_ruby/workflow/approval/approval_definition.rb +117 -0
  1621. data/lib/lcp_ruby/workflow/approval/approver_resolver.rb +98 -0
  1622. data/lib/lcp_ruby/workflow/approval/cleanup_handler.rb +37 -0
  1623. data/lib/lcp_ruby/workflow/approval/contract_validator.rb +96 -0
  1624. data/lib/lcp_ruby/workflow/approval/data_builder.rb +53 -0
  1625. data/lib/lcp_ruby/workflow/approval/discard_handler.rb +51 -0
  1626. data/lib/lcp_ruby/workflow/approval/engine.rb +314 -0
  1627. data/lib/lcp_ruby/workflow/approval/registry.rb +40 -0
  1628. data/lib/lcp_ruby/workflow/approval/resolution_handler.rb +103 -0
  1629. data/lib/lcp_ruby/workflow/approval/setup.rb +138 -0
  1630. data/lib/lcp_ruby/workflow/approval/step_definition.rb +52 -0
  1631. data/lib/lcp_ruby/workflow/approval/step_evaluator.rb +163 -0
  1632. data/lib/lcp_ruby/workflow/approval/system_evaluator.rb +29 -0
  1633. data/lib/lcp_ruby/workflow/approval/task_manager.rb +202 -0
  1634. data/lib/lcp_ruby/workflow/audit_contract_validator.rb +64 -0
  1635. data/lib/lcp_ruby/workflow/audit_registry.rb +24 -0
  1636. data/lib/lcp_ruby/workflow/audit_writer.rb +51 -0
  1637. data/lib/lcp_ruby/workflow/change_handler.rb +14 -0
  1638. data/lib/lcp_ruby/workflow/contract.rb +21 -0
  1639. data/lib/lcp_ruby/workflow/contract_validator.rb +44 -0
  1640. data/lib/lcp_ruby/workflow/errors.rb +12 -0
  1641. data/lib/lcp_ruby/workflow/host_source.rb +19 -0
  1642. data/lib/lcp_ruby/workflow/mermaid_builder.rb +217 -0
  1643. data/lib/lcp_ruby/workflow/model_source.rb +79 -0
  1644. data/lib/lcp_ruby/workflow/registry.rb +113 -0
  1645. data/lib/lcp_ruby/workflow/resolver.rb +32 -0
  1646. data/lib/lcp_ruby/workflow/setup.rb +135 -0
  1647. data/lib/lcp_ruby/workflow/state_definition.rb +59 -0
  1648. data/lib/lcp_ruby/workflow/state_machine.rb +78 -0
  1649. data/lib/lcp_ruby/workflow/static_source.rb +20 -0
  1650. data/lib/lcp_ruby/workflow/transition_action_builder.rb +46 -0
  1651. data/lib/lcp_ruby/workflow/transition_definition.rb +70 -0
  1652. data/lib/lcp_ruby/workflow/transition_executor.rb +140 -0
  1653. data/lib/lcp_ruby/workflow/transition_label_resolver.rb +21 -0
  1654. data/lib/lcp_ruby/workflow/transition_result.rb +20 -0
  1655. data/lib/lcp_ruby/workflow/value_resolver.rb +58 -0
  1656. data/lib/lcp_ruby/workflow/workflow_definition.rb +195 -0
  1657. data/lib/lcp_ruby.rb +764 -0
  1658. data/lib/rubocop/cop/lcp_ruby/no_hardcoded_i18n_string.rb +249 -0
  1659. data/lib/tasks/lcp_ruby.rake +432 -0
  1660. data/lib/tasks/lcp_ruby_assets.rake +37 -0
  1661. data/lib/tasks/lcp_ruby_auth.rake +49 -0
  1662. data/lib/tasks/lcp_ruby_db.rake +76 -0
  1663. data/lib/tasks/lcp_ruby_doctor.rake +20 -0
  1664. data/lib/tasks/lcp_ruby_feature_catalog.rake +61 -0
  1665. data/lib/tasks/lcp_ruby_gapfree_sequences.rake +39 -0
  1666. data/lib/tasks/lcp_ruby_i18n_check.rake +23 -0
  1667. data/lib/tasks/lcp_ruby_i18n_lint.rake +20 -0
  1668. data/lib/tasks/lcp_ruby_invariant_check.rake +72 -0
  1669. data/vendor/assets/javascripts/lcp_ruby/activestorage.min.js +866 -0
  1670. data/vendor/assets/javascripts/lcp_ruby/highlight.min.js +1244 -0
  1671. data/vendor/assets/javascripts/lcp_ruby/lucide.min.js +12 -0
  1672. data/vendor/assets/javascripts/lcp_ruby/stimulus.umd.js +2588 -0
  1673. data/vendor/assets/javascripts/lcp_ruby/tom-select.complete.min.js +444 -0
  1674. data/vendor/assets/stylesheets/lcp_ruby/highlight-github.min.css +12 -0
  1675. data/vendor/assets/stylesheets/lcp_ruby/tom-select.css +412 -0
  1676. metadata +1950 -0
@@ -0,0 +1,287 @@
1
+ ---
2
+ name: lcp-host-binding
3
+ description: Use when integrating LCP Ruby with an existing Rails host application — binding metadata to existing AR models (`bind_to:`), routing CRUD to host controllers (`controller:` / `action_controllers:`), or scaffolding a host controller that includes LCP concerns. Triggers on phrases like "bind_to existing model", "wrap an existing AR model", "use existing User model", "host controller", "delegate CRUD to host", "custom controller for presenter", "lcp_ruby:host_controller generator", "LcpRuby::Controller concerns", "PresenterSetup", "CrudHelpers", "skip ResourcesController", "wizard controller for new/create", "include LCP search in my controller".
4
+ ---
5
+
6
+ > **Reference docs base:** run `bundle exec rake lcp_ruby:docs` in an LCP app (version-matched), otherwise `lcp docs path`. Resolve any `docs/X` reference below under that base (or the project root if a `docs/` tree exists there).
7
+
8
+ # LCP Ruby — Host Application Integration
9
+
10
+ LCP usually generates ActiveRecord classes and routes them through `LcpRuby::ResourcesController`. The host-integration patterns let you escape that:
11
+
12
+ 1. **`bind_to:`** on a model — point metadata at an existing host AR class; no LCP-generated class, no table created.
13
+ 2. **`controller:`** on a presenter — route all CRUD for this presenter to a host controller.
14
+ 3. **`action_controllers:`** on a presenter — route specific actions only.
15
+ 4. **`LcpRuby::Controller::*` concerns** — include in your host controller to reuse LCP's auth, search, path helpers, and views.
16
+ 5. **`lcp_ruby:host_controller` generator** — scaffold a host controller with the right concerns + actions + permitted_params.
17
+
18
+ ## Before you write anything
19
+
20
+ 1. **Read the canonical reference**: `docs/reference/host-controller-integration.md` (~300 lines).
21
+ 2. **Guide**: `docs/guides/host-controller-integration.md`, `docs/guides/host-application.md`.
22
+ 3. **Model binding details** also covered in: `docs/reference/models.md` (search for `bind_to`).
23
+
24
+ ## Pattern 1 — `bind_to:` an existing AR model
25
+
26
+ Use when the host app already has a real AR class with its own associations, callbacks, validations, etc., and you want LCP to drive its UI without re-generating the class.
27
+
28
+ ```yaml
29
+ model:
30
+ name: employee
31
+ bind_to: "::Employee" # constantize'd at boot
32
+ bind_to_apply: [ransack, scopes] # opt-in applicators (see table)
33
+ fields: # REQUIRED non-empty (security)
34
+ - { name: name, type: string }
35
+ - { name: email, type: email }
36
+ - { name: department_id, type: integer }
37
+ associations: # metadata-only — never applied as AR macros
38
+ - { type: belongs_to, name: department }
39
+ options:
40
+ label_method: name
41
+ ```
42
+
43
+ DSL: `define_model(:employee) do bind_to "::Employee"; bind_to_apply :ransack, :scopes; field :name, :string; … end`.
44
+
45
+ ### What `bind_to:` does (and skips)
46
+
47
+ - **Skipped:** `SchemaManager` (no table created/altered), `ModelFactory::Builder` (no `LcpRuby::Dynamic::Employee` — the existing class is used as-is), all applicators **by default**.
48
+ - **Always applied:** `label_method` → `to_label`; registered `model_extensions` (`config.model_extensions`).
49
+ - **`table_name` is auto-synced** from the resolved class.
50
+
51
+ ### `bind_to_apply` — opt-in applicators
52
+
53
+ | Value | Effect |
54
+ |-------|--------|
55
+ | `ransack` | `ransackable_attributes` from readable fields + `ransackable_associations` from YAML |
56
+ | `scopes` | LCP-defined scopes from YAML |
57
+ | `validations` | YAML validations (host's own AR validations always apply) |
58
+ | `virtual_columns` | Aggregate / virtual column class methods |
59
+ | `transforms` | Field value transforms |
60
+ | `computed_fields` | Before-save hooks for computed fields |
61
+ | `custom_fields` | Runtime custom fields (REQUIRES `custom_data` JSON column on host table) |
62
+ | `workflow` | Workflow state machine |
63
+ | `userstamps` | `created_by`/`updated_by` callbacks |
64
+ | `soft_delete` | Includes `Discard::Model` |
65
+ | `auditing` | Audit trail callbacks |
66
+ | `tree` | Tree structure (REQUIRES `parent_id` column) |
67
+ | `sequences` | Sequence counters |
68
+ | `positioning` | Record positioning |
69
+ | `attachments` | Active Storage macros |
70
+
71
+ `associations` and `schema` are **NOT** valid `bind_to_apply` values — both are rejected at boot with a hint pointing at `lcp_managed: true`. Use the per-item flag (next section) for selective application.
72
+
73
+ Idempotent: applied features tracked in `@lcp_applied_features` Set on the class, so metadata reload won't double-register validators/callbacks.
74
+
75
+ ### `lcp_managed: true` — per-item selective additive behavior
76
+
77
+ Default for `bind_to:` is metadata-only (column expected on host, AR macros declared by host). When you need LCP to *add* a column or AR macro to the host class, set `lcp_managed: true` on the individual `fields:` / `associations:` row:
78
+
79
+ ```yaml
80
+ # YAML form
81
+ model:
82
+ name: user
83
+ bind_to: "::LcpRuby::User"
84
+ fields:
85
+ - { name: name, type: string } # host (metadata-only)
86
+ - { name: email, type: string } # host
87
+ - { name: parent_id, type: integer, lcp_managed: true } # LCP adds column
88
+ associations:
89
+ - { type: belongs_to, name: parent, target_model: parent, lcp_managed: true, required: false } # LCP declares AR macro
90
+ ```
91
+
92
+ ```ruby
93
+ # DSL form (config/lcp_ruby/models/user.rb) — `lcp_managed: true` is a kwarg on `field` / `belongs_to` / `has_many` / `has_one`
94
+ define_model :user do
95
+ bind_to "::LcpRuby::User"
96
+ field :name, :string # host
97
+ field :email, :string # host
98
+ field :parent_id, :integer, lcp_managed: true # LCP adds column
99
+
100
+ belongs_to :parent, target_model: :parent, lcp_managed: true, required: false
101
+ end
102
+ ```
103
+
104
+ **YAML style conventions** (recommended for readability when mixing managed and host-owned rows):
105
+ 1. Place `lcp_managed: true` immediately after `type:` (or `name:` for assocs) so the runtime-significant flag lives in the first three keys, not buried at the row's end.
106
+ 2. Group managed rows together and prefix with a comment header: `# === LCP-managed ===` so a `grep` for the marker surfaces the platform-added items.
107
+
108
+ Behavior:
109
+ - **Field rows:** `add_column` to the bound table at boot when missing (idempotent, additive only — never `change_column`/`remove_column`).
110
+ - **`belongs_to` rows:** declare AR macro on the host class + auto-add FK column (and `*_type` for polymorphic) with index.
111
+ - **`has_many` / `has_one` rows:** declare AR macro on the host class. No schema change on this side. `accepts_nested_attributes_for` is suppressed (host opts in by writing it themselves).
112
+ - Gated on `auto_migrate: true`. When `auto_migrate: false`, LCP emits a clear warning and skips both schema and association steps unless the host has pre-migrated all required FK columns by hand.
113
+
114
+ Validator catches at boot: type mismatch with existing host column, AR reflection collision (with reload carve-out for LCP-self-added), method-shadow with HARD ERRORS for ActiveStorage attachments / Action Text rich text / encrypted attributes (silently overriding these breaks file uploads / encrypted reads / rich rendering), NOT NULL without default on populated tables, `nested_attributes` ignored warning, `counter_cache` against non-LCP target, `dependent: :delete/:delete_all` over `soft_delete` target, and managed associations targeting `api_model` (incompatible).
115
+
116
+ Day-2 ops (full recipes in [bind_to Managed Fields and Associations](../../../docs/design/bind_to_managed_fields_and_associations.md) → "Day-2 lifecycle"):
117
+ - **Remove a managed column:** host migration `remove_column`, then drop YAML row. LCP never destructively touches host tables.
118
+ - **Rename:** host migration `rename_column` + update YAML row name; old reflection clears on next process restart.
119
+ - **Graduate to a real Rails migration:** `bin/rails db:schema:dump` writes the column to `schema.rb`; commit. Optionally drop `lcp_managed: true` to demote to metadata-only.
120
+
121
+ See [docs/design/bind_to_managed_fields_and_associations.md](../../../docs/design/bind_to_managed_fields_and_associations.md) for the full feature spec, behavior matrix, edge cases (multi-DB, polymorphic, reload safety, etc.), and validator rules.
122
+
123
+ ### `fields:` MUST be non-empty (security gate)
124
+
125
+ `PermissionEvaluator#all_field_names` builds the `readable: all` / `writable: all` allowlist from `model_def.fields.map(&:name)`. Auto-inferring from AR columns would expose sensitive columns (`encrypted_password`, `reset_password_token`, etc.). Empty `fields:` → boot error.
126
+
127
+ ### Constraints
128
+
129
+ | | |
130
+ |---|---|
131
+ | Mutually exclusive with | `table_name:`, `data_source:`, `inherits:` (STI), `table_name: _virtual` |
132
+ | Class must inherit from | `ActiveRecord::Base` |
133
+ | Boot errors | Class missing (with Zeitwerk hint), non-AR class, presenter declares search/advanced_filter but `ransack` not in `bind_to_apply` and host doesn't define `ransackable_attributes` |
134
+ | Boot warnings | YAML field doesn't match a host column/method; `type: enum` field doesn't match host's `defined_enums` |
135
+
136
+ ## Pattern 2 — `controller:` on a presenter
137
+
138
+ Route ALL 7 CRUD actions to a host controller (`index`, `show`, `new`, `create`, `edit`, `update`, `destroy`). Ancillary routes (saved filters, custom fields, custom actions, workflow transitions, approval tasks) still go to LCP controllers.
139
+
140
+ ```yaml
141
+ presenter:
142
+ name: checkout
143
+ model: order
144
+ slug: checkout # REQUIRED with controller:
145
+ controller: "checkouts" # → ::CheckoutsController
146
+ # "admin/reports" → ::Admin::ReportsController
147
+ ```
148
+
149
+ - Both `PUT` and `PATCH` accepted for `update`.
150
+ - `read_only: true` reduces to `index` + `show` only.
151
+ - Mutually exclusive with `action_controllers:`.
152
+
153
+ ## Pattern 3 — `action_controllers:` per-action override
154
+
155
+ Route SPECIFIC actions to a host controller; others fall through to LCP's `ResourcesController`.
156
+
157
+ ```yaml
158
+ presenter:
159
+ name: orders
160
+ model: order
161
+ slug: orders # REQUIRED
162
+ action_controllers:
163
+ new: "orders/wizard#new"
164
+ create: "orders/wizard#create"
165
+ # index, show, edit, update, destroy → LCP
166
+ ```
167
+
168
+ - Format: `"<lowercase/path>#<lowercase_action>"` (regex-validated).
169
+ - Valid action keys: `index`, `show`, `new`, `create`, `edit`, `update`, `destroy`.
170
+ - Mutually exclusive with `controller:`.
171
+
172
+ ### Routing internals
173
+
174
+ LCP's `config/routes.rb` has a static catch-all `scope ":lcp_slug"` that handles all "normal" presenters. `LcpRuby::Routing::PresenterRoutes.draw_custom_controller_routes` generates **explicit literal-slug routes** for `controller:` / `action_controllers:` presenters BEFORE the catch-all, so they win Rails' top-down match. Each custom route sets `defaults: { lcp_slug: <slug>, lcp_presenter: <name> }` so `set_presenter_and_model` (which reads `params[:lcp_slug]`) keeps working.
175
+
176
+ ## Pattern 4 — Including `LcpRuby::Controller::*` concerns in a host controller
177
+
178
+ Pick the concerns you need. Each has dependencies — include in this order:
179
+
180
+ ```
181
+ ErrorHandling → Authentication → PresenterSetup →
182
+ Impersonation → Authorization → PathHelpers →
183
+ ViewHelpers → Search → CrudHelpers
184
+ ```
185
+
186
+ (`Impersonation` MUST come before `Authorization` because it overrides `effective_user`.)
187
+
188
+ | Concern | Provides | Depends on |
189
+ |---------|----------|-----------|
190
+ | `ErrorHandling` | rescue_from `MetadataError`, `RecordNotFound` + handlers | — |
191
+ | `Authentication` | `authenticate_user!`, `current_user`, `effective_user`, `warden`, `LcpRuby::Current.user` setup, three modes (`:none`/`:built_in`/`:external`) | — |
192
+ | `PresenterSetup` | `set_presenter_and_model`, `current_presenter`/`current_page`/`current_model_definition`, all LCP view helpers, includes `LcpRuby::Engine.routes.url_helpers` (so `resources_path` etc. work without prefix) | — |
193
+ | `Impersonation` | `impersonating?`, overrides `effective_user` | Auth + Setup |
194
+ | `Authorization` | `current_evaluator`, `policy`, `policy_scope`, `authorize` (Pundit-compatible API via `PolicyFactory` — does NOT include `Pundit::Authorization`), `before_action :authorize_presenter_access`, `rescue_from Pundit::NotAuthorizedError` | Setup + Auth |
195
+ | `PathHelpers` | `resource_path`, `resources_path`, `new_resource_path`, `edit_resource_path` | Setup |
196
+ | `ViewHelpers` | sort, breadcrumbs, view group methods | Setup |
197
+ | `Search` | `apply_advanced_search`, `apply_sort`, filter helpers | Setup + Auth |
198
+ | `CrudHelpers` | `permitted_params`, `set_record`, `setup_show_view_objects`, `setup_index_view_objects`, `setup_form_view_objects`; auto-includes `LcpRuby::FormActionExecution` | Setup + Auth |
199
+
200
+ Each concern checks `method_defined?` for its dependencies in `included do` and raises a descriptive error at class load time → catches misconfiguration early.
201
+
202
+ ### View instance variable contract
203
+
204
+ When rendering LCP view templates (e.g. `render "lcp_ruby/resources/show"`), set the right ivars — most are populated by helpers from `CrudHelpers`:
205
+
206
+ | View | Required ivars (helper that sets them) |
207
+ |------|---------------------------------------|
208
+ | `…/index` | `@records` (you), `@column_set`/`@action_set` (`setup_index_view_objects`), `@ransack_search` (Search) |
209
+ | `…/show` | `@record` (you), `@layout_builder`/`@column_set`/`@field_resolver`/`@action_set` (`setup_show_view_objects(presenter)`) |
210
+ | `…/new`, `…/edit` | `@record` (you), `@layout_builder`/`@form_actions` (`setup_form_view_objects(record)`) |
211
+
212
+ `@presenter_definition`/`@model_definition`/`@page_definition` are set automatically by `PresenterSetup`'s `before_action`.
213
+
214
+ ## Pattern 5 — `lcp_ruby:host_controller` generator
215
+
216
+ ```bash
217
+ rails generate lcp_ruby:host_controller PRESENTER_NAME [options]
218
+ ```
219
+
220
+ | Option | Default | Values |
221
+ |--------|---------|--------|
222
+ | `--concerns` | `all` | comma-sep short names: `setup`, `auth`, `search`, `crud`, `paths`, `views`, `errors`, `all` |
223
+ | `--actions` | `all` | comma-sep: `index`, `show`, `new`, `create`, `edit`, `update`, `destroy`, `all` |
224
+ | `--views` | `lcp` | `lcp` (render LCP templates) or `custom` (generate empty view stubs) |
225
+
226
+ Concern aliases: `errors`→ErrorHandling, `setup`→PresenterSetup, `auth`→Authentication+Impersonation+Authorization, `paths`→PathHelpers, `views`→ViewHelpers, `search`→Search, `crud`→CrudHelpers.
227
+
228
+ Auto-resolves dependencies and orders includes topologically. Examples:
229
+
230
+ ```bash
231
+ rails generate lcp_ruby:host_controller orders # full
232
+ rails generate lcp_ruby:host_controller reports --concerns=setup,paths --actions=index,show
233
+ rails generate lcp_ruby:host_controller wizard --views=custom --actions=new,create
234
+ rails generate lcp_ruby:host_controller listings --concerns=search # auto-pulls setup+auth
235
+ ```
236
+
237
+ Generated: `app/controllers/<plural>_controller.rb` + (for `--views=custom`) `app/views/<plural>/*.html.erb` stubs. `permitted_params` is derived from the presenter's writable fields when metadata is loadable, else a TODO comment.
238
+
239
+ ## Pitfalls & guidance
240
+
241
+ - **`bind_to:` `fields:` empty → boot error.** Always declare what LCP needs to know about (it's the security allowlist, not a column list).
242
+ - **`bind_to:` `associations:` are metadata-only.** Don't expect AR `belongs_to`/`has_many` to be installed — declare them on the host class. The YAML associations are used by presenters for display, FK permitting, and association select widgets.
243
+ - **Always-applied features run regardless** of `bind_to_apply`: `label_method` and `model_extensions`.
244
+ - **Adding a new applicator?** It must respect the bind_to + bind_to_apply contract — only run when explicitly listed (or document why it's always-applied).
245
+ - **`controller:` / `action_controllers:` REQUIRE `slug:`.** Without it, the route generator can't draw the explicit slug-scoped route.
246
+ - **Don't skip the include order** for concerns — `Impersonation` before `Authorization` is critical (overrides `effective_user`); other concerns will load-time-error if their deps are missing.
247
+ - **Custom controller can render LCP views** — set the right ivars (table above) and `render "lcp_ruby/resources/index"` etc. Or use `--views=custom` to start from blank stubs.
248
+ - **The leading `/` on `controller:` paths** is added internally by the router to break out of the engine module scope into the host namespace. Don't add it yourself in YAML.
249
+ - **Ransack for bind_to models:** if a presenter declares `search_parameters` or `advanced_filter` on a `bind_to:` model, either include `ransack` in `bind_to_apply` OR define `ransackable_attributes` on the host class. Otherwise: boot error.
250
+ - **Custom fields on bind_to:** requires `bind_to_apply: [custom_fields]` AND a `custom_data` JSON/JSONB column on the host table. Without the column, dynamic accessors will fail at runtime.
251
+
252
+ ## Advanced (one-line pointers)
253
+
254
+ Stuff with its own dedicated reference / guide. **Browse `docs/feature-catalog.md`** — sections `## Bind To`, `## Host Controller`, `## Authentication`, `## API Backed Models`. Don't inline syntax; just open the relevant doc.
255
+
256
+ - **Engine configuration full surface** — `LcpRuby.configure do |c| ... end` knobs: authentication mode, mount paths, model_extensions hooks (`on_model_ready`), service registry discovery, hierarchy_resolver, group_source, role_source, permission_source, workflow_source, audit model names. → `docs/reference/engine-configuration.md`.
257
+ - **Authentication tri-mode** — `:none` (anonymous), `:built_in` (Devise via `lcp_ruby:install_auth` generator: lockable, recoverable, timeoutable, registration toggle, account locking), `:external` (host app provides `current_user`). → `docs/guides/host-application.md` `## Step 5: Set Up current_user`, feature-catalog `## Authentication`.
258
+ - **Concern dependency guards** — each concern's `included do` block calls `method_defined?` for required methods and raises descriptive error at class-load time → catches misconfigured include order before first request. → host-controller-integration.md `## Concern dependency guards`.
259
+ - **View instance variable contract** — full table of which ivars LCP templates expect for index/show/new/edit, mapped to which helper sets them (`setup_show_view_objects`, `setup_index_view_objects`, `setup_form_view_objects`). Critical when hand-crafting a host action that renders LCP templates. → host-controller-integration.md `## View instance variable contract`.
260
+ - **Hybrid routing internals** — explicit literal-slug routes drawn BEFORE the `scope ":lcp_slug"` catch-all by `LcpRuby::Routing::PresenterRoutes.draw_custom_controller_routes`; each sets `defaults: { lcp_slug:, lcp_presenter: }` so `set_presenter_and_model` keeps working unchanged. `rails routes | grep <slug>` to verify precedence. → host-controller-integration.md `## Routing architecture`.
261
+ - **Impersonation under host integration** — include `LcpRuby::Controller::Impersonation` BEFORE Authorization (overrides `effective_user`). Inherits target user's groups. → `docs/guides/impersonation.md`, feature-catalog `## Groups → Groups with Impersonation`.
262
+ - **Workflow on bind_to models** — `bind_to_apply: [workflow]` then define workflow in `config/lcp_ruby/workflows/` referencing the LCP model name; `before_save` guard installed on the host AR class. → `lcp-workflow` skill.
263
+ - **Custom fields on bind_to models** — `bind_to_apply: [custom_fields]` AND host table needs `custom_data` JSON/JSONB column. → `lcp-custom-field` skill.
264
+ - **Three-source principle for Groups / Roles / Permissions / Workflow / Pages** — same pattern as `bind_to:`: YAML/DSL static + DB-backed model + host provider class. Each has `*_source` config knob and a contract validator. → `docs/reference/groups.md`, `role-source.md`, `permission-source.md`, `workflow.md` (Three Definition Sources), `pages.md` (Page Source).
265
+ - **API-backed models as alternative to `bind_to`** — when the data lives in an external HTTP API rather than a host AR table, use `data_source: type: rest_json` or `:host` (host provides ActiveModel data source). Cross-source associations supported. → `docs/reference/api-backed-models.md`, feature-catalog `## API Backed Models`.
266
+ - **Generator concern auto-resolution** — `--concerns=search` auto-pulls `PresenterSetup`, `Authentication`, `Authorization` in correct topological order. `--concerns=all` includes all 9. Aliases: `errors`/`setup`/`auth`/`paths`/`views`/`search`/`crud`. → host-controller-integration.md `## Concern aliases`.
267
+ - **`PresenterSetup` magic** — auto-registers all 11 LCP view helpers (Display, Form, Layout, Tree, Search, …) AND includes `LcpRuby::Engine.routes.url_helpers`, so host controllers get `resources_path`, `landing_path`, `new_resource_path` etc. without `lcp_ruby.` prefix. `url_for` in LCP partials resolves against the engine's route table. → host-controller-integration.md.
268
+ - **Authorization concern is NOT Pundit** — provides Pundit-compatible API (`authorize`, `policy`, `policy_scope`) backed by `LcpRuby::Authorization::PolicyFactory`. Does NOT include `Pundit::Authorization`. Avoids version conflicts. → host-controller-integration.md.
269
+ - **`bind_to` always-applied features** — `label_method` → `to_label`, plus any `on_model_ready` blocks from `config.model_extensions`. Run regardless of `bind_to_apply`. → host-controller-integration.md `## Always-applied features`.
270
+ - **Boot-time validation** — class resolution (Zeitwerk hint), AR check, field-column matching (warning), enum value matching (warning), Ransack requirement enforcement. → host-controller-integration.md `## Boot-time validation`.
271
+
272
+ When in doubt about whether a capability exists at all → grep `docs/feature-catalog.md`.
273
+
274
+ ## After editing
275
+
276
+ 1. Restart the dev server (model bindings + custom routes draw at boot).
277
+ 2. `bundle exec rake lcp_ruby:validate` (auto-fired by the `lcp-validate` hook for `examples/*/config/lcp_ruby/`).
278
+ 3. For a new host controller: hit each routed action in the browser to confirm the right controller handles it. `rails routes | grep <slug>` to verify route precedence.
279
+
280
+ ## Related skills / docs
281
+
282
+ - Defining the LCP model first → `lcp-model` skill (then add `bind_to:`).
283
+ - Custom field bind_to gotchas → `lcp-custom-field` skill.
284
+ - Workflow on a bind_to model → `lcp-workflow` skill (`bind_to_apply: [workflow]` + workflow definition referencing the host model).
285
+ - Permissions for host-bound models work normally → `lcp-permissions` skill.
286
+ - Full host-app setup walkthrough (initial `rails new` → first model+presenter+menu) → `docs/guides/host-application.md`.
287
+ - Three-source principle this fits into → see CLAUDE.md "Configuration Source Principle" table.
@@ -0,0 +1,185 @@
1
+ ---
2
+ name: lcp-model
3
+ description: Use when creating or modifying LCP Ruby model definitions in `config/lcp_ruby/models/` (either YAML `*.yml` or DSL `*.rb`). Triggers on phrases like "add a model", "model field", "model validation", "belongs_to", "has_many", "scope", "soft_delete", "auditing", "userstamps", "tree", "positioning", "STI", "abstract model", "aggregate", "display_template", "data_source", "API-backed", "bind_to". Also for editing existing model files under `config/lcp_ruby/models/`.
4
+ ---
5
+
6
+ > **Reference docs base:** run `bundle exec rake lcp_ruby:docs` in an LCP app (version-matched), otherwise `lcp docs path`. Resolve any `docs/X` reference below under that base (or the project root if a `docs/` tree exists there).
7
+
8
+ # LCP Ruby — Model Authoring
9
+
10
+ Models define data structure: tables, columns, validations, associations, scopes, lifecycle events. Defined per-file in `config/lcp_ruby/models/<name>.{rb,yml}`. The engine builds `ActiveRecord` classes under `LcpRuby::Dynamic::*` at boot.
11
+
12
+ > **New entity from scratch?** If the user is creating a brand-new model **and** also needs a presenter + permissions + view group (the typical case for a fresh CRUD entity), prefer `rails generate lcp_ruby:entity NAME field:type ...` — one command produces all four files atomically. Hand-writing is for **editing** existing models or for cases the CLI grammar can't express. See `lcp-getting-started` skill, "Fast path" subsection, or `docs/design/entity_generator.md` for the full grammar.
13
+
14
+ ## Before you write anything
15
+
16
+ 1. **Read the canonical reference** — pick one based on chosen format:
17
+ - DSL (`.rb`): `docs/reference/model-dsl.md` (full, ~1100 lines)
18
+ - YAML (`.yml`): `docs/reference/models.md` (full, ~2200 lines)
19
+ - JSON Schema: `lib/lcp_ruby/schemas/model.json` (authoritative for valid YAML keys)
20
+ 2. **Mirror the project's chosen format.** Look at neighbouring files in `config/lcp_ruby/models/` — do not introduce a new format if all existing files use one. A given model name must be unique across `.yml` and `.rb`.
21
+ 3. **Check the host project's CLAUDE.md** for any model conventions (e.g., naming, prefixes for abstract models like `_auditable`).
22
+
23
+ ## File location
24
+
25
+ ```
26
+ config/lcp_ruby/models/<name>.rb # DSL
27
+ config/lcp_ruby/models/<name>.yml # YAML
28
+ ```
29
+
30
+ `<name>` is the model name in `snake_case` and becomes the table name (auto-pluralised). Files starting with `_` (e.g. `_auditable.rb`) are conventionally abstract templates.
31
+
32
+ ## Minimal model
33
+
34
+ DSL:
35
+ ```ruby
36
+ define_model :task do
37
+ field :title, :string do
38
+ validates :presence
39
+ validates :length, minimum: 3, maximum: 255
40
+ end
41
+ field :completed, :boolean, default: false
42
+ timestamps true
43
+ label_method :title
44
+ end
45
+ ```
46
+
47
+ YAML:
48
+ ```yaml
49
+ model:
50
+ name: task
51
+ fields:
52
+ - name: title
53
+ type: string
54
+ validations:
55
+ - { type: presence }
56
+ - { type: length, minimum: 3, maximum: 255 }
57
+ - name: completed
58
+ type: boolean
59
+ default: false
60
+ options:
61
+ timestamps: true
62
+ label_method: title
63
+ ```
64
+
65
+ ## Field types
66
+
67
+ **Base types** (15): `string`, `text`, `integer`, `float`, `decimal` (use `precision:`/`scale:`), `boolean`, `date`, `datetime`, `enum` (requires `values:`), `file`, `rich_text`, `json` (jsonb on PG), `uuid`, `attachment` (Active Storage, no DB column), `array` (requires `item_type:`).
68
+
69
+ **Built-in business types**: `email`, `phone`, `url`, `color`, `bigint` — these bundle transforms + validations + input hints. See `docs/reference/types.md`.
70
+
71
+ **Custom types** can be defined in `config/lcp_ruby/types/` — see `docs/reference/types.md`.
72
+
73
+ ## Common per-model options
74
+
75
+ | Option | Purpose | Doc section |
76
+ |--------|---------|-------------|
77
+ | `timestamps true` | Adds `created_at`/`updated_at` | `models.md` |
78
+ | `soft_delete` | Logical deletion (`discarded_at`) | `models.md#soft_delete` |
79
+ | `auditing` | Change audit log | `models.md#auditing` |
80
+ | `userstamps` | `created_by_id`/`updated_by_id` | `models.md#userstamps` |
81
+ | `tree` | Self-referential hierarchy | `models.md#tree` + `docs/reference/tree-structures.md` |
82
+ | `positioning` | Drag-and-drop ordering | `models.md#positioning` |
83
+ | `custom_fields true` | Runtime user-defined fields | `docs/reference/custom-fields.md` |
84
+ | `slug_field :slug` | Slug-based routing (also add unique index + format validation) | `models.md#slug_field` |
85
+ | `data_source` | API-backed model (no DB table) | `docs/reference/api-backed-models.md` |
86
+ | `bind_to: "::HostClass"` | Use existing host AR model instead of generating one | `docs/reference/models.md` |
87
+ | `abstract` + `inherits:` | Template / STI parent | `models.md#abstract`, `models.md#inherits` |
88
+
89
+ ## Associations
90
+
91
+ Both `belongs_to` and `has_many`/`has_one` require **either** `model:` (LCP-managed model) **or** `class_name:` (host AR class). Polymorphic, `through:`, `nested_attributes:`, `primary_key:` (business-key joins) are all supported. See `docs/reference/model-dsl.md#associations` (or `models.md#associations`).
92
+
93
+ `nested_attributes` requires `inverse_of:`. For sortable nested rows on a `has_many`, set `order: { position: :asc }` and use `sortable: true` in the presenter's `nested_fields`.
94
+
95
+ For intentionally one-directional `belongs_to` (audit/owner/author refs where reverse traversal would be noise), set `skip_inverse_check: true` to silence the missing-`has_many` warning from `lcp_ruby:validate`. Only valid on `belongs_to` — has_many/has_one without inverse is a real bug. See `models.md#skip_inverse_check`.
96
+
97
+ ## Scopes
98
+
99
+ Declarative only — `where`, `where_not`, `order`, `limit`. No raw SQL or lambdas in YAML/DSL config. For runtime parameters, use `type: :parameterized` with typed `parameters:`. See `models.md#scopes`. Scopes are referenced from `presenter.search.filter` blocks.
100
+
101
+ ## Validations
102
+
103
+ Built-in types: `presence`, `length`, `numericality`, `format` (use **string** patterns, not regex literals — for portability), `inclusion`, `exclusion`, `uniqueness`, `confirmation`, `comparison`, `array_length`, `array_inclusion`, `array_uniqueness`, `service` (named service), `custom` (full class). All accept `message:`, `allow_blank:`, `if:`, `unless:` (method-name strings only). See `model-dsl.md#validations`.
104
+
105
+ For cross-field validators: `validates_model :custom, validator_class: "DateRangeValidator"`.
106
+
107
+ ## Lifecycle events & display templates & aggregates
108
+
109
+ These are advanced — read the relevant section before adding:
110
+ - **Events**: `after_create`, `after_update`, `before_destroy`, `after_destroy`, `on_field_change` → wired to event handlers (`docs/guides/event-handlers.md`).
111
+ - **Display templates**: rich record labels with `{field}` interpolation, custom renderers, or partials. `models.md#display-templates`.
112
+ - **Aggregates**: virtual SQL-derived columns (count/sum/min/max/avg over an association, or full custom SQL, or service). Useful for index columns and dashboards. `models.md#aggregates`.
113
+
114
+ ## Pitfalls & guidance
115
+
116
+ - **Inheritance.** `inherits:` works in two modes: abstract template (fields merge into child, no parent table) and STI (`options.sti: true` on parent, single shared table). They behave differently — read `models.md#inherits`.
117
+ - **Indexes** are declared on the model (`index :col, unique: true`); the engine creates them at boot. Don't write ad-hoc `add_index` migrations.
118
+ - **Tables** must come from the YAML/DSL — `SchemaManager` creates them at boot. Never write `create_table` in Ruby code (see project CLAUDE.md "Table creation rule").
119
+ - **Format validation regexes** must be strings (e.g. `'\A[a-z0-9-]+\z'`), not Ruby regex literals. The string is converted to a `Regexp` at runtime.
120
+ - **`bind_to:`** — when integrating an existing host AR model, the table already exists. Don't duplicate columns; just declare what LCP needs to know about.
121
+ - **Field-level vs model-level validations:** both styles produce identical output. Prefer field-block style for readability when the validation belongs to one field.
122
+
123
+ ## Advanced (one-line pointers)
124
+
125
+ Stuff with its own dedicated reference / guide. **Browse `docs/feature-catalog.md` first** — section names below match it 1:1. Don't inline syntax for these unless asked; just open the relevant doc.
126
+
127
+ - **Virtual columns** — query-time SQL-derived columns: declarative aggregates (function/association/where/distinct/default), expression columns (raw SQL with `%{table}` placeholder, `auto_include:`), JOIN-based columns (deduplicated), window functions, service columns. → `docs/guides/virtual-columns.md`, `docs/design/virtual_columns.md`, feature-catalog `## Virtual Fields`. (YAML alias `aggregates` → `virtual_columns`, `sql` → `expression`.)
128
+ - **Computed fields** (`computed: { service: ClassName }`) — read-only fields populated by a Ruby service on save. Different from virtual columns: stored in DB, computed before-save vs computed at query time. → `docs/guides/computed-fields.md`, `docs/reference/models.md#computed`.
129
+ - **Field accessors / virtual fields with `source:`** (beta) — no-column fields backed by `json_field` service or `:external` accessor; expose JSON column keys as typed first-class fields, support default values + inclusion validation. → `docs/design/fields_accessors.md`, `docs/guides/virtual-columns.md` (Virtual Field sub-section). Useful pattern: user preferences as `user.profile_data` keys.
130
+ - **Sequences** — auto-numbering on field via `sequence:` on a `field`. Format strings, scope, padding. → `docs/guides/sequences.md`, `docs/reference/models.md#sequence`.
131
+ - **Transforms** (`transforms: [strip, downcase, parameterize]`) — auto value transforms on save. Custom transforms via `app/lcp_services/`. → `docs/reference/models.md#transforms`.
132
+ - **Default services** (`default: { service: ClassName }`) — computed defaults beyond literals. → `docs/reference/models.md#default`.
133
+ - **Attachments** — image variants (`resize_to_limit`), multi-file (`mode: multiple`, `max_files`), validation (`max_size`, `content_types`, MIME wildcards). → `docs/guides/attachments.md`, feature-catalog `## Attachments`.
134
+ - **Association `primary_key:` (business-key joins)** — join on a non-id column (e.g. `division.vema_code`). Boot validations: column exists, type-compat, uniqueness, reciprocity. Rejected with `through:`/polymorphic/tree/cross-source. Importer write-back uses business key. → `docs/design/association_primary_key.md`, feature-catalog `## Association Primary Key`.
135
+ - **Model inheritance details** — abstract+STI combined chains, additive validation inheritance, deep-merged options, multi-level chained inheritance, scope inheritance, STI permission fallback (child → parent → `_default`). → `docs/design/model_inheritance.md`, feature-catalog `## Model Inheritance`.
136
+ - **Tree structures** — closure tables, depth column, counter cache, recursive scopes (`descendants`, `ancestors`). → `docs/reference/tree-structures.md`, `docs/guides/tree-structures.md`.
137
+ - **Soft delete** — `discarded_at`, custom column, `with_discarded` / `kept` scopes, controller-level `restore`/`permanently_destroy` actions. → `docs/guides/soft-delete.md`.
138
+ - **Userstamps** — `created_by_id`/`updated_by_id` + `store_name: true` denormalized snapshots, custom column names. → `docs/guides/userstamps.md`.
139
+ - **Auditing** — `lcp_audit_logs` model contract, expand_custom_fields/expand_json_fields, audit history section in presenters. → `docs/reference/auditing.md`, `docs/guides/auditing.md`.
140
+ - **Eager loading** — `includes` vs `eager_load` semantics, auto-detection for nested fields, N+1 patterns. → `docs/guides/eager-loading.md`.
141
+ - **API-backed models** (`data_source: type: rest_json` or `:host`) — REST adapter with auth/pagination/cache, host-provided ActiveModel data sources, cross-source associations (DB↔API), caching & resilience (stale-on-error). → `docs/reference/api-backed-models.md`, `docs/guides/api-backed-models.md`, feature-catalog `## API Backed Models`.
142
+ - **Display templates with renderer/partial** — beyond `template:` interpolation, you can plug a `BaseRenderer` subclass or a Rails partial. → `docs/reference/models.md#display-templates`.
143
+ - **Slug field reserved-segment validation** — auto-added exclusion validation prevents slug values colliding with routing segments (`new`, `edit`, `actions`, …). → `docs/design/record_aliases.md`.
144
+
145
+ When in doubt about whether a capability exists at all → grep `docs/feature-catalog.md` (auto-generated inventory of every shipped capability with category + doc/source links).
146
+
147
+ ## After editing
148
+
149
+ 1. Run validation from the host app directory: `bundle exec rake lcp_ruby:validate`
150
+ (Picked up automatically by the project's `lcp-validate` PostToolUse hook for files under `examples/*/config/lcp_ruby/`.)
151
+ 2. If you changed schema (added/removed fields or changed types), restart the dev server — schema rebuilds at boot.
152
+ 3. Run tests if any exist for this model: `bundle exec rspec spec/integration/<model>_spec.rb`.
153
+ 4. Look at `examples/showcase/config/lcp_ruby/models/` for working patterns of every option.
154
+
155
+ ## i18n principle
156
+
157
+ **No user-visible literals in YAML / DSL.** Model `label`, `label_plural`, field `label:`, and enum value labels all resolve through `I18n.t` with humanize as fallback. The translation lives in `config/locales/<locale>.yml`, not in the model definition.
158
+
159
+ Authoring pattern:
160
+
161
+ ```ruby
162
+ # config/lcp_ruby/models/grade.rb
163
+ field :recorded_on, :date # NO `label: "Recorded on"` — humanize default + translation
164
+ ```
165
+
166
+ ```yaml
167
+ # config/locales/cs.yml
168
+ cs:
169
+ lcp_ruby:
170
+ models:
171
+ grade:
172
+ one: "Známka"
173
+ other: "Známky"
174
+ fields:
175
+ recorded_on: "Zaznamenáno"
176
+ ```
177
+
178
+ Verify with `bundle exec rake lcp_ruby:i18n_check` (boots Rails, asserts every Tier 1 key has a translation in every configured locale). See `docs/reference/i18n_check.md`.
179
+
180
+ ## Related skills / docs
181
+
182
+ - Adding/changing UI for a model → use `lcp-presenter` skill.
183
+ - Locking down access → use `lcp-permissions` skill.
184
+ - Custom field types → `docs/reference/types.md` and `docs/guides/custom-types.md`.
185
+ - DB-backed models → see `docs/reference/api-backed-models.md` for the host-API pattern.