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.
- checksums.yaml +7 -0
- data/.claude/skills/lcp-custom-field/SKILL.md +205 -0
- data/.claude/skills/lcp-getting-started/SKILL.md +332 -0
- data/.claude/skills/lcp-host-binding/SKILL.md +287 -0
- data/.claude/skills/lcp-model/SKILL.md +185 -0
- data/.claude/skills/lcp-permissions/SKILL.md +176 -0
- data/.claude/skills/lcp-presenter/SKILL.md +194 -0
- data/.claude/skills/lcp-workflow/SKILL.md +281 -0
- data/CHANGELOG.md +69 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +17 -0
- data/app/assets/javascripts/lcp_ruby/application.js +58 -0
- data/app/assets/javascripts/lcp_ruby/controllers/advanced_filter_controller.js +1521 -0
- data/app/assets/javascripts/lcp_ruby/controllers/approval_actions_controller.js +24 -0
- data/app/assets/javascripts/lcp_ruby/controllers/array_input_controller.js +156 -0
- data/app/assets/javascripts/lcp_ruby/controllers/batch_select_controller.js +405 -0
- data/app/assets/javascripts/lcp_ruby/controllers/cascading_selects_controller.js +436 -0
- data/app/assets/javascripts/lcp_ruby/controllers/char_counter_controller.js +28 -0
- data/app/assets/javascripts/lcp_ruby/controllers/clipboard_controller.js +62 -0
- data/app/assets/javascripts/lcp_ruby/controllers/conditional_rendering_controller.js +178 -0
- data/app/assets/javascripts/lcp_ruby/controllers/confirm_dialog_controller.js +131 -0
- data/app/assets/javascripts/lcp_ruby/controllers/custom_fields_manage_controller.js +80 -0
- data/app/assets/javascripts/lcp_ruby/controllers/dialog_controller.js +421 -0
- data/app/assets/javascripts/lcp_ruby/controllers/dialog_nested_controller.js +182 -0
- data/app/assets/javascripts/lcp_ruby/controllers/direct_upload_controller.js +100 -0
- data/app/assets/javascripts/lcp_ruby/controllers/drawer_controller.js +205 -0
- data/app/assets/javascripts/lcp_ruby/controllers/dropdown_controller.js +160 -0
- data/app/assets/javascripts/lcp_ruby/controllers/export_dialog_controller.js +15 -0
- data/app/assets/javascripts/lcp_ruby/controllers/field_picker_controller.js +290 -0
- data/app/assets/javascripts/lcp_ruby/controllers/file_upload_controller.js +135 -0
- data/app/assets/javascripts/lcp_ruby/controllers/filter_auto_submit_controller.js +46 -0
- data/app/assets/javascripts/lcp_ruby/controllers/filter_dirty_controller.js +94 -0
- data/app/assets/javascripts/lcp_ruby/controllers/form_actions_controller.js +68 -0
- data/app/assets/javascripts/lcp_ruby/controllers/form_handling_controller.js +67 -0
- data/app/assets/javascripts/lcp_ruby/controllers/import_dialog_controller.js +142 -0
- data/app/assets/javascripts/lcp_ruby/controllers/import_mapper_controller.js +322 -0
- data/app/assets/javascripts/lcp_ruby/controllers/index_sortable_controller.js +388 -0
- data/app/assets/javascripts/lcp_ruby/controllers/inline_create_controller.js +137 -0
- data/app/assets/javascripts/lcp_ruby/controllers/kanban_board_controller.js +290 -0
- data/app/assets/javascripts/lcp_ruby/controllers/menu_controller.js +19 -0
- data/app/assets/javascripts/lcp_ruby/controllers/nested_forms_controller.js +261 -0
- data/app/assets/javascripts/lcp_ruby/controllers/responsive_sidebar_controller.js +161 -0
- data/app/assets/javascripts/lcp_ruby/controllers/responsive_top_nav_controller.js +394 -0
- data/app/assets/javascripts/lcp_ruby/controllers/saved_filters_controller.js +129 -0
- data/app/assets/javascripts/lcp_ruby/controllers/search_controller.js +82 -0
- data/app/assets/javascripts/lcp_ruby/controllers/selection_controller.js +33 -0
- data/app/assets/javascripts/lcp_ruby/controllers/sidebar_controller.js +83 -0
- data/app/assets/javascripts/lcp_ruby/controllers/sidebar_toggle_controller.js +66 -0
- data/app/assets/javascripts/lcp_ruby/controllers/slider_controller.js +26 -0
- data/app/assets/javascripts/lcp_ruby/controllers/submenu_controller.js +55 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tom_select_controller.js +168 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tree_index_controller.js +106 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tree_reparent_controller.js +182 -0
- data/app/assets/javascripts/lcp_ruby/controllers/tree_select_controller.js +119 -0
- data/app/assets/javascripts/lcp_ruby/controllers/ui_components_controller.js +135 -0
- data/app/assets/javascripts/lcp_ruby/controllers/zone_tabs_controller.js +66 -0
- data/app/assets/javascripts/lcp_ruby/dev_toolbar.js +494 -0
- data/app/assets/javascripts/lcp_ruby/i18n.js.erb +29 -0
- data/app/assets/javascripts/lcp_ruby/lucide_init.js +24 -0
- data/app/assets/javascripts/lcp_ruby/stimulus_bootstrap.js +7 -0
- data/app/assets/javascripts/lcp_ruby/utils.js +119 -0
- data/app/assets/javascripts/lcp_ruby/xhr_fetch.js +411 -0
- data/app/assets/stylesheets/lcp_ruby/application.css +1940 -0
- data/app/assets/stylesheets/lcp_ruby/dev_toolbar.css +355 -0
- data/app/controllers/concerns/lcp_ruby/dialog_rendering.rb +167 -0
- data/app/controllers/concerns/lcp_ruby/form_action_execution.rb +249 -0
- data/app/controllers/concerns/lcp_ruby/page_authorization.rb +105 -0
- data/app/controllers/concerns/lcp_ruby/zone_resolution.rb +199 -0
- data/app/controllers/lcp_ruby/actions_controller.rb +481 -0
- data/app/controllers/lcp_ruby/application_controller.rb +59 -0
- data/app/controllers/lcp_ruby/approval_tasks_controller.rb +98 -0
- data/app/controllers/lcp_ruby/auth/base_controller.rb +58 -0
- data/app/controllers/lcp_ruby/auth/callbacks_controller.rb +103 -0
- data/app/controllers/lcp_ruby/auth/passwords_controller.rb +15 -0
- data/app/controllers/lcp_ruby/auth/registrations_controller.rb +37 -0
- data/app/controllers/lcp_ruby/auth/sessions_controller.rb +112 -0
- data/app/controllers/lcp_ruby/custom_fields_controller.rb +370 -0
- data/app/controllers/lcp_ruby/dev_toolbar_controller.rb +197 -0
- data/app/controllers/lcp_ruby/dialogs_controller.rb +199 -0
- data/app/controllers/lcp_ruby/health_controller.rb +23 -0
- data/app/controllers/lcp_ruby/impersonation_controller.rb +32 -0
- data/app/controllers/lcp_ruby/landing_controller.rb +49 -0
- data/app/controllers/lcp_ruby/metrics_controller.rb +17 -0
- data/app/controllers/lcp_ruby/resources_controller.rb +2218 -0
- data/app/controllers/lcp_ruby/saved_filters_controller.rb +221 -0
- data/app/helpers/lcp_ruby/condition_helper.rb +87 -0
- data/app/helpers/lcp_ruby/dashboard_helper.rb +45 -0
- data/app/helpers/lcp_ruby/dev_toolbar_helper.rb +17 -0
- data/app/helpers/lcp_ruby/dialog_helper.rb +27 -0
- data/app/helpers/lcp_ruby/display/card_helper.rb +317 -0
- data/app/helpers/lcp_ruby/display_helper.rb +63 -0
- data/app/helpers/lcp_ruby/display_template_helper.rb +100 -0
- data/app/helpers/lcp_ruby/form_helper.rb +1020 -0
- data/app/helpers/lcp_ruby/grouped_query_helper.rb +107 -0
- data/app/helpers/lcp_ruby/i18n_payload_helper.rb +197 -0
- data/app/helpers/lcp_ruby/layout_helper.rb +832 -0
- data/app/helpers/lcp_ruby/link_through_helper.rb +29 -0
- data/app/helpers/lcp_ruby/oidc_button_helper.rb +59 -0
- data/app/helpers/lcp_ruby/search_helper.rb +31 -0
- data/app/helpers/lcp_ruby/tree_helper.rb +140 -0
- data/app/helpers/lcp_ruby/view_slot_helper.rb +33 -0
- data/app/models/lcp_ruby/user.rb +61 -0
- data/app/views/layouts/lcp_ruby/application.html.erb +168 -0
- data/app/views/layouts/lcp_ruby/auth.html.erb +170 -0
- data/app/views/lcp_ruby/auth/callbacks/failure.html.erb +18 -0
- data/app/views/lcp_ruby/auth/mailer/reset_password_instructions.html.erb +9 -0
- data/app/views/lcp_ruby/auth/passwords/edit.html.erb +34 -0
- data/app/views/lcp_ruby/auth/passwords/new.html.erb +24 -0
- data/app/views/lcp_ruby/auth/registrations/edit.html.erb +48 -0
- data/app/views/lcp_ruby/auth/registrations/new.html.erb +46 -0
- data/app/views/lcp_ruby/auth/sessions/new.html.erb +55 -0
- data/app/views/lcp_ruby/auth/shared/_links.html.erb +13 -0
- data/app/views/lcp_ruby/custom_fields/_manage_row.html.erb +82 -0
- data/app/views/lcp_ruby/custom_fields/manage.html.erb +47 -0
- data/app/views/lcp_ruby/dialogs/_dialog_composite_frame.html.erb +87 -0
- data/app/views/lcp_ruby/dialogs/_dialog_frame.html.erb +60 -0
- data/app/views/lcp_ruby/dialogs/_dialog_show_frame.html.erb +14 -0
- data/app/views/lcp_ruby/dialogs/_show_secret.html.erb +10 -0
- data/app/views/lcp_ruby/dialogs/_success.html.erb +1 -0
- data/app/views/lcp_ruby/errors/not_found.html.erb +5 -0
- data/app/views/lcp_ruby/menu_renderers/_user_menu.html.erb +51 -0
- data/app/views/lcp_ruby/menu_renderers/_user_menu_panel.html.erb +32 -0
- data/app/views/lcp_ruby/navigation/_auto_top.html.erb +16 -0
- data/app/views/lcp_ruby/navigation/_both_sidebar.html.erb +1 -0
- data/app/views/lcp_ruby/navigation/_both_top.html.erb +1 -0
- data/app/views/lcp_ruby/navigation/_impersonation_banner.html.erb +14 -0
- data/app/views/lcp_ruby/navigation/_item_content.html.erb +23 -0
- data/app/views/lcp_ruby/navigation/_link_or_button.html.erb +51 -0
- data/app/views/lcp_ruby/navigation/_mobile_header.html.erb +23 -0
- data/app/views/lcp_ruby/navigation/_panel_item.html.erb +32 -0
- data/app/views/lcp_ruby/navigation/_sidebar.html.erb +38 -0
- data/app/views/lcp_ruby/navigation/_sidebar_item.html.erb +38 -0
- data/app/views/lcp_ruby/navigation/_sidebar_toggle.html.erb +32 -0
- data/app/views/lcp_ruby/navigation/_top.html.erb +26 -0
- data/app/views/lcp_ruby/navigation/_top_item.html.erb +112 -0
- data/app/views/lcp_ruby/navigation/_widget_item.html.erb +14 -0
- data/app/views/lcp_ruby/resources/_action_button.html.erb +138 -0
- data/app/views/lcp_ruby/resources/_advanced_filter.html.erb +55 -0
- data/app/views/lcp_ruby/resources/_api_status_banner.html.erb +11 -0
- data/app/views/lcp_ruby/resources/_association_list.html.erb +132 -0
- data/app/views/lcp_ruby/resources/_audit_history.html.erb +66 -0
- data/app/views/lcp_ruby/resources/_batch_toolbar.html.erb +54 -0
- data/app/views/lcp_ruby/resources/_filter_form.html.erb +57 -0
- data/app/views/lcp_ruby/resources/_form.html.erb +73 -0
- data/app/views/lcp_ruby/resources/_form_action_button.html.erb +20 -0
- data/app/views/lcp_ruby/resources/_form_action_dropdown_item.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_form_actions.html.erb +38 -0
- data/app/views/lcp_ruby/resources/_form_section.html.erb +235 -0
- data/app/views/lcp_ruby/resources/_grid_page.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_grouped_index.html.erb +61 -0
- data/app/views/lcp_ruby/resources/_inline_create_form.html.erb +50 -0
- data/app/views/lcp_ruby/resources/_json_items_list.html.erb +77 -0
- data/app/views/lcp_ruby/resources/_json_nested_fields.html.erb +30 -0
- data/app/views/lcp_ruby/resources/_kanban_card.html.erb +31 -0
- data/app/views/lcp_ruby/resources/_kanban_card_body.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_kanban_column.html.erb +33 -0
- data/app/views/lcp_ruby/resources/_kanban_column_header.html.erb +10 -0
- data/app/views/lcp_ruby/resources/_kanban_index.html.erb +17 -0
- data/app/views/lcp_ruby/resources/_nested_field_cell.html.erb +33 -0
- data/app/views/lcp_ruby/resources/_nested_fields.html.erb +26 -0
- data/app/views/lcp_ruby/resources/_nested_row_content.html.erb +65 -0
- data/app/views/lcp_ruby/resources/_scope_filters.html.erb +71 -0
- data/app/views/lcp_ruby/resources/_semantic_index_page.html.erb +162 -0
- data/app/views/lcp_ruby/resources/_semantic_page.html.erb +121 -0
- data/app/views/lcp_ruby/resources/_show_sections.html.erb +128 -0
- data/app/views/lcp_ruby/resources/_table_index.html.erb +169 -0
- data/app/views/lcp_ruby/resources/_tile_card.html.erb +26 -0
- data/app/views/lcp_ruby/resources/_tile_card_body.html.erb +19 -0
- data/app/views/lcp_ruby/resources/_tiles_index.html.erb +15 -0
- data/app/views/lcp_ruby/resources/_transition_button.html.erb +33 -0
- data/app/views/lcp_ruby/resources/_tree_index.html.erb +61 -0
- data/app/views/lcp_ruby/resources/_view_switcher.html.erb +24 -0
- data/app/views/lcp_ruby/resources/edit.html.erb +9 -0
- data/app/views/lcp_ruby/resources/index.html.erb +80 -0
- data/app/views/lcp_ruby/resources/new.html.erb +9 -0
- data/app/views/lcp_ruby/resources/show.html.erb +37 -0
- data/app/views/lcp_ruby/shared/_breadcrumbs.html.erb +15 -0
- data/app/views/lcp_ruby/shared/_custom_partial_error.html.erb +3 -0
- data/app/views/lcp_ruby/shared/_flash_messages.html.erb +19 -0
- data/app/views/lcp_ruby/slots/index/_advanced_filter.html.erb +3 -0
- data/app/views/lcp_ruby/slots/index/_collection_actions.html.erb +50 -0
- data/app/views/lcp_ruby/slots/index/_manage_all.html.erb +4 -0
- data/app/views/lcp_ruby/slots/index/_pagination_footer.html.erb +71 -0
- data/app/views/lcp_ruby/slots/index/_predefined_filters.html.erb +8 -0
- data/app/views/lcp_ruby/slots/index/_saved_filters.html.erb +87 -0
- data/app/views/lcp_ruby/slots/index/_search.html.erb +52 -0
- data/app/views/lcp_ruby/slots/index/_search_parameter.html.erb +72 -0
- data/app/views/lcp_ruby/slots/index/_sort_dropdown.html.erb +21 -0
- data/app/views/lcp_ruby/slots/index/_summary_bar.html.erb +22 -0
- data/app/views/lcp_ruby/slots/index/_view_switcher.html.erb +1 -0
- data/app/views/lcp_ruby/slots/show/_approval_status.html.erb +8 -0
- data/app/views/lcp_ruby/slots/show/_back_to_list.html.erb +1 -0
- data/app/views/lcp_ruby/slots/show/_copy_url.html.erb +5 -0
- data/app/views/lcp_ruby/slots/show/_single_actions.html.erb +4 -0
- data/app/views/lcp_ruby/slots/show/_view_switcher.html.erb +1 -0
- data/app/views/lcp_ruby/widgets/_approval_status.html.erb +150 -0
- data/app/views/lcp_ruby/widgets/_chart.html.erb +36 -0
- data/app/views/lcp_ruby/widgets/_embed.html.erb +13 -0
- data/app/views/lcp_ruby/widgets/_kpi_card.html.erb +29 -0
- data/app/views/lcp_ruby/widgets/_list.html.erb +17 -0
- data/app/views/lcp_ruby/widgets/_presenter_zone.html.erb +84 -0
- data/app/views/lcp_ruby/widgets/_record_show_zone.html.erb +11 -0
- data/app/views/lcp_ruby/widgets/_text.html.erb +3 -0
- data/app/views/lcp_ruby/widgets/_workflow_graph.html.erb +32 -0
- data/app/views/lcp_ruby/zones/_custom_zone.html.erb +16 -0
- data/app/views/lcp_ruby/zones/_error.html.erb +5 -0
- data/app/views/lcp_ruby/zones/_zone_frame.html.erb +25 -0
- data/app/views/lcp_ruby/zones/_zone_search.html.erb +20 -0
- data/config/locales/cs.yml +859 -0
- data/config/locales/en.yml +731 -0
- data/config/routes.rb +119 -0
- data/docs/README.md +225 -0
- data/docs/architecture.md +212 -0
- data/docs/feature-catalog.md +763 -0
- data/docs/feature-catalog.yml +20911 -0
- data/docs/getting-started.md +1187 -0
- data/docs/guides/action-buttons.md +537 -0
- data/docs/guides/adding-locale.md +353 -0
- data/docs/guides/api-backed-models.md +478 -0
- data/docs/guides/attachments.md +399 -0
- data/docs/guides/auditing.md +333 -0
- data/docs/guides/batch-actions.md +342 -0
- data/docs/guides/composite-pages.md +1290 -0
- data/docs/guides/computed-fields.md +350 -0
- data/docs/guides/conditional-rendering.md +832 -0
- data/docs/guides/custom-actions.md +238 -0
- data/docs/guides/custom-fields.md +439 -0
- data/docs/guides/custom-renderers.md +234 -0
- data/docs/guides/custom-types.md +274 -0
- data/docs/guides/dashboards.md +504 -0
- data/docs/guides/debugging/README.md +38 -0
- data/docs/guides/debugging/controllers.md +147 -0
- data/docs/guides/debugging/data.md +165 -0
- data/docs/guides/debugging/metadata.md +143 -0
- data/docs/guides/debugging/models.md +126 -0
- data/docs/guides/debugging/permissions.md +147 -0
- data/docs/guides/debugging/presenters.md +151 -0
- data/docs/guides/developer-tools.md +418 -0
- data/docs/guides/dialogs.md +392 -0
- data/docs/guides/display-types.md +1430 -0
- data/docs/guides/eager-loading.md +230 -0
- data/docs/guides/event-handlers.md +135 -0
- data/docs/guides/export.md +305 -0
- data/docs/guides/extensibility.md +761 -0
- data/docs/guides/groups.md +220 -0
- data/docs/guides/hierarchical-authorization.md +427 -0
- data/docs/guides/host-application.md +556 -0
- data/docs/guides/host-controller-integration.md +473 -0
- data/docs/guides/impersonation.md +83 -0
- data/docs/guides/import.md +165 -0
- data/docs/guides/inherited-permissions.md +459 -0
- data/docs/guides/menu.md +373 -0
- data/docs/guides/monitoring.md +254 -0
- data/docs/guides/oidc-setup.md +399 -0
- data/docs/guides/permission-source.md +205 -0
- data/docs/guides/permissions.md +364 -0
- data/docs/guides/presenters.md +2324 -0
- data/docs/guides/record-aliases.md +303 -0
- data/docs/guides/rendering-extension-points.md +280 -0
- data/docs/guides/role-source.md +288 -0
- data/docs/guides/selectbox.md +516 -0
- data/docs/guides/sequences.md +291 -0
- data/docs/guides/soft-delete.md +460 -0
- data/docs/guides/theming.md +129 -0
- data/docs/guides/tiles.md +383 -0
- data/docs/guides/tree-structures.md +297 -0
- data/docs/guides/userstamps.md +288 -0
- data/docs/guides/view-groups.md +259 -0
- data/docs/guides/view-slots.md +352 -0
- data/docs/guides/virtual-columns.md +810 -0
- data/docs/guides/workflow.md +692 -0
- data/docs/reference/api-backed-models.md +404 -0
- data/docs/reference/api-tokens.md +128 -0
- data/docs/reference/auditing.md +277 -0
- data/docs/reference/boot_lifecycle.md +188 -0
- data/docs/reference/cascading_selects.md +189 -0
- data/docs/reference/condition-operators.md +445 -0
- data/docs/reference/custom-fields.md +483 -0
- data/docs/reference/dialogs.md +286 -0
- data/docs/reference/doctor.md +168 -0
- data/docs/reference/dynamic-references.md +95 -0
- data/docs/reference/eager-loading.md +192 -0
- data/docs/reference/engine-configuration.md +989 -0
- data/docs/reference/export.md +309 -0
- data/docs/reference/forms.md +68 -0
- data/docs/reference/groups.md +176 -0
- data/docs/reference/host-controller-integration.md +342 -0
- data/docs/reference/i18n.md +497 -0
- data/docs/reference/i18n_check.md +351 -0
- data/docs/reference/import.md +260 -0
- data/docs/reference/invariant_check.md +216 -0
- data/docs/reference/menu.md +985 -0
- data/docs/reference/model-dsl.md +1157 -0
- data/docs/reference/models.md +2972 -0
- data/docs/reference/monitoring.md +222 -0
- data/docs/reference/oidc-bearer.md +269 -0
- data/docs/reference/oidc.md +407 -0
- data/docs/reference/page_filters.md +328 -0
- data/docs/reference/pages.md +1375 -0
- data/docs/reference/permission-source.md +185 -0
- data/docs/reference/permissions.md +715 -0
- data/docs/reference/presenter-dsl.md +1719 -0
- data/docs/reference/presenters.md +3627 -0
- data/docs/reference/role-source.md +227 -0
- data/docs/reference/theme-variables.md +139 -0
- data/docs/reference/tree-structures.md +374 -0
- data/docs/reference/types.md +470 -0
- data/docs/reference/view-groups.md +347 -0
- data/docs/reference/view-slots.md +228 -0
- data/docs/reference/virtual_forms.md +196 -0
- data/docs/reference/workflow-approvals.md +387 -0
- data/docs/reference/workflow.md +651 -0
- data/examples/crm/Gemfile +9 -0
- data/examples/crm/Gemfile.lock +417 -0
- data/examples/crm/Rakefile +2 -0
- data/examples/crm/app/actions/activity/complete.rb +20 -0
- data/examples/crm/app/actions/deal/close_won.rb +20 -0
- data/examples/crm/app/assets/config/manifest.js +3 -0
- data/examples/crm/app/controllers/application_controller.rb +9 -0
- data/examples/crm/app/event_handlers/deal/on_stage_change.rb +17 -0
- data/examples/crm/app/lcp_services/computed/weighted_deal_value.rb +13 -0
- data/examples/crm/app/lcp_services/data_providers/active_contacts_count.rb +14 -0
- data/examples/crm/app/lcp_services/data_providers/open_deals_count.rb +14 -0
- data/examples/crm/app/lcp_services/data_providers/pending_activities_count.rb +15 -0
- data/examples/crm/app/lcp_services/data_providers/pipeline_value.rb +27 -0
- data/examples/crm/app/lcp_services/data_providers/won_deals_count.rb +14 -0
- data/examples/crm/app/lcp_services/defaults/thirty_days_out.rb +11 -0
- data/examples/crm/app/lcp_services/transforms/titlecase.rb +11 -0
- data/examples/crm/app/lcp_services/validators/deal_credit_limit.rb +19 -0
- data/examples/crm/app/lcp_services/validators/deal_documents_required.rb +17 -0
- data/examples/crm/app/renderers/conditional_badge.rb +39 -0
- data/examples/crm/bin/rails +4 -0
- data/examples/crm/bin/rake +4 -0
- data/examples/crm/config/application.rb +31 -0
- data/examples/crm/config/boot.rb +2 -0
- data/examples/crm/config/database.yml +12 -0
- data/examples/crm/config/environment.rb +2 -0
- data/examples/crm/config/initializers/lcp_ruby.rb +45 -0
- data/examples/crm/config/lcp_ruby/menu.yml +53 -0
- data/examples/crm/config/lcp_ruby/models/activity.rb +43 -0
- data/examples/crm/config/lcp_ruby/models/city.rb +19 -0
- data/examples/crm/config/lcp_ruby/models/company.rb +65 -0
- data/examples/crm/config/lcp_ruby/models/contact.rb +62 -0
- data/examples/crm/config/lcp_ruby/models/country.rb +22 -0
- data/examples/crm/config/lcp_ruby/models/custom_field_definition.rb +60 -0
- data/examples/crm/config/lcp_ruby/models/deal.rb +85 -0
- data/examples/crm/config/lcp_ruby/models/deal_category.rb +15 -0
- data/examples/crm/config/lcp_ruby/models/gapfree_sequence.rb +17 -0
- data/examples/crm/config/lcp_ruby/models/region.rb +15 -0
- data/examples/crm/config/lcp_ruby/models/saved_filter.rb +50 -0
- data/examples/crm/config/lcp_ruby/pages/activity_quick_log.yml +19 -0
- data/examples/crm/config/lcp_ruby/pages/company_detail.yml +127 -0
- data/examples/crm/config/lcp_ruby/pages/deals_overview.yml +65 -0
- data/examples/crm/config/lcp_ruby/permissions/activity.yml +40 -0
- data/examples/crm/config/lcp_ruby/permissions/custom_field_definition.yml +16 -0
- data/examples/crm/config/lcp_ruby/permissions/deal.yml +54 -0
- data/examples/crm/config/lcp_ruby/permissions/default.yml +16 -0
- data/examples/crm/config/lcp_ruby/permissions/gapfree_sequence.yml +6 -0
- data/examples/crm/config/lcp_ruby/permissions/saved_filter.yml +27 -0
- data/examples/crm/config/lcp_ruby/presenters/activity.rb +140 -0
- data/examples/crm/config/lcp_ruby/presenters/activity_quick_form.rb +36 -0
- data/examples/crm/config/lcp_ruby/presenters/activity_short.rb +16 -0
- data/examples/crm/config/lcp_ruby/presenters/activity_tiles.rb +35 -0
- data/examples/crm/config/lcp_ruby/presenters/city.rb +53 -0
- data/examples/crm/config/lcp_ruby/presenters/company.rb +147 -0
- data/examples/crm/config/lcp_ruby/presenters/company_activities_zone.rb +26 -0
- data/examples/crm/config/lcp_ruby/presenters/company_archive.rb +37 -0
- data/examples/crm/config/lcp_ruby/presenters/company_contacts_zone.rb +22 -0
- data/examples/crm/config/lcp_ruby/presenters/company_deals_zone.rb +36 -0
- data/examples/crm/config/lcp_ruby/presenters/company_short.rb +21 -0
- data/examples/crm/config/lcp_ruby/presenters/company_show_zone.rb +38 -0
- data/examples/crm/config/lcp_ruby/presenters/company_sidebar.rb +15 -0
- data/examples/crm/config/lcp_ruby/presenters/company_tiles.rb +35 -0
- data/examples/crm/config/lcp_ruby/presenters/contact.rb +120 -0
- data/examples/crm/config/lcp_ruby/presenters/contact_quick_form.rb +17 -0
- data/examples/crm/config/lcp_ruby/presenters/contact_short.rb +20 -0
- data/examples/crm/config/lcp_ruby/presenters/contact_tiles.rb +34 -0
- data/examples/crm/config/lcp_ruby/presenters/country.rb +44 -0
- data/examples/crm/config/lcp_ruby/presenters/custom_fields.rb +124 -0
- data/examples/crm/config/lcp_ruby/presenters/deal.rb +181 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_category.rb +46 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_overview.rb +6 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_pipeline.rb +18 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_short.rb +25 -0
- data/examples/crm/config/lcp_ruby/presenters/deal_tiles.rb +48 -0
- data/examples/crm/config/lcp_ruby/presenters/region.rb +42 -0
- data/examples/crm/config/lcp_ruby/presenters/save_filter_dialog.rb +17 -0
- data/examples/crm/config/lcp_ruby/presenters/saved_filters.rb +93 -0
- data/examples/crm/config/lcp_ruby/views/activities.yml +16 -0
- data/examples/crm/config/lcp_ruby/views/cities.yml +10 -0
- data/examples/crm/config/lcp_ruby/views/companies.yml +14 -0
- data/examples/crm/config/lcp_ruby/views/contacts.yml +16 -0
- data/examples/crm/config/lcp_ruby/views/countries.yml +8 -0
- data/examples/crm/config/lcp_ruby/views/custom_fields.rb +9 -0
- data/examples/crm/config/lcp_ruby/views/deal_categories.yml +8 -0
- data/examples/crm/config/lcp_ruby/views/deals.yml +19 -0
- data/examples/crm/config/lcp_ruby/views/pipeline.yml +10 -0
- data/examples/crm/config/lcp_ruby/views/regions.yml +10 -0
- data/examples/crm/config/lcp_ruby/views/saved_filters.yml +7 -0
- data/examples/crm/config/locales/cs.yml +338 -0
- data/examples/crm/config/locales/en.yml +353 -0
- data/examples/crm/config/routes.rb +4 -0
- data/examples/crm/config/storage.yml +3 -0
- data/examples/crm/config.ru +2 -0
- data/examples/crm/db/migrate/20260219104942_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/crm/db/schema.rb +245 -0
- data/examples/crm/db/seeds.rb +1111 -0
- data/examples/crm/erd.md +163 -0
- data/examples/hr/Gemfile +9 -0
- data/examples/hr/Gemfile.lock +419 -0
- data/examples/hr/Rakefile +6 -0
- data/examples/hr/app/actions/asset/assign_asset.rb +20 -0
- data/examples/hr/app/actions/asset/return_asset.rb +20 -0
- data/examples/hr/app/actions/candidate/advance.rb +32 -0
- data/examples/hr/app/actions/candidate/hire.rb +20 -0
- data/examples/hr/app/actions/candidate/reject_candidate.rb +20 -0
- data/examples/hr/app/actions/expense_claim/approve.rb +21 -0
- data/examples/hr/app/actions/expense_claim/reject.rb +21 -0
- data/examples/hr/app/actions/expense_claim/submit.rb +20 -0
- data/examples/hr/app/actions/interview/complete_interview.rb +20 -0
- data/examples/hr/app/actions/leave_request/approve.rb +21 -0
- data/examples/hr/app/actions/leave_request/cancel.rb +20 -0
- data/examples/hr/app/actions/leave_request/reject.rb +21 -0
- data/examples/hr/app/assets/config/manifest.js +1 -0
- data/examples/hr/app/assets/stylesheets/application.css +10 -0
- data/examples/hr/app/condition_services/is_own_org_unit.rb +14 -0
- data/examples/hr/app/condition_services/is_own_record.rb +20 -0
- data/examples/hr/app/controllers/application_controller.rb +15 -0
- data/examples/hr/app/event_handlers/asset_assignment/on_create.rb +24 -0
- data/examples/hr/app/event_handlers/candidate/on_status_change.rb +18 -0
- data/examples/hr/app/event_handlers/leave_request/on_status_change.rb +45 -0
- data/examples/hr/app/helpers/application_helper.rb +2 -0
- data/examples/hr/app/javascript/application.js +1 -0
- data/examples/hr/app/jobs/application_job.rb +7 -0
- data/examples/hr/app/lcp_services/computed/employee_tenure.rb +28 -0
- data/examples/hr/app/lcp_services/computed/leave_remaining.rb +13 -0
- data/examples/hr/app/lcp_services/data_providers/headcount_text.rb +14 -0
- data/examples/hr/app/lcp_services/data_providers/open_positions_count.rb +14 -0
- data/examples/hr/app/lcp_services/data_providers/pending_expenses_count.rb +14 -0
- data/examples/hr/app/lcp_services/data_providers/pending_leaves_count.rb +14 -0
- data/examples/hr/app/lcp_services/defaults/current_year.rb +11 -0
- data/examples/hr/app/lcp_services/transforms/titlecase.rb +11 -0
- data/examples/hr/app/lcp_services/validators/expense_receipt_required.rb +17 -0
- data/examples/hr/app/lcp_services/validators/leave_balance_check.rb +37 -0
- data/examples/hr/app/models/application_record.rb +3 -0
- data/examples/hr/app/views/layouts/application.html.erb +29 -0
- data/examples/hr/app/views/pwa/manifest.json.erb +22 -0
- data/examples/hr/app/views/pwa/service-worker.js +26 -0
- data/examples/hr/bin/brakeman +7 -0
- data/examples/hr/bin/bundler-audit +6 -0
- data/examples/hr/bin/ci +6 -0
- data/examples/hr/bin/dev +2 -0
- data/examples/hr/bin/docker-entrypoint +8 -0
- data/examples/hr/bin/importmap +4 -0
- data/examples/hr/bin/jobs +6 -0
- data/examples/hr/bin/kamal +27 -0
- data/examples/hr/bin/rails +4 -0
- data/examples/hr/bin/rake +4 -0
- data/examples/hr/bin/rubocop +8 -0
- data/examples/hr/bin/setup +35 -0
- data/examples/hr/bin/thrust +5 -0
- data/examples/hr/config/application.rb +31 -0
- data/examples/hr/config/boot.rb +2 -0
- data/examples/hr/config/bundler-audit.yml +5 -0
- data/examples/hr/config/cache.yml +16 -0
- data/examples/hr/config/ci.rb +20 -0
- data/examples/hr/config/credentials.yml.enc +1 -0
- data/examples/hr/config/database.yml +36 -0
- data/examples/hr/config/deploy.yml +119 -0
- data/examples/hr/config/environment.rb +5 -0
- data/examples/hr/config/environments/development.rb +66 -0
- data/examples/hr/config/environments/production.rb +74 -0
- data/examples/hr/config/environments/test.rb +45 -0
- data/examples/hr/config/importmap.rb +3 -0
- data/examples/hr/config/initializers/assets.rb +7 -0
- data/examples/hr/config/initializers/content_security_policy.rb +29 -0
- data/examples/hr/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/hr/config/initializers/inflections.rb +16 -0
- data/examples/hr/config/initializers/lcp_ruby.rb +18 -0
- data/examples/hr/config/lcp_ruby/menu.yml +86 -0
- data/examples/hr/config/lcp_ruby/models/announcement.rb +33 -0
- data/examples/hr/config/lcp_ruby/models/asset.rb +73 -0
- data/examples/hr/config/lcp_ruby/models/asset_assignment.rb +39 -0
- data/examples/hr/config/lcp_ruby/models/audit_log.yml +57 -0
- data/examples/hr/config/lcp_ruby/models/candidate.rb +68 -0
- data/examples/hr/config/lcp_ruby/models/custom_field_definition.rb +60 -0
- data/examples/hr/config/lcp_ruby/models/dashboard.rb +17 -0
- data/examples/hr/config/lcp_ruby/models/document.rb +38 -0
- data/examples/hr/config/lcp_ruby/models/employee.rb +128 -0
- data/examples/hr/config/lcp_ruby/models/employee_skill.rb +29 -0
- data/examples/hr/config/lcp_ruby/models/expense_claim.rb +70 -0
- data/examples/hr/config/lcp_ruby/models/goal.rb +48 -0
- data/examples/hr/config/lcp_ruby/models/group.rb +37 -0
- data/examples/hr/config/lcp_ruby/models/group_membership.rb +26 -0
- data/examples/hr/config/lcp_ruby/models/interview.rb +54 -0
- data/examples/hr/config/lcp_ruby/models/job_posting.rb +67 -0
- data/examples/hr/config/lcp_ruby/models/leave_balance.rb +31 -0
- data/examples/hr/config/lcp_ruby/models/leave_request.rb +52 -0
- data/examples/hr/config/lcp_ruby/models/leave_type.rb +35 -0
- data/examples/hr/config/lcp_ruby/models/organization_unit.rb +42 -0
- data/examples/hr/config/lcp_ruby/models/performance_review.rb +59 -0
- data/examples/hr/config/lcp_ruby/models/position.rb +43 -0
- data/examples/hr/config/lcp_ruby/models/skill.rb +27 -0
- data/examples/hr/config/lcp_ruby/models/training_course.rb +53 -0
- data/examples/hr/config/lcp_ruby/models/training_enrollment.rb +35 -0
- data/examples/hr/config/lcp_ruby/pages/dashboard.yml +101 -0
- data/examples/hr/config/lcp_ruby/permissions/announcement.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/asset.yml +35 -0
- data/examples/hr/config/lcp_ruby/permissions/audit_log.yml +28 -0
- data/examples/hr/config/lcp_ruby/permissions/candidate.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/custom_field_definition.yml +28 -0
- data/examples/hr/config/lcp_ruby/permissions/dashboard.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/default.yml +25 -0
- data/examples/hr/config/lcp_ruby/permissions/document.yml +37 -0
- data/examples/hr/config/lcp_ruby/permissions/employee.yml +55 -0
- data/examples/hr/config/lcp_ruby/permissions/expense_claim.yml +45 -0
- data/examples/hr/config/lcp_ruby/permissions/group.yml +27 -0
- data/examples/hr/config/lcp_ruby/permissions/job_posting.yml +34 -0
- data/examples/hr/config/lcp_ruby/permissions/leave_request.yml +45 -0
- data/examples/hr/config/lcp_ruby/permissions/performance_review.yml +42 -0
- data/examples/hr/config/lcp_ruby/presenters/announcement.rb +47 -0
- data/examples/hr/config/lcp_ruby/presenters/asset.rb +69 -0
- data/examples/hr/config/lcp_ruby/presenters/asset_assignment.rb +47 -0
- data/examples/hr/config/lcp_ruby/presenters/audit_logs.yml +43 -0
- data/examples/hr/config/lcp_ruby/presenters/candidate.rb +71 -0
- data/examples/hr/config/lcp_ruby/presenters/custom_fields.rb +124 -0
- data/examples/hr/config/lcp_ruby/presenters/dashboard.rb +37 -0
- data/examples/hr/config/lcp_ruby/presenters/document.rb +46 -0
- data/examples/hr/config/lcp_ruby/presenters/employee.rb +167 -0
- data/examples/hr/config/lcp_ruby/presenters/employee_archive.rb +38 -0
- data/examples/hr/config/lcp_ruby/presenters/employee_directory.rb +27 -0
- data/examples/hr/config/lcp_ruby/presenters/employee_skill.rb +57 -0
- data/examples/hr/config/lcp_ruby/presenters/expense_claim.rb +76 -0
- data/examples/hr/config/lcp_ruby/presenters/goal.rb +60 -0
- data/examples/hr/config/lcp_ruby/presenters/group.rb +48 -0
- data/examples/hr/config/lcp_ruby/presenters/interview.rb +59 -0
- data/examples/hr/config/lcp_ruby/presenters/job_posting.rb +73 -0
- data/examples/hr/config/lcp_ruby/presenters/leave_balance.rb +50 -0
- data/examples/hr/config/lcp_ruby/presenters/leave_request.rb +89 -0
- data/examples/hr/config/lcp_ruby/presenters/leave_type.rb +52 -0
- data/examples/hr/config/lcp_ruby/presenters/organization_unit.rb +56 -0
- data/examples/hr/config/lcp_ruby/presenters/performance_review.rb +87 -0
- data/examples/hr/config/lcp_ruby/presenters/position.rb +54 -0
- data/examples/hr/config/lcp_ruby/presenters/skill.rb +45 -0
- data/examples/hr/config/lcp_ruby/presenters/training_course.rb +61 -0
- data/examples/hr/config/lcp_ruby/presenters/training_enrollment.rb +49 -0
- data/examples/hr/config/lcp_ruby/views/announcements.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/asset_assignments.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/assets.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/audit_logs.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/candidates.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/custom_fields.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/dashboard.yml +6 -0
- data/examples/hr/config/lcp_ruby/views/documents.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/employee_skills.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/employees.yml +14 -0
- data/examples/hr/config/lcp_ruby/views/expense_claims.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/goals.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/groups.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/interviews.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/job_postings.yml +6 -0
- data/examples/hr/config/lcp_ruby/views/leave_balances.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/leave_requests.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/leave_types.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/organization_units.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/performance_reviews.yml +10 -0
- data/examples/hr/config/lcp_ruby/views/positions.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/skills.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/training_courses.yml +8 -0
- data/examples/hr/config/lcp_ruby/views/training_enrollments.yml +10 -0
- data/examples/hr/config/locales/cs.yml +496 -0
- data/examples/hr/config/locales/en.yml +740 -0
- data/examples/hr/config/locales/sk.yml +496 -0
- data/examples/hr/config/puma.rb +42 -0
- data/examples/hr/config/queue.yml +18 -0
- data/examples/hr/config/recurring.yml +15 -0
- data/examples/hr/config/routes.rb +4 -0
- data/examples/hr/config/storage.yml +27 -0
- data/examples/hr/config.ru +6 -0
- data/examples/hr/db/cache_schema.rb +12 -0
- data/examples/hr/db/migrate/20260303202825_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/hr/db/queue_schema.rb +129 -0
- data/examples/hr/db/schema.rb +588 -0
- data/examples/hr/db/seeds.rb +932 -0
- data/examples/hr/erd.md +396 -0
- data/examples/hr/public/400.html +135 -0
- data/examples/hr/public/404.html +135 -0
- data/examples/hr/public/406-unsupported-browser.html +135 -0
- data/examples/hr/public/422.html +135 -0
- data/examples/hr/public/500.html +135 -0
- data/examples/hr/public/icon.svg +3 -0
- data/examples/hr/public/robots.txt +1 -0
- data/examples/showcase/Gemfile +15 -0
- data/examples/showcase/Gemfile.lock +425 -0
- data/examples/showcase/Rakefile +2 -0
- data/examples/showcase/app/actions/showcase_batch_task/assign_batch.rb +20 -0
- data/examples/showcase/app/actions/showcase_batch_task/close_task.rb +21 -0
- data/examples/showcase/app/actions/showcase_condition/approve.rb +20 -0
- data/examples/showcase/app/actions/showcase_permission/lock.rb +20 -0
- data/examples/showcase/app/assets/config/manifest.js +3 -0
- data/examples/showcase/app/assets/stylesheets/application.css +27 -0
- data/examples/showcase/app/condition_services/budget_threshold.rb +16 -0
- data/examples/showcase/app/condition_services/overdue_check.rb +11 -0
- data/examples/showcase/app/controllers/application_controller.rb +2 -0
- data/examples/showcase/app/controllers/docs_controller.rb +48 -0
- data/examples/showcase/app/controllers/host_inventory_items_managed_controller.rb +90 -0
- data/examples/showcase/app/controllers/host_inventory_items_report_controller.rb +39 -0
- data/examples/showcase/app/controllers/host_inventory_items_wizard_controller.rb +50 -0
- data/examples/showcase/app/data_providers/showcase_amount_provider.rb +52 -0
- data/examples/showcase/app/data_providers/weather_station_provider.rb +140 -0
- data/examples/showcase/app/event_handlers/showcase_model/on_status_change.rb +17 -0
- data/examples/showcase/app/event_handlers/showcase_permission/on_status_change.rb +17 -0
- data/examples/showcase/app/event_handlers/showcase_workflow/log_review_exit.rb +16 -0
- data/examples/showcase/app/event_handlers/showcase_workflow/notify_reviewers.rb +15 -0
- data/examples/showcase/app/event_handlers/showcase_workflow/request_submitted.rb +15 -0
- data/examples/showcase/app/lcp_metrics/showcase_metrics.rb +31 -0
- data/examples/showcase/app/lcp_services/computed/showcase_score.rb +18 -0
- data/examples/showcase/app/lcp_services/computed/showcase_total.rb +13 -0
- data/examples/showcase/app/lcp_services/defaults/one_week_from_now.rb +11 -0
- data/examples/showcase/app/lcp_services/menu_items/recent_announcements.rb +36 -0
- data/examples/showcase/app/lcp_services/virtual_columns/project_health.rb +26 -0
- data/examples/showcase/app/model_extensions/lcp_error_log_extension.rb +12 -0
- data/examples/showcase/app/models/host_inventory_item.rb +20 -0
- data/examples/showcase/app/models/platform_profile.rb +27 -0
- data/examples/showcase/app/models/platform_user.rb +5 -0
- data/examples/showcase/app/views/docs/show.html.erb +19 -0
- data/examples/showcase/app/views/host_inventory_items_report/index.html.erb +61 -0
- data/examples/showcase/app/views/host_inventory_items_report/show.html.erb +39 -0
- data/examples/showcase/app/views/layouts/docs.html.erb +46 -0
- data/examples/showcase/app/views/showcase/menu_renderers/_status_pill.html.erb +17 -0
- data/examples/showcase/app/views/showcase_custom/_activity_timeline.html.erb +37 -0
- data/examples/showcase/app/views/showcase_custom/_card_index.html.erb +74 -0
- data/examples/showcase/app/views/showcase_custom/_detail_show.html.erb +115 -0
- data/examples/showcase/app/views/showcase_custom/_location_map.html.erb +29 -0
- data/examples/showcase/app/views/showcase_custom/_location_view.html.erb +34 -0
- data/examples/showcase/app/views/showcase_custom/_quick_stats.html.erb +50 -0
- data/examples/showcase/app/views/showcase_custom/_stats_sidebar.html.erb +42 -0
- data/examples/showcase/app/views/showcase_custom/_tags_editor.html.erb +48 -0
- data/examples/showcase/bin/rails +4 -0
- data/examples/showcase/bin/rake +4 -0
- data/examples/showcase/config/application.rb +37 -0
- data/examples/showcase/config/boot.rb +2 -0
- data/examples/showcase/config/database.yml +12 -0
- data/examples/showcase/config/environment.rb +2 -0
- data/examples/showcase/config/initializers/devise.rb +5 -0
- data/examples/showcase/config/initializers/lcp_ruby.rb +175 -0
- data/examples/showcase/config/lcp_ruby/auth.yml +60 -0
- data/examples/showcase/config/lcp_ruby/jobs/data_import.yml +7 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_cleanup.yml +11 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_event_triggered.yml +11 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_multi_step.yml +9 -0
- data/examples/showcase/config/lcp_ruby/jobs/showcase_webhook.yml +13 -0
- data/examples/showcase/config/lcp_ruby/menu.yml +249 -0
- data/examples/showcase/config/lcp_ruby/models/_base_document.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/_categorized_document.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/_contactable.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/api_token.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/article.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/article_tag.rb +10 -0
- data/examples/showcase/config/lcp_ruby/models/author.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/batch_operation.yml +79 -0
- data/examples/showcase/config/lcp_ruby/models/batch_operation_item.yml +45 -0
- data/examples/showcase/config/lcp_ruby/models/category.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/comment.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/custom_field_definition.rb +59 -0
- data/examples/showcase/config/lcp_ruby/models/department.rb +32 -0
- data/examples/showcase/config/lcp_ruby/models/employee.rb +52 -0
- data/examples/showcase/config/lcp_ruby/models/employee_emergency_contact.rb +24 -0
- data/examples/showcase/config/lcp_ruby/models/employee_profile.rb +18 -0
- data/examples/showcase/config/lcp_ruby/models/employee_skill.rb +10 -0
- data/examples/showcase/config/lcp_ruby/models/export_log.yml +27 -0
- data/examples/showcase/config/lcp_ruby/models/export_profile.yml +37 -0
- data/examples/showcase/config/lcp_ruby/models/feature.rb +76 -0
- data/examples/showcase/config/lcp_ruby/models/gapfree_sequence.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/group.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/group_membership.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/group_role_mapping.rb +14 -0
- data/examples/showcase/config/lcp_ruby/models/host_inventory_item.yml +111 -0
- data/examples/showcase/config/lcp_ruby/models/import_profile.rb +30 -0
- data/examples/showcase/config/lcp_ruby/models/import_row.rb +32 -0
- data/examples/showcase/config/lcp_ruby/models/ingredient_def.rb +11 -0
- data/examples/showcase/config/lcp_ruby/models/lcp_error_log.yml +61 -0
- data/examples/showcase/config/lcp_ruby/models/page_config.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/permission_config.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/pipeline.rb +15 -0
- data/examples/showcase/config/lcp_ruby/models/pipeline_stage.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/platform_profile.rb +104 -0
- data/examples/showcase/config/lcp_ruby/models/profile_setting.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/profile_tag.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/project.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/role.rb +24 -0
- data/examples/showcase/config/lcp_ruby/models/saved_filter.rb +50 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_aggregate.rb +93 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_aggregate_company.rb +14 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_aggregate_item.rb +25 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_announcement.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_array.rb +45 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_attachment.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_audit_log.yml +44 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_audited_record.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_batch_task.rb +27 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_business_unit.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition.rb +24 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition_category.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition_task.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_condition_threshold.rb +13 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_contact.rb +22 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_custom_render.rb +38 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_delete_reason.rb +11 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_division.rb +31 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_extensibility.rb +25 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_field.rb +53 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_form.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_form_action.rb +38 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_grade.rb +18 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_hr_employee.rb +90 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_item_class.rb +31 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_job_execution.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_memo.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_model.rb +74 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_organization.rb +31 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_permission.rb +30 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_person.rb +23 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_positioning.rb +19 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_quick_note.rb +13 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_recipe.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_report.rb +32 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_school_class.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_search.rb +84 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_sequence.rb +46 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_soft_delete.rb +30 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_soft_delete_item.rb +21 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_student.rb +17 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_type_default.rb +49 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_userstamps.rb +26 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_virtual_field.rb +68 -0
- data/examples/showcase/config/lcp_ruby/models/showcase_workflow.rb +54 -0
- data/examples/showcase/config/lcp_ruby/models/skill.rb +22 -0
- data/examples/showcase/config/lcp_ruby/models/tag.rb +16 -0
- data/examples/showcase/config/lcp_ruby/models/user.rb +54 -0
- data/examples/showcase/config/lcp_ruby/models/weather_station.rb +20 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_approval_request.yml +77 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_approval_step.yml +56 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_approval_task.yml +51 -0
- data/examples/showcase/config/lcp_ruby/models/workflow_audit_log.yml +74 -0
- data/examples/showcase/config/lcp_ruby/pages/article_detail.yml +32 -0
- data/examples/showcase/config/lcp_ruby/pages/author_detail.yml +27 -0
- data/examples/showcase/config/lcp_ruby/pages/category_detail.yml +24 -0
- data/examples/showcase/config/lcp_ruby/pages/chart_showcase.yml +151 -0
- data/examples/showcase/config/lcp_ruby/pages/department_detail.yml +55 -0
- data/examples/showcase/config/lcp_ruby/pages/department_explorer.yml +60 -0
- data/examples/showcase/config/lcp_ruby/pages/employee_overview.yml +106 -0
- data/examples/showcase/config/lcp_ruby/pages/employee_transfer_dialog.yml +24 -0
- data/examples/showcase/config/lcp_ruby/pages/hr_turnover_dashboard.yml +288 -0
- data/examples/showcase/config/lcp_ruby/pages/main_dashboard.yml +142 -0
- data/examples/showcase/config/lcp_ruby/pages/monitoring_dashboard.yml +58 -0
- data/examples/showcase/config/lcp_ruby/pages/pipeline_detail.yml +16 -0
- data/examples/showcase/config/lcp_ruby/pages/showcase_custom_zones.yml +39 -0
- data/examples/showcase/config/lcp_ruby/pages/showcase_form_action_dialog.yml +11 -0
- data/examples/showcase/config/lcp_ruby/pages/workflow_request_detail.yml +34 -0
- data/examples/showcase/config/lcp_ruby/permissions/api_token.yml +26 -0
- data/examples/showcase/config/lcp_ruby/permissions/batch_operation.yml +36 -0
- data/examples/showcase/config/lcp_ruby/permissions/custom_field_definition.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/default.yml +28 -0
- data/examples/showcase/config/lcp_ruby/permissions/export_log.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/export_profile.yml +25 -0
- data/examples/showcase/config/lcp_ruby/permissions/gapfree_sequence.yml +6 -0
- data/examples/showcase/config/lcp_ruby/permissions/group.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/group_membership.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/group_role_mapping.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/host_inventory_item.yml +34 -0
- data/examples/showcase/config/lcp_ruby/permissions/import_profile.yml +29 -0
- data/examples/showcase/config/lcp_ruby/permissions/import_row.yml +17 -0
- data/examples/showcase/config/lcp_ruby/permissions/lcp_error_log.yml +8 -0
- data/examples/showcase/config/lcp_ruby/permissions/page_config.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/permission_config.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/platform_profile.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/profile_setting.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/profile_tag.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/role.yml +20 -0
- data/examples/showcase/config/lcp_ruby/permissions/saved_filter.yml +39 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_announcement.yml +22 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_audit_log.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_audited_record.yml +15 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_batch_task.yml +31 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_condition.yml +54 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_contact.yml +21 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_custom_render.yml +21 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_delete_reason.yml +12 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_form_action.yml +26 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_grade.yml +33 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_job_execution.yml +23 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_permission.yml +47 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_quick_note.yml +12 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_school_class.yml +37 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_student.yml +43 -0
- data/examples/showcase/config/lcp_ruby/permissions/showcase_workflow.yml +34 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_request.yml +18 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_step.yml +18 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_approval_task.yml +18 -0
- data/examples/showcase/config/lcp_ruby/permissions/workflow_audit_log.yml +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/announcements.rb +59 -0
- data/examples/showcase/config/lcp_ruby/presenters/approval_requests.rb +69 -0
- data/examples/showcase/config/lcp_ruby/presenters/approval_steps.rb +59 -0
- data/examples/showcase/config/lcp_ruby/presenters/approval_tasks.rb +65 -0
- data/examples/showcase/config/lcp_ruby/presenters/article_comments_zone.rb +12 -0
- data/examples/showcase/config/lcp_ruby/presenters/article_related_zone.rb +15 -0
- data/examples/showcase/config/lcp_ruby/presenters/articles.rb +149 -0
- data/examples/showcase/config/lcp_ruby/presenters/articles_tiles.rb +30 -0
- data/examples/showcase/config/lcp_ruby/presenters/author_articles_zone.rb +12 -0
- data/examples/showcase/config/lcp_ruby/presenters/author_show_zone.rb +12 -0
- data/examples/showcase/config/lcp_ruby/presenters/authors.rb +39 -0
- data/examples/showcase/config/lcp_ruby/presenters/batch_operation_items.yml +45 -0
- data/examples/showcase/config/lcp_ruby/presenters/batch_operations.yml +66 -0
- data/examples/showcase/config/lcp_ruby/presenters/categories.rb +50 -0
- data/examples/showcase/config/lcp_ruby/presenters/category_articles_zone.rb +20 -0
- data/examples/showcase/config/lcp_ruby/presenters/category_children_zone.rb +10 -0
- data/examples/showcase/config/lcp_ruby/presenters/comment_quick_add_dialog.rb +15 -0
- data/examples/showcase/config/lcp_ruby/presenters/custom_fields.rb +124 -0
- data/examples/showcase/config/lcp_ruby/presenters/dashboard_employees.rb +16 -0
- data/examples/showcase/config/lcp_ruby/presenters/delete_reason_dialog.rb +13 -0
- data/examples/showcase/config/lcp_ruby/presenters/departments.rb +55 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_add_employee_dialog.rb +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_children_zone.rb +10 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_detail_zone.rb +14 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_employees_zone.rb +16 -0
- data/examples/showcase/config/lcp_ruby/presenters/dept_list_selection_zone.rb +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_overview_index_zone.rb +36 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_quick_add_dialog.rb +14 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_show_zone.rb +20 -0
- data/examples/showcase/config/lcp_ruby/presenters/employee_transfer_form_zone.rb +19 -0
- data/examples/showcase/config/lcp_ruby/presenters/employees.rb +165 -0
- data/examples/showcase/config/lcp_ruby/presenters/employees_tiles.rb +33 -0
- data/examples/showcase/config/lcp_ruby/presenters/export_logs.yml +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/export_profiles.yml +70 -0
- data/examples/showcase/config/lcp_ruby/presenters/extensibility_quick_edit_dialog.rb +13 -0
- data/examples/showcase/config/lcp_ruby/presenters/feature_kanban.rb +30 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_card.rb +179 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_hub.rb +44 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_table.rb +37 -0
- data/examples/showcase/config/lcp_ruby/presenters/features_tiles.rb +48 -0
- data/examples/showcase/config/lcp_ruby/presenters/group_memberships.rb +54 -0
- data/examples/showcase/config/lcp_ruby/presenters/group_role_mappings.rb +48 -0
- data/examples/showcase/config/lcp_ruby/presenters/groups.rb +74 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items.rb +99 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_managed.rb +84 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_report.rb +40 -0
- data/examples/showcase/config/lcp_ruby/presenters/host_inventory_items_wizard.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/import_profiles.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/import_rows.rb +39 -0
- data/examples/showcase/config/lcp_ruby/presenters/lcp_error_logs.yml +46 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_api_tokens.rb +35 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_api_tokens_create_dialog.rb +27 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_employee_profile.rb +24 -0
- data/examples/showcase/config/lcp_ruby/presenters/my_settings.rb +50 -0
- data/examples/showcase/config/lcp_ruby/presenters/page_configs.rb +56 -0
- data/examples/showcase/config/lcp_ruby/presenters/permission_configs.rb +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipeline_edit_zone.rb +11 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipeline_stages.rb +51 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipeline_stages_zone.rb +11 -0
- data/examples/showcase/config/lcp_ruby/presenters/pipelines.rb +40 -0
- data/examples/showcase/config/lcp_ruby/presenters/platform_profiles.rb +90 -0
- data/examples/showcase/config/lcp_ruby/presenters/projects.rb +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/quick_note_dialog.rb +14 -0
- data/examples/showcase/config/lcp_ruby/presenters/roles.rb +60 -0
- data/examples/showcase/config/lcp_ruby/presenters/save_filter_dialog.rb +17 -0
- data/examples/showcase/config/lcp_ruby/presenters/saved_filters.rb +94 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregate_items.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregates.rb +115 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_aggregates_tiles.rb +44 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_amount_kanban.rb +31 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_arrays.rb +140 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_attachments.rb +66 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_audit_logs.rb +46 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_audited_records.rb +58 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_batch_tasks.rb +97 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_batch_tasks_archive.rb +52 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_business_units.rb +43 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_conditions.rb +195 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_contacts.rb +82 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_render_with.rb +50 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_sections.rb +88 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_custom_zones_main.rb +75 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_divisions.rb +53 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_extensibility.rb +48 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_card.rb +34 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_table.rb +128 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_fields_tiles.rb +42 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_form_action_dialog.rb +27 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_form_actions.rb +132 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_form_actions_overflow.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_forms.rb +110 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_grades.rb +38 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_hr_employees.rb +84 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_item_classes.rb +120 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_job_executions.rb +150 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_memos.rb +96 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_models.rb +112 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_organizations.rb +106 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_people.rb +97 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_permissions.rb +84 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_positioning.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_recipes.rb +105 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_recipes_raw.rb +32 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_reports.rb +109 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_school_classes.rb +34 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_searches.rb +226 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_sequences.rb +67 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete.rb +88 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete_archive.rb +52 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_soft_delete_items.rb +47 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_students.rb +33 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_type_defaults.rb +92 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_userstamps.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_virtual_fields.rb +104 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_workflow_admin.rb +24 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_workflow_kanban.rb +36 -0
- data/examples/showcase/config/lcp_ruby/presenters/showcase_workflows.rb +103 -0
- data/examples/showcase/config/lcp_ruby/presenters/tags.rb +35 -0
- data/examples/showcase/config/lcp_ruby/presenters/users.rb +61 -0
- data/examples/showcase/config/lcp_ruby/presenters/weather_stations.rb +60 -0
- data/examples/showcase/config/lcp_ruby/presenters/workflow_audit_logs.rb +76 -0
- data/examples/showcase/config/lcp_ruby/presenters/workflow_request_audit_zone.rb +28 -0
- data/examples/showcase/config/lcp_ruby/theme.yml +2 -0
- data/examples/showcase/config/lcp_ruby/types/currency.yml +15 -0
- data/examples/showcase/config/lcp_ruby/types/percentage.yml +16 -0
- data/examples/showcase/config/lcp_ruby/types/rating.yml +20 -0
- data/examples/showcase/config/lcp_ruby/views/announcements.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/approval_requests.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/approval_steps.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/approval_tasks.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/articles.yml +12 -0
- data/examples/showcase/config/lcp_ruby/views/authors.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/batch_operation_items.yml +6 -0
- data/examples/showcase/config/lcp_ruby/views/batch_operations.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/categories.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/custom_fields.rb +8 -0
- data/examples/showcase/config/lcp_ruby/views/dashboard.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/department_explorer.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/departments.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/employee_overview.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/employees.yml +12 -0
- data/examples/showcase/config/lcp_ruby/views/export_logs.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/export_profiles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/features.yml +19 -0
- data/examples/showcase/config/lcp_ruby/views/group_memberships.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/group_role_mappings.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/groups.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/host_inventory_items.yml +16 -0
- data/examples/showcase/config/lcp_ruby/views/hr_turnover_dashboard.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/import_profiles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/import_rows.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/lcp_error_logs.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/monitoring.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/my_api_tokens.rb +9 -0
- data/examples/showcase/config/lcp_ruby/views/page_configs.yml +11 -0
- data/examples/showcase/config/lcp_ruby/views/permission_configs.yml +11 -0
- data/examples/showcase/config/lcp_ruby/views/pipeline_stages.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/pipelines.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/platform_profiles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/projects.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/roles.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/saved_filters.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_aggregate_items.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_aggregates.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_arrays.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_attachments.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_audit_logs.yml +11 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_audited_records.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_batch_tasks.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_business_units.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_conditions.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_contacts.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_custom_render_with.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_custom_sections.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_custom_zones.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_divisions.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_extensibility.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_fields.yml +13 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_form_actions.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_forms.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_grades.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_hr_employees.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_item_classes.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_job_executions.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_memos.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_models.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_organizations.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_people.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_permissions.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_positioning.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_recipes.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_reports.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_school_classes.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_searches.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_sequences.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_soft_delete.yml +10 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_soft_delete_items.yml +8 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_students.yml +9 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_userstamps.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_virtual_fields.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/showcase_workflows.yml +16 -0
- data/examples/showcase/config/lcp_ruby/views/tags.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/users.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/weather_stations.yml +7 -0
- data/examples/showcase/config/lcp_ruby/views/workflow_audit_logs.yml +9 -0
- data/examples/showcase/config/lcp_ruby/workflows/showcase_form_action.rb +48 -0
- data/examples/showcase/config/lcp_ruby/workflows/showcase_workflow.rb +199 -0
- data/examples/showcase/config/locales/cs.yml +2818 -0
- data/examples/showcase/config/locales/en.yml +67 -0
- data/examples/showcase/config/locales/lcp_ruby/api_tokens.cs.yml +46 -0
- data/examples/showcase/config/locales/lcp_ruby/api_tokens.en.yml +49 -0
- data/examples/showcase/config/routes.rb +21 -0
- data/examples/showcase/config/storage.yml +3 -0
- data/examples/showcase/config.ru +2 -0
- data/examples/showcase/db/migrate/20260219124321_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/showcase/db/migrate/20260220072723_create_lcp_ruby_users.rb +42 -0
- data/examples/showcase/db/migrate/20260406120000_create_host_inventory_items.rb +32 -0
- data/examples/showcase/db/migrate/20260428134542_add_oidc_columns_to_lcp_ruby_users.rb +13 -0
- data/examples/showcase/db/migrate/20260502120000_create_platform_profiles.rb +19 -0
- data/examples/showcase/db/schema.rb +1222 -0
- data/examples/showcase/db/seeds.rb +3085 -0
- data/examples/showcase/erd.md +567 -0
- data/examples/showcase/test/fixtures/import_articles.csv +4 -0
- data/examples/showcase/test/fixtures/import_employees.csv +4 -0
- data/examples/todo/Gemfile +8 -0
- data/examples/todo/Gemfile.lock +415 -0
- data/examples/todo/Rakefile +2 -0
- data/examples/todo/app/assets/config/manifest.js +1 -0
- data/examples/todo/app/controllers/application_controller.rb +6 -0
- data/examples/todo/app/lcp_services/defaults/one_week_from_now.rb +11 -0
- data/examples/todo/bin/rails +4 -0
- data/examples/todo/bin/rake +4 -0
- data/examples/todo/config/application.rb +31 -0
- data/examples/todo/config/boot.rb +2 -0
- data/examples/todo/config/database.yml +12 -0
- data/examples/todo/config/environment.rb +2 -0
- data/examples/todo/config/lcp_ruby/models/todo_item.yml +67 -0
- data/examples/todo/config/lcp_ruby/models/todo_list.yml +49 -0
- data/examples/todo/config/lcp_ruby/permissions/default.yml +10 -0
- data/examples/todo/config/lcp_ruby/permissions/todo_item.yml +21 -0
- data/examples/todo/config/lcp_ruby/presenters/todo_item.yml +75 -0
- data/examples/todo/config/lcp_ruby/presenters/todo_list.yml +68 -0
- data/examples/todo/config/lcp_ruby/views/todo_items.yml +11 -0
- data/examples/todo/config/lcp_ruby/views/todo_lists.yml +9 -0
- data/examples/todo/config/routes.rb +4 -0
- data/examples/todo/config/storage.yml +3 -0
- data/examples/todo/config.ru +2 -0
- data/examples/todo/db/migrate/20260219103416_create_active_storage_tables.active_storage.rb +57 -0
- data/examples/todo/db/schema.rb +63 -0
- data/examples/todo/db/seeds.rb +24 -0
- data/examples/todo/erd.md +21 -0
- data/exe/lcp +33 -0
- data/lib/generators/lcp_ruby/agent_setup_generator.rb +102 -0
- data/lib/generators/lcp_ruby/api_tokens_generator.rb +102 -0
- data/lib/generators/lcp_ruby/auditing_generator.rb +54 -0
- data/lib/generators/lcp_ruby/background_jobs_generator.rb +61 -0
- data/lib/generators/lcp_ruby/batch_operations_generator.rb +62 -0
- data/lib/generators/lcp_ruby/claude_skills_generator.rb +47 -0
- data/lib/generators/lcp_ruby/custom_fields_generator.rb +54 -0
- data/lib/generators/lcp_ruby/dsl_to_yaml.rb +72 -0
- data/lib/generators/lcp_ruby/entity/color_palette.rb +22 -0
- data/lib/generators/lcp_ruby/entity/field_descriptor.rb +24 -0
- data/lib/generators/lcp_ruby/entity/field_token_parser.rb +101 -0
- data/lib/generators/lcp_ruby/entity/role_discovery.rb +45 -0
- data/lib/generators/lcp_ruby/entity_generator.rb +1104 -0
- data/lib/generators/lcp_ruby/export_generator.rb +71 -0
- data/lib/generators/lcp_ruby/format_support.rb +56 -0
- data/lib/generators/lcp_ruby/gapfree_sequences_generator.rb +64 -0
- data/lib/generators/lcp_ruby/groups_generator.rb +94 -0
- data/lib/generators/lcp_ruby/host_controller_generator.rb +202 -0
- data/lib/generators/lcp_ruby/import_generator.rb +96 -0
- data/lib/generators/lcp_ruby/install_auth_generator.rb +432 -0
- data/lib/generators/lcp_ruby/install_generator.rb +319 -0
- data/lib/generators/lcp_ruby/monitoring_generator.rb +58 -0
- data/lib/generators/lcp_ruby/oidc_role_mappings_generator.rb +60 -0
- data/lib/generators/lcp_ruby/pages_generator.rb +66 -0
- data/lib/generators/lcp_ruby/permission_source_generator.rb +66 -0
- data/lib/generators/lcp_ruby/role_model_generator.rb +73 -0
- data/lib/generators/lcp_ruby/saved_filters_generator.rb +62 -0
- data/lib/generators/lcp_ruby/templates/add_oidc_columns_to_lcp_ruby_users.rb.erb +13 -0
- data/lib/generators/lcp_ruby/templates/agent_setup/agents_md.md +3 -0
- data/lib/generators/lcp_ruby/templates/agent_setup/claude_md.md +12 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/create_dialog.rb +31 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/locales.en.yml +43 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/model.rb +23 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/permissions.yml +30 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/presenter.rb +38 -0
- data/lib/generators/lcp_ruby/templates/api_tokens/view_group.rb +13 -0
- data/lib/generators/lcp_ruby/templates/auditing/model.rb +34 -0
- data/lib/generators/lcp_ruby/templates/auditing/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/auditing/presenter.rb +41 -0
- data/lib/generators/lcp_ruby/templates/auditing/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/model.rb +59 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/permissions.yml +22 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/presenter.rb +82 -0
- data/lib/generators/lcp_ruby/templates/background_jobs/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/item_model.rb +28 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/item_presenter.rb +43 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/model.rb +42 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/permissions.yml +44 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/presenter.rb +61 -0
- data/lib/generators/lcp_ruby/templates/batch_operations/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/create_lcp_ruby_users.rb.erb +50 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/model.rb +60 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/presenter.rb +128 -0
- data/lib/generators/lcp_ruby/templates/custom_fields/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/entity/model.rb +42 -0
- data/lib/generators/lcp_ruby/templates/entity/permissions.yml +20 -0
- data/lib/generators/lcp_ruby/templates/entity/presenter.rb +55 -0
- data/lib/generators/lcp_ruby/templates/entity/view_group.rb +8 -0
- data/lib/generators/lcp_ruby/templates/export/export_log_model.rb +30 -0
- data/lib/generators/lcp_ruby/templates/export/export_log_permissions.yml +24 -0
- data/lib/generators/lcp_ruby/templates/export/export_logs_presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/export/export_profile_model.rb +28 -0
- data/lib/generators/lcp_ruby/templates/export/export_profile_permissions.yml +26 -0
- data/lib/generators/lcp_ruby/templates/export/export_profiles_presenter.rb +59 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/model.rb +18 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/gapfree_sequences/view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/groups/group_membership_model.rb +17 -0
- data/lib/generators/lcp_ruby/templates/groups/group_model.rb +28 -0
- data/lib/generators/lcp_ruby/templates/groups/group_permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/groups/group_presenter.rb +53 -0
- data/lib/generators/lcp_ruby/templates/groups/group_role_mapping_model.rb +15 -0
- data/lib/generators/lcp_ruby/templates/groups/group_view_group.rb +9 -0
- data/lib/generators/lcp_ruby/templates/host_controller/controller.rb.erb +131 -0
- data/lib/generators/lcp_ruby/templates/import/data_import_job.yml +7 -0
- data/lib/generators/lcp_ruby/templates/import/import_profile_model.rb +30 -0
- data/lib/generators/lcp_ruby/templates/import/import_profile_permissions.yml +29 -0
- data/lib/generators/lcp_ruby/templates/import/import_profiles_presenter.rb +57 -0
- data/lib/generators/lcp_ruby/templates/import/import_row_model.rb +32 -0
- data/lib/generators/lcp_ruby/templates/import/import_row_permissions.yml +11 -0
- data/lib/generators/lcp_ruby/templates/import/import_rows_presenter.rb +35 -0
- data/lib/generators/lcp_ruby/templates/install/default_permissions.yml +26 -0
- data/lib/generators/lcp_ruby/templates/install/menu.yml.tt +71 -0
- data/lib/generators/lcp_ruby/templates/install/model.rb +20 -0
- data/lib/generators/lcp_ruby/templates/install/permissions.yml +25 -0
- data/lib/generators/lcp_ruby/templates/install/presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/install/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/entra.yml.erb +46 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/generic.yml.erb +55 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/google.yml.erb +42 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/keycloak.yml.erb +45 -0
- data/lib/generators/lcp_ruby/templates/install_auth/oidc/okta.yml.erb +45 -0
- data/lib/generators/lcp_ruby/templates/install_auth/user.rb +36 -0
- data/lib/generators/lcp_ruby/templates/monitoring/model.rb +34 -0
- data/lib/generators/lcp_ruby/templates/monitoring/model_extension.rb +12 -0
- data/lib/generators/lcp_ruby/templates/monitoring/page.yml +49 -0
- data/lib/generators/lcp_ruby/templates/monitoring/permissions.yml +8 -0
- data/lib/generators/lcp_ruby/templates/monitoring/presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/locales.en.yml +15 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/model.rb +32 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/permissions.yml +21 -0
- data/lib/generators/lcp_ruby/templates/oidc_role_mappings/presenter.rb +41 -0
- data/lib/generators/lcp_ruby/templates/pages/model.rb +19 -0
- data/lib/generators/lcp_ruby/templates/pages/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/pages/presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/pages/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/permission_source/model.rb +21 -0
- data/lib/generators/lcp_ruby/templates/permission_source/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/permission_source/presenter.rb +51 -0
- data/lib/generators/lcp_ruby/templates/permission_source/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/role_model/model.rb +24 -0
- data/lib/generators/lcp_ruby/templates/role_model/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/role_model/presenter.rb +62 -0
- data/lib/generators/lcp_ruby/templates/role_model/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/model.rb +51 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/permissions.yml +44 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/presenter.rb +96 -0
- data/lib/generators/lcp_ruby/templates/saved_filters/save_dialog_presenter.rb +19 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_model.rb +50 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/request_view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/step_model.rb +36 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/step_permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_model.rb +34 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_presenter.rb +39 -0
- data/lib/generators/lcp_ruby/templates/workflow_approvals/task_view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/model.rb +48 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/permissions.yml +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/presenter.rb +44 -0
- data/lib/generators/lcp_ruby/templates/workflow_audit_log/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/model.rb +43 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/permissions.yml +19 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/presenter.rb +70 -0
- data/lib/generators/lcp_ruby/templates/workflow_definition/view_group.rb +10 -0
- data/lib/generators/lcp_ruby/workflow_approvals_generator.rb +93 -0
- data/lib/generators/lcp_ruby/workflow_audit_log_generator.rb +54 -0
- data/lib/generators/lcp_ruby/workflow_definition_generator.rb +77 -0
- data/lib/lcp.rb +6 -0
- data/lib/lcp_ruby/actions/action_executor.rb +66 -0
- data/lib/lcp_ruby/actions/action_registry.rb +48 -0
- data/lib/lcp_ruby/actions/api_tokens/revoke.rb +13 -0
- data/lib/lcp_ruby/actions/base_action.rb +79 -0
- data/lib/lcp_ruby/actions/form_action_pipeline.rb +138 -0
- data/lib/lcp_ruby/aggregates/query_builder.rb +6 -0
- data/lib/lcp_ruby/api_tokens/model_extension.rb +41 -0
- data/lib/lcp_ruby/api_tokens/resolver_registry.rb +53 -0
- data/lib/lcp_ruby/api_tokens/token_generator.rb +27 -0
- data/lib/lcp_ruby/api_tokens/verifier.rb +38 -0
- data/lib/lcp_ruby/app_template.rb +181 -0
- data/lib/lcp_ruby/array_query.rb +120 -0
- data/lib/lcp_ruby/asset_copier.rb +62 -0
- data/lib/lcp_ruby/association_fk_type.rb +191 -0
- data/lib/lcp_ruby/association_join_column.rb +28 -0
- data/lib/lcp_ruby/association_options_builder.rb +231 -0
- data/lib/lcp_ruby/auditing/audit_writer.rb +258 -0
- data/lib/lcp_ruby/auditing/contract_validator.rb +95 -0
- data/lib/lcp_ruby/auditing/registry.rb +29 -0
- data/lib/lcp_ruby/auditing/setup.rb +49 -0
- data/lib/lcp_ruby/authentication/audit_subscriber.rb +51 -0
- data/lib/lcp_ruby/authentication/bearer_jwt_verifier.rb +139 -0
- data/lib/lcp_ruby/authentication/devise_setup.rb +47 -0
- data/lib/lcp_ruby/authentication/errors.rb +27 -0
- data/lib/lcp_ruby/authentication/http_fetcher.rb +36 -0
- data/lib/lcp_ruby/authentication/jwks_cache.rb +91 -0
- data/lib/lcp_ruby/authentication/oidc_bearer_resolver.rb +84 -0
- data/lib/lcp_ruby/authentication/omniauth_builder.rb +147 -0
- data/lib/lcp_ruby/authentication/provider.rb +108 -0
- data/lib/lcp_ruby/authentication/provider_registry.rb +227 -0
- data/lib/lcp_ruby/authentication/role_mapper.rb +94 -0
- data/lib/lcp_ruby/authentication/test_support.rb +257 -0
- data/lib/lcp_ruby/authentication/user_resolver.rb +169 -0
- data/lib/lcp_ruby/authentication.rb +40 -0
- data/lib/lcp_ruby/authorization/association_lookup.rb +56 -0
- data/lib/lcp_ruby/authorization/authorization_error.rb +12 -0
- data/lib/lcp_ruby/authorization/cache.rb +89 -0
- data/lib/lcp_ruby/authorization/codes.rb +17 -0
- data/lib/lcp_ruby/authorization/impersonated_user.rb +29 -0
- data/lib/lcp_ruby/authorization/includes_hint.rb +110 -0
- data/lib/lcp_ruby/authorization/inherited_parent_validator.rb +142 -0
- data/lib/lcp_ruby/authorization/invariant_check/configuration.rb +132 -0
- data/lib/lcp_ruby/authorization/invariant_error.rb +15 -0
- data/lib/lcp_ruby/authorization/misconfigured_page_error.rb +30 -0
- data/lib/lcp_ruby/authorization/page_gate.rb +57 -0
- data/lib/lcp_ruby/authorization/permission_evaluator.rb +343 -0
- data/lib/lcp_ruby/authorization/policy_factory.rb +91 -0
- data/lib/lcp_ruby/authorization/runtime_invariant_validator.rb +421 -0
- data/lib/lcp_ruby/authorization/scope_builder.rb +227 -0
- data/lib/lcp_ruby/authorization/scope_resolver.rb +28 -0
- data/lib/lcp_ruby/authorized_controller.rb +44 -0
- data/lib/lcp_ruby/background_jobs/base_handler.rb +113 -0
- data/lib/lcp_ruby/background_jobs/change_handler.rb +17 -0
- data/lib/lcp_ruby/background_jobs/contract.rb +16 -0
- data/lib/lcp_ruby/background_jobs/contract_validator.rb +112 -0
- data/lib/lcp_ruby/background_jobs/declarative/base_action.rb +11 -0
- data/lib/lcp_ruby/background_jobs/declarative/call_webhook_action.rb +174 -0
- data/lib/lcp_ruby/background_jobs/declarative/fire_event_action.rb +24 -0
- data/lib/lcp_ruby/background_jobs/declarative/registry.rb +34 -0
- data/lib/lcp_ruby/background_jobs/declarative/run_scope_action.rb +98 -0
- data/lib/lcp_ruby/background_jobs/declarative/send_notification_action.rb +13 -0
- data/lib/lcp_ruby/background_jobs/definition.rb +134 -0
- data/lib/lcp_ruby/background_jobs/enqueue.rb +83 -0
- data/lib/lcp_ruby/background_jobs/errors.rb +9 -0
- data/lib/lcp_ruby/background_jobs/executor_job.rb +111 -0
- data/lib/lcp_ruby/background_jobs/handler_factory.rb +46 -0
- data/lib/lcp_ruby/background_jobs/host_source.rb +33 -0
- data/lib/lcp_ruby/background_jobs/model_source.rb +93 -0
- data/lib/lcp_ruby/background_jobs/registry.rb +81 -0
- data/lib/lcp_ruby/background_jobs/resolver.rb +29 -0
- data/lib/lcp_ruby/background_jobs/schedule_adapter.rb +14 -0
- data/lib/lcp_ruby/background_jobs/setup.rb +145 -0
- data/lib/lcp_ruby/background_jobs/static_source.rb +19 -0
- data/lib/lcp_ruby/background_jobs/steps_executor.rb +52 -0
- data/lib/lcp_ruby/background_jobs/triggers/event_trigger.rb +97 -0
- data/lib/lcp_ruby/background_jobs/triggers/trigger_installer.rb +20 -0
- data/lib/lcp_ruby/background_jobs/unique_key_builder.rb +31 -0
- data/lib/lcp_ruby/batch_actions/base_service.rb +70 -0
- data/lib/lcp_ruby/batch_actions/batch_action_handler.rb +200 -0
- data/lib/lcp_ruby/batch_actions/custom_action_dispatcher.rb +133 -0
- data/lib/lcp_ruby/batch_actions/destroy_service.rb +37 -0
- data/lib/lcp_ruby/batch_actions/permanently_destroy_service.rb +33 -0
- data/lib/lcp_ruby/batch_actions/restore_service.rb +33 -0
- data/lib/lcp_ruby/batch_actions.rb +5 -0
- data/lib/lcp_ruby/bulk_updater.rb +25 -0
- data/lib/lcp_ruby/cli/docs_command.rb +29 -0
- data/lib/lcp_ruby/cli/examples_command.rb +29 -0
- data/lib/lcp_ruby/cli/new_command.rb +509 -0
- data/lib/lcp_ruby/cli/run_command.rb +155 -0
- data/lib/lcp_ruby/cli/skills_command.rb +54 -0
- data/lib/lcp_ruby/cli.rb +74 -0
- data/lib/lcp_ruby/condition_evaluator.rb +366 -0
- data/lib/lcp_ruby/condition_service_registry.rb +58 -0
- data/lib/lcp_ruby/condition_services/current_user_role.rb +28 -0
- data/lib/lcp_ruby/condition_services/feature_flag.rb +63 -0
- data/lib/lcp_ruby/condition_services/impersonating.rb +24 -0
- data/lib/lcp_ruby/conditions/validator.rb +35 -0
- data/lib/lcp_ruby/configuration.rb +431 -0
- data/lib/lcp_ruby/controller/authentication.rb +118 -0
- data/lib/lcp_ruby/controller/authorization.rb +198 -0
- data/lib/lcp_ruby/controller/bearer_authentication.rb +76 -0
- data/lib/lcp_ruby/controller/crud_helpers.rb +233 -0
- data/lib/lcp_ruby/controller/error_handling.rb +94 -0
- data/lib/lcp_ruby/controller/impersonation.rb +70 -0
- data/lib/lcp_ruby/controller/locale_binding.rb +62 -0
- data/lib/lcp_ruby/controller/path_helpers.rb +125 -0
- data/lib/lcp_ruby/controller/presenter_setup.rb +89 -0
- data/lib/lcp_ruby/controller/search.rb +321 -0
- data/lib/lcp_ruby/controller/view_helpers.rb +105 -0
- data/lib/lcp_ruby/current.rb +13 -0
- data/lib/lcp_ruby/custom_fields/applicator.rb +194 -0
- data/lib/lcp_ruby/custom_fields/contract_validator.rb +77 -0
- data/lib/lcp_ruby/custom_fields/definition_change_handler.rb +21 -0
- data/lib/lcp_ruby/custom_fields/query.rb +112 -0
- data/lib/lcp_ruby/custom_fields/registry.rb +70 -0
- data/lib/lcp_ruby/custom_fields/setup.rb +58 -0
- data/lib/lcp_ruby/custom_fields/utils.rb +40 -0
- data/lib/lcp_ruby/custom_fields.rb +9 -0
- data/lib/lcp_ruby/data_source/api_error_placeholder.rb +47 -0
- data/lib/lcp_ruby/data_source/api_filter_translator.rb +72 -0
- data/lib/lcp_ruby/data_source/api_model_concern.rb +131 -0
- data/lib/lcp_ruby/data_source/api_preloader.rb +44 -0
- data/lib/lcp_ruby/data_source/base.rb +85 -0
- data/lib/lcp_ruby/data_source/cached_wrapper.rb +107 -0
- data/lib/lcp_ruby/data_source/host.rb +71 -0
- data/lib/lcp_ruby/data_source/registry.rb +39 -0
- data/lib/lcp_ruby/data_source/resilient_wrapper.rb +67 -0
- data/lib/lcp_ruby/data_source/rest_json.rb +247 -0
- data/lib/lcp_ruby/data_source/setup.rb +57 -0
- data/lib/lcp_ruby/dev_toolbar.rb +8 -0
- data/lib/lcp_ruby/display/base_renderer.rb +21 -0
- data/lib/lcp_ruby/display/count_badge.rb +11 -0
- data/lib/lcp_ruby/display/icon_badge.rb +17 -0
- data/lib/lcp_ruby/display/renderer_registry.rb +138 -0
- data/lib/lcp_ruby/display/renderers/attachment_link.rb +26 -0
- data/lib/lcp_ruby/display/renderers/attachment_list.rb +32 -0
- data/lib/lcp_ruby/display/renderers/attachment_preview.rb +26 -0
- data/lib/lcp_ruby/display/renderers/avatar.rb +14 -0
- data/lib/lcp_ruby/display/renderers/badge.rb +43 -0
- data/lib/lcp_ruby/display/renderers/boolean_icon.rb +54 -0
- data/lib/lcp_ruby/display/renderers/code.rb +39 -0
- data/lib/lcp_ruby/display/renderers/collection.rb +34 -0
- data/lib/lcp_ruby/display/renderers/color_swatch.rb +25 -0
- data/lib/lcp_ruby/display/renderers/concerns/attachment_helpers.rb +73 -0
- data/lib/lcp_ruby/display/renderers/concerns/workflow_helpers.rb +35 -0
- data/lib/lcp_ruby/display/renderers/copy_code.rb +33 -0
- data/lib/lcp_ruby/display/renderers/currency.rb +14 -0
- data/lib/lcp_ruby/display/renderers/date.rb +17 -0
- data/lib/lcp_ruby/display/renderers/datetime.rb +17 -0
- data/lib/lcp_ruby/display/renderers/email_link.rb +15 -0
- data/lib/lcp_ruby/display/renderers/file_size.rb +11 -0
- data/lib/lcp_ruby/display/renderers/heading.rb +11 -0
- data/lib/lcp_ruby/display/renderers/image.rb +17 -0
- data/lib/lcp_ruby/display/renderers/internal_link.rb +23 -0
- data/lib/lcp_ruby/display/renderers/link.rb +15 -0
- data/lib/lcp_ruby/display/renderers/link_list.rb +90 -0
- data/lib/lcp_ruby/display/renderers/markdown.rb +33 -0
- data/lib/lcp_ruby/display/renderers/number.rb +14 -0
- data/lib/lcp_ruby/display/renderers/percentage.rb +12 -0
- data/lib/lcp_ruby/display/renderers/phone_link.rb +15 -0
- data/lib/lcp_ruby/display/renderers/progress_bar.rb +15 -0
- data/lib/lcp_ruby/display/renderers/rating.rb +15 -0
- data/lib/lcp_ruby/display/renderers/record_link.rb +101 -0
- data/lib/lcp_ruby/display/renderers/relative_date.rb +15 -0
- data/lib/lcp_ruby/display/renderers/rich_text.rb +15 -0
- data/lib/lcp_ruby/display/renderers/text.rb +12 -0
- data/lib/lcp_ruby/display/renderers/truncate.rb +17 -0
- data/lib/lcp_ruby/display/renderers/url_link.rb +22 -0
- data/lib/lcp_ruby/display/renderers/workflow_badge.rb +37 -0
- data/lib/lcp_ruby/display/renderers/workflow_timeline.rb +173 -0
- data/lib/lcp_ruby/display/renderers.rb +3 -0
- data/lib/lcp_ruby/display/text_badge.rb +15 -0
- data/lib/lcp_ruby/dsl/condition_builder.rb +190 -0
- data/lib/lcp_ruby/dsl/dsl_loader.rb +365 -0
- data/lib/lcp_ruby/dsl/field_builder.rb +35 -0
- data/lib/lcp_ruby/dsl/job_builder.rb +92 -0
- data/lib/lcp_ruby/dsl/model_builder.rb +544 -0
- data/lib/lcp_ruby/dsl/presenter_builder.rb +1272 -0
- data/lib/lcp_ruby/dsl/source_location_capture.rb +52 -0
- data/lib/lcp_ruby/dsl/type_builder.rb +88 -0
- data/lib/lcp_ruby/dsl/view_group_builder.rb +92 -0
- data/lib/lcp_ruby/dsl/workflow_builder.rb +319 -0
- data/lib/lcp_ruby/dynamic.rb +7 -0
- data/lib/lcp_ruby/dynamic_references/resolver.rb +154 -0
- data/lib/lcp_ruby/dynamic_references/validator.rb +92 -0
- data/lib/lcp_ruby/embed_providers/base.rb +18 -0
- data/lib/lcp_ruby/embed_providers/grafana.rb +38 -0
- data/lib/lcp_ruby/embed_providers/metabase.rb +37 -0
- data/lib/lcp_ruby/engine.rb +680 -0
- data/lib/lcp_ruby/events/async_handler_job.rb +21 -0
- data/lib/lcp_ruby/events/dispatcher.rb +52 -0
- data/lib/lcp_ruby/events/handler_base.rb +51 -0
- data/lib/lcp_ruby/events/handler_registry.rb +49 -0
- data/lib/lcp_ruby/export/data_generator.rb +158 -0
- data/lib/lcp_ruby/export/export_handler.rb +315 -0
- data/lib/lcp_ruby/export/field_tree_builder.rb +219 -0
- data/lib/lcp_ruby/export/setup.rb +94 -0
- data/lib/lcp_ruby/export/value_formatter.rb +223 -0
- data/lib/lcp_ruby/export.rb +9 -0
- data/lib/lcp_ruby/gem_paths.rb +51 -0
- data/lib/lcp_ruby/generators/entity_menu_writer.rb +258 -0
- data/lib/lcp_ruby/generators/feature_registry.rb +208 -0
- data/lib/lcp_ruby/generators/prerequisites.rb +90 -0
- data/lib/lcp_ruby/grouped_query/builder.rb +206 -0
- data/lib/lcp_ruby/grouped_query/result_wrapper.rb +72 -0
- data/lib/lcp_ruby/grouped_query/row.rb +31 -0
- data/lib/lcp_ruby/groups/change_handler.rb +18 -0
- data/lib/lcp_ruby/groups/contract.rb +42 -0
- data/lib/lcp_ruby/groups/contract_validator.rb +110 -0
- data/lib/lcp_ruby/groups/host_loader.rb +54 -0
- data/lib/lcp_ruby/groups/model_loader.rb +186 -0
- data/lib/lcp_ruby/groups/registry.rb +113 -0
- data/lib/lcp_ruby/groups/setup.rb +129 -0
- data/lib/lcp_ruby/groups/yaml_loader.rb +97 -0
- data/lib/lcp_ruby/hash_utils.rb +42 -0
- data/lib/lcp_ruby/i18n_check/configuration.rb +104 -0
- data/lib/lcp_ruby/i18n_check/heuristics.rb +26 -0
- data/lib/lcp_ruby/i18n_check/key_deriver.rb +136 -0
- data/lib/lcp_ruby/i18n_check/offense.rb +29 -0
- data/lib/lcp_ruby/i18n_check/registry_walker.rb +621 -0
- data/lib/lcp_ruby/i18n_check/reporter.rb +96 -0
- data/lib/lcp_ruby/i18n_check/runner.rb +46 -0
- data/lib/lcp_ruby/i18n_check.rb +15 -0
- data/lib/lcp_ruby/i18n_lint.rb +145 -0
- data/lib/lcp_ruby/import/auto_mapper.rb +98 -0
- data/lib/lcp_ruby/import/field_tree_builder.rb +178 -0
- data/lib/lcp_ruby/import/file_parser.rb +223 -0
- data/lib/lcp_ruby/import/import_dialog_handler.rb +410 -0
- data/lib/lcp_ruby/import/import_job_handler.rb +224 -0
- data/lib/lcp_ruby/import/row_processor.rb +281 -0
- data/lib/lcp_ruby/import/setup.rb +277 -0
- data/lib/lcp_ruby/import/value_coercer.rb +143 -0
- data/lib/lcp_ruby/import.rb +14 -0
- data/lib/lcp_ruby/json_item_wrapper.rb +152 -0
- data/lib/lcp_ruby/kanban/board.rb +28 -0
- data/lib/lcp_ruby/kanban/column.rb +28 -0
- data/lib/lcp_ruby/kanban/default_provider.rb +376 -0
- data/lib/lcp_ruby/kanban/host_provider.rb +94 -0
- data/lib/lcp_ruby/kanban/move_result.rb +52 -0
- data/lib/lcp_ruby/kanban/provider_test_harness.rb +54 -0
- data/lib/lcp_ruby/kanban/swimlane.rb +21 -0
- data/lib/lcp_ruby/menu.rb +46 -0
- data/lib/lcp_ruby/metadata/aggregate_definition.rb +6 -0
- data/lib/lcp_ruby/metadata/association_definition.rb +196 -0
- data/lib/lcp_ruby/metadata/auth_validator.rb +222 -0
- data/lib/lcp_ruby/metadata/configuration_validator.rb +7958 -0
- data/lib/lcp_ruby/metadata/contract_result.rb +9 -0
- data/lib/lcp_ruby/metadata/display_template_definition.rb +77 -0
- data/lib/lcp_ruby/metadata/enum_label_resolver.rb +27 -0
- data/lib/lcp_ruby/metadata/erd_generator.rb +274 -0
- data/lib/lcp_ruby/metadata/event_definition.rb +55 -0
- data/lib/lcp_ruby/metadata/field_definition.rb +267 -0
- data/lib/lcp_ruby/metadata/group_definition.rb +31 -0
- data/lib/lcp_ruby/metadata/i18n_label.rb +29 -0
- data/lib/lcp_ruby/metadata/loader.rb +916 -0
- data/lib/lcp_ruby/metadata/menu_definition.rb +116 -0
- data/lib/lcp_ruby/metadata/menu_item.rb +792 -0
- data/lib/lcp_ruby/metadata/menu_item_resolver.rb +105 -0
- data/lib/lcp_ruby/metadata/model_definition.rb +612 -0
- data/lib/lcp_ruby/metadata/model_hash_merger.rb +88 -0
- data/lib/lcp_ruby/metadata/model_inheritance_resolver.rb +165 -0
- data/lib/lcp_ruby/metadata/page_definition.rb +245 -0
- data/lib/lcp_ruby/metadata/path_template.rb +231 -0
- data/lib/lcp_ruby/metadata/permission_definition.rb +237 -0
- data/lib/lcp_ruby/metadata/permission_merger.rb +81 -0
- data/lib/lcp_ruby/metadata/presenter_definition.rb +689 -0
- data/lib/lcp_ruby/metadata/reserved_names.rb +79 -0
- data/lib/lcp_ruby/metadata/responsive_policy.rb +95 -0
- data/lib/lcp_ruby/metadata/schema_validator.rb +172 -0
- data/lib/lcp_ruby/metadata/validation_definition.rb +69 -0
- data/lib/lcp_ruby/metadata/view_group_definition.rb +208 -0
- data/lib/lcp_ruby/metadata/virtual_column_definition.rb +154 -0
- data/lib/lcp_ruby/metadata/zone_definition.rb +423 -0
- data/lib/lcp_ruby/metrics/collector.rb +123 -0
- data/lib/lcp_ruby/metrics/collector_registry.rb +57 -0
- data/lib/lcp_ruby/metrics/error_recorder.rb +70 -0
- data/lib/lcp_ruby/metrics/fingerprint.rb +33 -0
- data/lib/lcp_ruby/metrics/json_query.rb +47 -0
- data/lib/lcp_ruby/metrics/metric_definitions.rb +105 -0
- data/lib/lcp_ruby/metrics/prometheus_check.rb +9 -0
- data/lib/lcp_ruby/metrics/rate_limiter.rb +99 -0
- data/lib/lcp_ruby/metrics/setup.rb +71 -0
- data/lib/lcp_ruby/metrics/subscriber.rb +126 -0
- data/lib/lcp_ruby/model_factory/aggregate_applicator.rb +14 -0
- data/lib/lcp_ruby/model_factory/api_association_applicator.rb +119 -0
- data/lib/lcp_ruby/model_factory/api_builder.rb +85 -0
- data/lib/lcp_ruby/model_factory/array_type.rb +78 -0
- data/lib/lcp_ruby/model_factory/array_type_applicator.rb +33 -0
- data/lib/lcp_ruby/model_factory/association_applicator.rb +201 -0
- data/lib/lcp_ruby/model_factory/attachment_applicator.rb +160 -0
- data/lib/lcp_ruby/model_factory/auditing_applicator.rb +72 -0
- data/lib/lcp_ruby/model_factory/builder.rb +235 -0
- data/lib/lcp_ruby/model_factory/callback_applicator.rb +63 -0
- data/lib/lcp_ruby/model_factory/computed_applicator.rb +55 -0
- data/lib/lcp_ruby/model_factory/default_applicator.rb +85 -0
- data/lib/lcp_ruby/model_factory/enum_applicator.rb +24 -0
- data/lib/lcp_ruby/model_factory/inherited_parent_validator_applicator.rb +39 -0
- data/lib/lcp_ruby/model_factory/label_method_builder.rb +82 -0
- data/lib/lcp_ruby/model_factory/managed_tracking.rb +71 -0
- data/lib/lcp_ruby/model_factory/positioning_applicator.rb +23 -0
- data/lib/lcp_ruby/model_factory/ransack_applicator.rb +66 -0
- data/lib/lcp_ruby/model_factory/registry.rb +33 -0
- data/lib/lcp_ruby/model_factory/schema_manager.rb +655 -0
- data/lib/lcp_ruby/model_factory/scope_applicator.rb +87 -0
- data/lib/lcp_ruby/model_factory/sequence_applicator.rb +173 -0
- data/lib/lcp_ruby/model_factory/service_accessor_applicator.rb +40 -0
- data/lib/lcp_ruby/model_factory/soft_delete_applicator.rb +141 -0
- data/lib/lcp_ruby/model_factory/transform_applicator.rb +51 -0
- data/lib/lcp_ruby/model_factory/tree_applicator.rb +239 -0
- data/lib/lcp_ruby/model_factory/userstamps_applicator.rb +73 -0
- data/lib/lcp_ruby/model_factory/validation_applicator.rb +319 -0
- data/lib/lcp_ruby/model_factory/virtual_column_applicator.rb +79 -0
- data/lib/lcp_ruby/model_factory/workflow_applicator.rb +141 -0
- data/lib/lcp_ruby/pages/change_handler.rb +15 -0
- data/lib/lcp_ruby/pages/contract_validator.rb +74 -0
- data/lib/lcp_ruby/pages/definition_validator.rb +42 -0
- data/lib/lcp_ruby/pages/filter_form.rb +200 -0
- data/lib/lcp_ruby/pages/filter_form_validator.rb +636 -0
- data/lib/lcp_ruby/pages/registry.rb +133 -0
- data/lib/lcp_ruby/pages/resolver.rb +32 -0
- data/lib/lcp_ruby/pages/scope_context_resolver.rb +37 -0
- data/lib/lcp_ruby/pages/scope_filter_set.rb +57 -0
- data/lib/lcp_ruby/pages/setup.rb +46 -0
- data/lib/lcp_ruby/path_utils.rb +12 -0
- data/lib/lcp_ruby/permissions/change_handler.rb +22 -0
- data/lib/lcp_ruby/permissions/contract_validator.rb +74 -0
- data/lib/lcp_ruby/permissions/definition_validator.rb +119 -0
- data/lib/lcp_ruby/permissions/registry.rb +135 -0
- data/lib/lcp_ruby/permissions/setup.rb +51 -0
- data/lib/lcp_ruby/permissions/source_resolver.rb +56 -0
- data/lib/lcp_ruby/presenter/action_set.rb +236 -0
- data/lib/lcp_ruby/presenter/breadcrumb_builder.rb +183 -0
- data/lib/lcp_ruby/presenter/breadcrumb_path_helper.rb +17 -0
- data/lib/lcp_ruby/presenter/column_set.rb +268 -0
- data/lib/lcp_ruby/presenter/enrichment.rb +136 -0
- data/lib/lcp_ruby/presenter/field_value_resolver.rb +237 -0
- data/lib/lcp_ruby/presenter/includes_resolver/association_dependency.rb +59 -0
- data/lib/lcp_ruby/presenter/includes_resolver/dependency_collector.rb +394 -0
- data/lib/lcp_ruby/presenter/includes_resolver/loading_strategy.rb +70 -0
- data/lib/lcp_ruby/presenter/includes_resolver/strategy_resolver.rb +123 -0
- data/lib/lcp_ruby/presenter/includes_resolver.rb +42 -0
- data/lib/lcp_ruby/presenter/layout_builder.rb +467 -0
- data/lib/lcp_ruby/presenter/link_resolver.rb +65 -0
- data/lib/lcp_ruby/presenter/metadata_lookup.rb +28 -0
- data/lib/lcp_ruby/presenter/resolver.rb +25 -0
- data/lib/lcp_ruby/record_aliases/metadata_checker.rb +213 -0
- data/lib/lcp_ruby/record_aliases/setup.rb +212 -0
- data/lib/lcp_ruby/reserved_route_segments.rb +37 -0
- data/lib/lcp_ruby/roles/change_handler.rb +11 -0
- data/lib/lcp_ruby/roles/contract_validator.rb +67 -0
- data/lib/lcp_ruby/roles/registry.rb +89 -0
- data/lib/lcp_ruby/roles/setup.rb +50 -0
- data/lib/lcp_ruby/routing/presenter_routes.rb +104 -0
- data/lib/lcp_ruby/saved_filters/change_handler.rb +13 -0
- data/lib/lcp_ruby/saved_filters/contract_validator.rb +85 -0
- data/lib/lcp_ruby/saved_filters/registry.rb +36 -0
- data/lib/lcp_ruby/saved_filters/resolver.rb +108 -0
- data/lib/lcp_ruby/saved_filters/setup.rb +42 -0
- data/lib/lcp_ruby/saved_filters/stale_field_validator.rb +84 -0
- data/lib/lcp_ruby/schemas/auth.json +208 -0
- data/lib/lcp_ruby/schemas/menu.json +338 -0
- data/lib/lcp_ruby/schemas/model.json +1161 -0
- data/lib/lcp_ruby/schemas/page.json +877 -0
- data/lib/lcp_ruby/schemas/permission.json +454 -0
- data/lib/lcp_ruby/schemas/presenter.json +2274 -0
- data/lib/lcp_ruby/schemas/theme.json +62 -0
- data/lib/lcp_ruby/schemas/type.json +146 -0
- data/lib/lcp_ruby/schemas/view_group.json +163 -0
- data/lib/lcp_ruby/search/custom_field_filter.rb +171 -0
- data/lib/lcp_ruby/search/custom_filter_interceptor.rb +40 -0
- data/lib/lcp_ruby/search/filter_metadata_builder.rb +409 -0
- data/lib/lcp_ruby/search/filter_param_builder.rb +177 -0
- data/lib/lcp_ruby/search/operator_registry.rb +79 -0
- data/lib/lcp_ruby/search/param_sanitizer.rb +25 -0
- data/lib/lcp_ruby/search/parameter_definition.rb +187 -0
- data/lib/lcp_ruby/search/parameterized_scope_applicator.rb +129 -0
- data/lib/lcp_ruby/search/query_builder.rb +143 -0
- data/lib/lcp_ruby/search/query_language_parser.rb +549 -0
- data/lib/lcp_ruby/search/query_language_serializer.rb +193 -0
- data/lib/lcp_ruby/search/quick_search.rb +162 -0
- data/lib/lcp_ruby/search/relative_date_expander.rb +57 -0
- data/lib/lcp_ruby/search_result.rb +70 -0
- data/lib/lcp_ruby/sequences/sequence_manager.rb +51 -0
- data/lib/lcp_ruby/services/accessors/json_field.rb +23 -0
- data/lib/lcp_ruby/services/built_in_accessors.rb +17 -0
- data/lib/lcp_ruby/services/built_in_defaults.rb +22 -0
- data/lib/lcp_ruby/services/built_in_transforms.rb +20 -0
- data/lib/lcp_ruby/services/checker.rb +133 -0
- data/lib/lcp_ruby/services/registry.rb +83 -0
- data/lib/lcp_ruby/skills_installer.rb +73 -0
- data/lib/lcp_ruby/sort/enum_sort_order.rb +38 -0
- data/lib/lcp_ruby/tasks/destroy_order_resolver.rb +57 -0
- data/lib/lcp_ruby/tasks/doctor.rb +294 -0
- data/lib/lcp_ruby/tasks/permission_resolve_formatter.rb +245 -0
- data/lib/lcp_ruby/types/built_in_types.rb +157 -0
- data/lib/lcp_ruby/types/transforms/base_transform.rb +11 -0
- data/lib/lcp_ruby/types/transforms/downcase.rb +11 -0
- data/lib/lcp_ruby/types/transforms/normalize_phone.rb +19 -0
- data/lib/lcp_ruby/types/transforms/normalize_url.rb +16 -0
- data/lib/lcp_ruby/types/transforms/strip.rb +11 -0
- data/lib/lcp_ruby/types/type_definition.rb +112 -0
- data/lib/lcp_ruby/types/type_registry.rb +75 -0
- data/lib/lcp_ruby/url_safety.rb +97 -0
- data/lib/lcp_ruby/user_snapshot.rb +15 -0
- data/lib/lcp_ruby/version.rb +3 -0
- data/lib/lcp_ruby/view_slots/registry.rb +71 -0
- data/lib/lcp_ruby/view_slots/slot_component.rb +22 -0
- data/lib/lcp_ruby/view_slots/slot_context.rb +20 -0
- data/lib/lcp_ruby/virtual_columns/builder.rb +234 -0
- data/lib/lcp_ruby/virtual_columns/collector.rb +186 -0
- data/lib/lcp_ruby/virtual_columns.rb +4 -0
- data/lib/lcp_ruby/virtual_fields/synthetic_marker.rb +17 -0
- data/lib/lcp_ruby/virtual_fields/types/array_of.rb +49 -0
- data/lib/lcp_ruby/virtual_fields/virtual_field.rb +107 -0
- data/lib/lcp_ruby/virtual_fields/virtual_form.rb +144 -0
- data/lib/lcp_ruby/widgets/chart_palette.rb +25 -0
- data/lib/lcp_ruby/widgets/chartkick_check.rb +9 -0
- data/lib/lcp_ruby/widgets/data_resolver.rb +676 -0
- data/lib/lcp_ruby/widgets/date_grouper.rb +54 -0
- data/lib/lcp_ruby/widgets/presenter_zone_resolver.rb +170 -0
- data/lib/lcp_ruby/widgets/record_source_resolver.rb +56 -0
- data/lib/lcp_ruby/widgets/scope_applicator.rb +187 -0
- data/lib/lcp_ruby/workflow/approval/activation_handler.rb +39 -0
- data/lib/lcp_ruby/workflow/approval/approval_definition.rb +117 -0
- data/lib/lcp_ruby/workflow/approval/approver_resolver.rb +98 -0
- data/lib/lcp_ruby/workflow/approval/cleanup_handler.rb +37 -0
- data/lib/lcp_ruby/workflow/approval/contract_validator.rb +96 -0
- data/lib/lcp_ruby/workflow/approval/data_builder.rb +53 -0
- data/lib/lcp_ruby/workflow/approval/discard_handler.rb +51 -0
- data/lib/lcp_ruby/workflow/approval/engine.rb +314 -0
- data/lib/lcp_ruby/workflow/approval/registry.rb +40 -0
- data/lib/lcp_ruby/workflow/approval/resolution_handler.rb +103 -0
- data/lib/lcp_ruby/workflow/approval/setup.rb +138 -0
- data/lib/lcp_ruby/workflow/approval/step_definition.rb +52 -0
- data/lib/lcp_ruby/workflow/approval/step_evaluator.rb +163 -0
- data/lib/lcp_ruby/workflow/approval/system_evaluator.rb +29 -0
- data/lib/lcp_ruby/workflow/approval/task_manager.rb +202 -0
- data/lib/lcp_ruby/workflow/audit_contract_validator.rb +64 -0
- data/lib/lcp_ruby/workflow/audit_registry.rb +24 -0
- data/lib/lcp_ruby/workflow/audit_writer.rb +51 -0
- data/lib/lcp_ruby/workflow/change_handler.rb +14 -0
- data/lib/lcp_ruby/workflow/contract.rb +21 -0
- data/lib/lcp_ruby/workflow/contract_validator.rb +44 -0
- data/lib/lcp_ruby/workflow/errors.rb +12 -0
- data/lib/lcp_ruby/workflow/host_source.rb +19 -0
- data/lib/lcp_ruby/workflow/mermaid_builder.rb +217 -0
- data/lib/lcp_ruby/workflow/model_source.rb +79 -0
- data/lib/lcp_ruby/workflow/registry.rb +113 -0
- data/lib/lcp_ruby/workflow/resolver.rb +32 -0
- data/lib/lcp_ruby/workflow/setup.rb +135 -0
- data/lib/lcp_ruby/workflow/state_definition.rb +59 -0
- data/lib/lcp_ruby/workflow/state_machine.rb +78 -0
- data/lib/lcp_ruby/workflow/static_source.rb +20 -0
- data/lib/lcp_ruby/workflow/transition_action_builder.rb +46 -0
- data/lib/lcp_ruby/workflow/transition_definition.rb +70 -0
- data/lib/lcp_ruby/workflow/transition_executor.rb +140 -0
- data/lib/lcp_ruby/workflow/transition_label_resolver.rb +21 -0
- data/lib/lcp_ruby/workflow/transition_result.rb +20 -0
- data/lib/lcp_ruby/workflow/value_resolver.rb +58 -0
- data/lib/lcp_ruby/workflow/workflow_definition.rb +195 -0
- data/lib/lcp_ruby.rb +764 -0
- data/lib/rubocop/cop/lcp_ruby/no_hardcoded_i18n_string.rb +249 -0
- data/lib/tasks/lcp_ruby.rake +432 -0
- data/lib/tasks/lcp_ruby_assets.rake +37 -0
- data/lib/tasks/lcp_ruby_auth.rake +49 -0
- data/lib/tasks/lcp_ruby_db.rake +76 -0
- data/lib/tasks/lcp_ruby_doctor.rake +20 -0
- data/lib/tasks/lcp_ruby_feature_catalog.rake +61 -0
- data/lib/tasks/lcp_ruby_gapfree_sequences.rake +39 -0
- data/lib/tasks/lcp_ruby_i18n_check.rake +23 -0
- data/lib/tasks/lcp_ruby_i18n_lint.rake +20 -0
- data/lib/tasks/lcp_ruby_invariant_check.rake +72 -0
- data/vendor/assets/javascripts/lcp_ruby/activestorage.min.js +866 -0
- data/vendor/assets/javascripts/lcp_ruby/highlight.min.js +1244 -0
- data/vendor/assets/javascripts/lcp_ruby/lucide.min.js +12 -0
- data/vendor/assets/javascripts/lcp_ruby/stimulus.umd.js +2588 -0
- data/vendor/assets/javascripts/lcp_ruby/tom-select.complete.min.js +444 -0
- data/vendor/assets/stylesheets/lcp_ruby/highlight-github.min.css +12 -0
- data/vendor/assets/stylesheets/lcp_ruby/tom-select.css +412 -0
- metadata +1950 -0
data/config/routes.rb
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
LcpRuby::Engine.routes.draw do
|
|
2
|
+
# Devise routes are always mounted so URL helpers stay available regardless
|
|
3
|
+
# of mode; controllers gate access via require_session_based_auth!.
|
|
4
|
+
devise_for :users,
|
|
5
|
+
class_name: "LcpRuby::User",
|
|
6
|
+
module: "lcp_ruby/auth",
|
|
7
|
+
path: "auth",
|
|
8
|
+
router_name: :lcp_ruby,
|
|
9
|
+
path_names: {
|
|
10
|
+
sign_in: "login",
|
|
11
|
+
sign_out: "logout",
|
|
12
|
+
sign_up: "register",
|
|
13
|
+
password: "password"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# OIDC endpoints — only drawn when at least one :oidc provider is configured
|
|
17
|
+
# in config/lcp_ruby/auth.yml. OmniAuth 2.0 requires POST on the request phase
|
|
18
|
+
# for CSRF protection; the login view initiates provider sign-in via button_to.
|
|
19
|
+
if LcpRuby::Authentication::ProviderRegistry.oidc_enabled?
|
|
20
|
+
scope "auth", controller: "auth/callbacks" do
|
|
21
|
+
provider_constraint = { provider: /[a-z0-9_]+/ }
|
|
22
|
+
post ":provider", action: :passthru, as: :oidc_start, constraints: provider_constraint
|
|
23
|
+
match ":provider/callback", action: :callback, as: :oidc_callback, constraints: provider_constraint, via: %i[get post]
|
|
24
|
+
get "failure", action: :failure, as: :oidc_failure
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
get "lcp_health", to: "health#show", as: :health_check if LcpRuby.configuration.health_check
|
|
29
|
+
get "metrics", to: "metrics#show", as: :metrics if LcpRuby.configuration.metrics_endpoint
|
|
30
|
+
|
|
31
|
+
get "/_dev/metadata", to: "dev_toolbar#metadata", as: :dev_toolbar_metadata
|
|
32
|
+
|
|
33
|
+
get "/", to: "landing#show", as: :landing
|
|
34
|
+
|
|
35
|
+
post "impersonate", to: "impersonation#create", as: :impersonate
|
|
36
|
+
delete "impersonate", to: "impersonation#destroy", as: :stop_impersonate
|
|
37
|
+
|
|
38
|
+
scope "lcp_dialog/:page_name" do
|
|
39
|
+
get "/new", to: "dialogs#new", as: :dialog_new
|
|
40
|
+
post "/", to: "dialogs#create", as: :dialog_create
|
|
41
|
+
get "/:id/edit", to: "dialogs#edit", as: :dialog_edit
|
|
42
|
+
patch "/:id", to: "dialogs#update", as: :dialog_update
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Per-presenter routes for presenters with controller: or action_controllers:.
|
|
46
|
+
# Drawn before the catch-all so explicit slug routes take precedence.
|
|
47
|
+
LcpRuby::Routing::PresenterRoutes.draw_custom_controller_routes(self)
|
|
48
|
+
|
|
49
|
+
# Slug constraint rejects asset paths (`favicon.ico`, …) at the routing layer.
|
|
50
|
+
# Format whitelist accepts REST-style suffixes for data formats only.
|
|
51
|
+
# NOTE: do NOT add `\A…\z` anchors to the format regex — Rails embeds it into
|
|
52
|
+
# a larger pattern and the anchors break format extraction. Rails anchors
|
|
53
|
+
# implicitly; the `.jsonp`-style partial-match guard test in
|
|
54
|
+
# spec/integration/asset_route_passthrough_spec.rb keeps that invariant.
|
|
55
|
+
# Asset paths that slip through (e.g. `manifest.json`, slug=manifest) are
|
|
56
|
+
# caught downstream by `rescue_from MetadataError` in ErrorHandling.
|
|
57
|
+
scope ":lcp_slug",
|
|
58
|
+
constraints: { lcp_slug: %r{[^/.]+} },
|
|
59
|
+
format: /(?:json|csv|xml)/ do
|
|
60
|
+
# Saved filters API (must precede /:id to avoid matching "saved-filters" as id)
|
|
61
|
+
scope "saved-filters", as: :saved_filters do
|
|
62
|
+
get "/", to: "saved_filters#index"
|
|
63
|
+
post "/", to: "saved_filters#create"
|
|
64
|
+
patch "/:id", to: "saved_filters#update", as: :update
|
|
65
|
+
delete "/:id", to: "saved_filters#destroy", as: :destroy
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Custom fields management (must precede /:id to avoid matching "custom-fields" as id)
|
|
69
|
+
scope "custom-fields", as: :custom_fields do
|
|
70
|
+
get "/", to: "custom_fields#index"
|
|
71
|
+
get "/manage", to: "custom_fields#manage", as: :manage
|
|
72
|
+
patch "/manage", to: "custom_fields#bulk_update", as: :bulk_update
|
|
73
|
+
get "/new", to: "custom_fields#new", as: :new
|
|
74
|
+
post "/", to: "custom_fields#create"
|
|
75
|
+
get "/:id", to: "custom_fields#show", as: :show
|
|
76
|
+
get "/:id/edit", to: "custom_fields#edit", as: :edit
|
|
77
|
+
patch "/:id", to: "custom_fields#update", as: :update
|
|
78
|
+
put "/:id", to: "custom_fields#update"
|
|
79
|
+
delete "/:id", to: "custom_fields#destroy", as: :destroy
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
post "/parse_ql", to: "resources#parse_ql", as: :parse_ql
|
|
83
|
+
get "/filter_fields", to: "resources#filter_fields", as: :filter_fields
|
|
84
|
+
get "/batch_count", to: "resources#batch_count", as: :batch_count
|
|
85
|
+
get "/export_fields", to: "resources#export_fields", as: :export_fields
|
|
86
|
+
get "/export_profiles", to: "resources#export_profiles", as: :export_profiles
|
|
87
|
+
get "/import_fields", to: "resources#import_fields", as: :import_fields
|
|
88
|
+
get "/import_profiles", to: "resources#import_profiles", as: :import_profiles
|
|
89
|
+
post "/batch_selection", to: "resources#batch_selection", as: :batch_selection
|
|
90
|
+
get "/", to: "resources#index", as: :resources
|
|
91
|
+
get "/select_options", to: "resources#select_options", as: :select_options
|
|
92
|
+
get "/inline_create_form", to: "resources#inline_create_form", as: :inline_create_form
|
|
93
|
+
post "/inline_create", to: "resources#inline_create", as: :inline_create
|
|
94
|
+
get "/new", to: "resources#new", as: :new_resource
|
|
95
|
+
post "/", to: "resources#create", as: :create_resource
|
|
96
|
+
post "/evaluate_conditions", to: "resources#evaluate_conditions_new", as: :evaluate_conditions_new
|
|
97
|
+
post "/actions/:action_name", to: "actions#execute_collection", as: :collection_action
|
|
98
|
+
post "/batch_actions/:action_name", to: "actions#execute_batch", as: :batch_action
|
|
99
|
+
post "/:id/transitions/:transition_name", to: "resources#execute_transition", as: :execute_transition
|
|
100
|
+
post "/:id/approval_tasks/:task_id/approve", to: "approval_tasks#approve", as: :approve_approval_task
|
|
101
|
+
post "/:id/approval_tasks/:task_id/reject", to: "approval_tasks#reject", as: :reject_approval_task
|
|
102
|
+
post "/:id/approval_tasks/:task_id/return_task", to: "approval_tasks#return_task", as: :return_task_approval_task
|
|
103
|
+
post "/:id/approval_tasks/:task_id/claim", to: "approval_tasks#claim", as: :claim_approval_task
|
|
104
|
+
post "/:id/approval_tasks/:task_id/delegate", to: "approval_tasks#delegate", as: :delegate_approval_task
|
|
105
|
+
get "/:id", to: "resources#show", as: :resource
|
|
106
|
+
get "/:id/zones/:zone_name", to: "resources#zone", as: :zone_resource
|
|
107
|
+
get "/:id/edit", to: "resources#edit", as: :edit_resource
|
|
108
|
+
patch "/:id", to: "resources#update", as: :update_resource
|
|
109
|
+
put "/:id", to: "resources#update"
|
|
110
|
+
delete "/:id", to: "resources#destroy", as: :destroy_resource
|
|
111
|
+
post "/:id/restore", to: "resources#restore", as: :restore_resource
|
|
112
|
+
delete "/:id/permanently_destroy", to: "resources#permanently_destroy", as: :permanently_destroy_resource
|
|
113
|
+
patch "/:id/reorder", to: "resources#reorder", as: :reorder_resource
|
|
114
|
+
patch "/:id/reparent", to: "resources#reparent", as: :reparent_resource
|
|
115
|
+
patch "/:id/kanban_move", to: "resources#kanban_move", as: :kanban_move_resource
|
|
116
|
+
post "/:id/evaluate_conditions", to: "resources#evaluate_conditions", as: :evaluate_conditions
|
|
117
|
+
post "/:id/actions/:action_name", to: "actions#execute_single", as: :single_action
|
|
118
|
+
end
|
|
119
|
+
end
|
data/docs/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# LCP Ruby Documentation
|
|
2
|
+
|
|
3
|
+
LCP Ruby is a Rails mountable engine that generates full CRUD information systems from YAML metadata.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
- [Getting Started](getting-started.md) — Install, configure, create your first model/presenter/permission
|
|
8
|
+
- **`lcp new my_app`** — interactive CLI to create a new LCP application (database, format, feature preset)
|
|
9
|
+
- **`rails generate lcp_ruby:install`** — add LCP to an existing Rails app
|
|
10
|
+
- **`rails generate lcp_ruby:entity NAME field:type ...`** — scaffold a complete CRUD entity (model + presenter + permissions + view group). See [Getting Started → Scaffolding new entities](getting-started.md#scaffolding-new-entities) and the [design spec](design/entity_generator.md) for the field grammar and worked examples.
|
|
11
|
+
- [Host Application Guide](guides/host-application.md) — Full app bootstrap, optional dependencies (XLSX, charts, metrics), feature generators
|
|
12
|
+
|
|
13
|
+
## YAML Reference
|
|
14
|
+
|
|
15
|
+
Complete attribute reference for every YAML configuration file:
|
|
16
|
+
|
|
17
|
+
- [Models](reference/models.md) — Fields, validations, associations, scopes, events, display templates, virtual columns, abstract models, inheritance
|
|
18
|
+
- [Types](reference/types.md) — Custom business types (email, phone, url, color, and user-defined)
|
|
19
|
+
- [Presenters](reference/presenters.md) — Index, show, form, search, actions, navigation
|
|
20
|
+
- [Pages](reference/pages.md) — Page YAML format, zones, widget types (kpi_card, text, list, workflow_graph), grid positioning, auto-pages, dialog-only pages, composite pages (semantic layout, tabs, scope_context)
|
|
21
|
+
- [Virtual Forms](reference/virtual_forms.md) — Shared infrastructure for synthetic per-request form-like objects (filter forms, wizards, virtual show, PaaS config UI): VirtualField + VirtualForm + Type::ArrayOf, dispatcher contract, security invariants, GC lifecycle
|
|
22
|
+
- [Page Filters](reference/page_filters.md) — `filter_form:` (value-based, form-syntax fields with cascade + multi) and `scope_filters:` (AR-scope toggles) on dashboards and index composite pages; auto_submit derivation, dirty-state Apply button, `/select_options` fallback chain
|
|
23
|
+
- [Cascading Selects](reference/cascading_selects.md) — `data-lcp-depends-on` contract for child selects, form-level data attributes, forward + reverse cascade, multi-parent UNION, accessibility (aria-busy, polite live region, focus restoration), race semantics
|
|
24
|
+
- [Forms](reference/forms.md) — Form-input renderers shared between presenter forms and synthetic forms: `date_range` paired-date input, `multi_select` cascade activation, i18n keys, cross-links
|
|
25
|
+
- [Dialogs](reference/dialogs.md) — Dialog actions, confirm variants (boolean, role, styled, page-based), routing, virtual model flow
|
|
26
|
+
- [View Groups](reference/view-groups.md) — Navigation menu, view switching, auto-creation
|
|
27
|
+
- [Menu](reference/menu.md) — Configurable navigation: top bar, sidebar, dropdowns, nested submenus, badges, role visibility, responsive modes (overflow_more / hamburger / rail / off-canvas), per-item priority/pin/hide_below, sidebar_toggle marker, mobile header, rail-collapsed flyouts
|
|
28
|
+
- [Custom Fields](reference/custom-fields.md) — Runtime user-defined fields: definitions, types, permissions, querying
|
|
29
|
+
- [Role Source](reference/role-source.md) — DB-backed role model: contract, registry, cache invalidation, generator
|
|
30
|
+
- [Permission Source](reference/permission-source.md) — DB-backed permissions: JSON definitions, registry, cache invalidation, generator
|
|
31
|
+
- [OIDC Authentication](reference/oidc.md) — `auth.yml` provider registry, claim mapping, role source, provisioning, logout modes, redirect_uri override, boot validation rules
|
|
32
|
+
- [Groups](reference/groups.md) — Organizational groups: YAML, DB, host adapter, role mapping, resolution strategies
|
|
33
|
+
- [i18n](reference/i18n.md) — Internationalization: key hierarchy, model/field/enum/menu/action labels, UI framework keys, date formatting
|
|
34
|
+
- [i18n_check](reference/i18n_check.md) — Static-analysis lint for the i18n principle: three passes (DSL AST, YAML schema-driven, boot-time registry), configuration, severity / CI integration, exemption marker
|
|
35
|
+
- [invariant_check](reference/invariant_check.md) — Boot-time validator for permission/page metadata behavioral invariants (AUTH-001..009): custom-scope methods on klass, field_match column, inherits parent resolution, page visible_when shape; severity / CI integration
|
|
36
|
+
- [Permissions](reference/permissions.md) — Roles, CRUD, field access, scopes, record rules
|
|
37
|
+
- [Condition Operators](reference/condition-operators.md) — Shared operator reference for `visible_when`, `record_rules`, `item_classes`, etc. Plus invocation forms (`service:`, `lookup:`)
|
|
38
|
+
- [Dynamic References](reference/dynamic-references.md) — Single source of truth for dotted-string tokens (`current_user.<method>`, `record.<field>`, `current_date`, …) used in scopes, conditions, page `scope_context`, workflow `set_fields`, and field defaults
|
|
39
|
+
- [Auditing](reference/auditing.md) — Change tracking: audit log model, field diffs, JSON/custom field expansion, configuration
|
|
40
|
+
- [Workflow](reference/workflow.md) — State machine: states, transitions, guards, set_fields, readonly_fields, trigger modes, audit log, timeline_states, three definition sources
|
|
41
|
+
- [Workflow Approvals](reference/workflow-approvals.md) — Multi-step approval engine: sequential/parallel strategies, approver types, delegation, bypass, rework
|
|
42
|
+
- [Eager Loading](reference/eager-loading.md) — Auto-detection, manual overrides, strategy resolution, strict_loading
|
|
43
|
+
- [Tree Structures](reference/tree-structures.md) — Declarative tree hierarchies: model options, traversal, reparenting, tree index view
|
|
44
|
+
- [View Slots](reference/view-slots.md) — Extensible page layout injection points: registry, slot names, SlotContext, position ordering
|
|
45
|
+
- [API-Backed Models](reference/api-backed-models.md) — External data sources: REST JSON adapter, host providers, cross-source associations, caching, error handling
|
|
46
|
+
- [Host Controller Integration](reference/host-controller-integration.md) — `bind_to:` connecting LCP metadata to existing AR models, `controller:` / `action_controllers:` per-presenter routing to host controllers, includable `LcpRuby::Controller::*` concerns including `AuthorizedController` (Pundit `verify_authorized` framework guarantee), multi-model authorize helper pattern, `lcp_ruby:host_controller` generator
|
|
47
|
+
- [Monitoring](reference/monitoring.md) — Health check, Prometheus metrics, error log, AS::Notifications events, custom collectors
|
|
48
|
+
- [Export](reference/export.md) — Data export: CSV/XLSX formats, field picker, formatting options, profiles, history, generator
|
|
49
|
+
- [Import](reference/import.md) — Data import: CSV/XLSX upload, column mapping, strategies, nested has_one, profiles, background execution, generator
|
|
50
|
+
- [Theme Variables](reference/theme-variables.md) — All `--lcp-*` CSS custom properties with light/dark values
|
|
51
|
+
- [Engine Configuration](reference/engine-configuration.md) — `LcpRuby.configure` options
|
|
52
|
+
- [Boot / Reload Lifecycle](reference/boot_lifecycle.md) — Engine boot phases, extension hook timing (`on_model_ready`, `on_models_loaded`), dev-mode metadata watcher, `lcp_ruby:ensure_tables` rake + `db:prepare` / `db:setup` / `db:reset` integration, `boot.lcp_ruby` and `reload.lcp_ruby` AS::Notifications events
|
|
53
|
+
- [`lcp_ruby:doctor`](reference/doctor.md) — Health check rake task: install manifest replay, feature state vs. prereqs, environment leaks (`BUNDLE_GEMFILE`, `.envrc`), seeds hygiene; `FORMAT=text|json|summary` and `EXIT_ON=error|warning`; install manifest format and JSON schema for CI consumption
|
|
54
|
+
|
|
55
|
+
## DSL Reference
|
|
56
|
+
|
|
57
|
+
- [Model DSL](reference/model-dsl.md) — Ruby DSL alternative to YAML for model definitions
|
|
58
|
+
- [Presenter DSL](reference/presenter-dsl.md) — Ruby DSL alternative to YAML for presenter definitions (with inheritance)
|
|
59
|
+
- [Types](reference/types.md#dsl-type-definition) — Ruby DSL for defining custom business types
|
|
60
|
+
|
|
61
|
+
## Guides
|
|
62
|
+
|
|
63
|
+
- [Presenters](guides/presenters.md) — Step-by-step guide to building presenters (index, show, form, search, actions) with YAML and DSL examples
|
|
64
|
+
- [Selectbox](guides/selectbox.md) — Association select, cascading selects, remote search, multi-select, tree select, scoping, disabled options, legacy records, codelists
|
|
65
|
+
- [Virtual Columns](guides/virtual-columns.md) — Query-time computed columns: declarative aggregates, SQL expressions, JOINs, GROUP BY, services, auto-include, conditional rendering
|
|
66
|
+
- [Computed Fields](guides/computed-fields.md) — Auto-calculated persisted fields: template interpolation, service logic, arithmetic, comparison with virtual columns
|
|
67
|
+
- [Sequence Fields](guides/sequences.md) — Gap-free auto-numbering: scoped counters, format templates, counter management, rake tasks
|
|
68
|
+
- [Extensibility](guides/extensibility.md) — All extension mechanisms: actions, events, transforms, validators, defaults, computed fields, condition services, scopes, model extensions
|
|
69
|
+
- [Conditional Rendering](guides/conditional-rendering.md) — `visible_when`, `disable_when`, `item_classes`: simple, compound (all/any/not), dot-path, dynamic references, collection conditions, lookup value references, DSL builder
|
|
70
|
+
- [Custom Actions](guides/custom-actions.md) — Writing domain-specific operations beyond CRUD
|
|
71
|
+
- [Event Handlers](guides/event-handlers.md) — Responding to lifecycle events and field changes
|
|
72
|
+
- [Custom Types](guides/custom-types.md) — Defining custom business types (percentage, postal_code, slug, hex_color)
|
|
73
|
+
- [View Groups](guides/view-groups.md) — Multi-view navigation and view switcher setup
|
|
74
|
+
- [Menu](guides/menu.md) — Custom navigation menus: dropdowns, nested submenus, sidebar, combined layouts, badges
|
|
75
|
+
- [Renderers](guides/display-types.md) — Visual guide to all built-in renderers (including workflow_timeline, workflow_badge, dot-notation, templates, and collections)
|
|
76
|
+
- [Custom Renderers](guides/custom-renderers.md) — Creating custom renderers for host applications
|
|
77
|
+
- [Attachments](guides/attachments.md) — File upload with Active Storage
|
|
78
|
+
- [Userstamps](guides/userstamps.md) — Automatic created_by / updated_by tracking: setup, name snapshots, presenter display, seeds
|
|
79
|
+
- [Record Aliases & Slug Fields](guides/record-aliases.md) — Human-readable URLs (`/articles/my-slug`), user-context aliases (`/preferences/me`), dynamic shortcuts (`/issues/last`)
|
|
80
|
+
- [Soft Delete](guides/soft-delete.md) — Discard/restore, cascade, archive presenters, permissions
|
|
81
|
+
- [Action Buttons & Pipelines](guides/action-buttons.md) — All button contexts (collection, single, batch, form), form submit buttons, save + transition + action pipelines, show page pipelines
|
|
82
|
+
- [Batch Actions](guides/batch-actions.md) — Multiselect, batch delete/restore, custom batch actions, selection modes
|
|
83
|
+
- [Auditing](guides/auditing.md) — Change tracking: setup, field filtering, JSON expansion, custom writer, show page integration
|
|
84
|
+
- [Workflow](guides/workflow.md) — State machine setup: transitions, guards, readonly fields, events, system triggers, audit logging, workflow renderers, testing
|
|
85
|
+
- [Eager Loading](guides/eager-loading.md) — N+1 prevention, strict_loading, manual overrides
|
|
86
|
+
- [Tree Structures](guides/tree-structures.md) — Declarative tree hierarchies: setup, tree index view, drag-and-drop reparenting, search
|
|
87
|
+
- [Custom Fields](guides/custom-fields.md) — Runtime user-defined fields: enabling, defining, sections, permissions, programmatic access
|
|
88
|
+
- [Role Source](guides/role-source.md) — DB-backed role management: setup, validation, cache, testing
|
|
89
|
+
- [Permission Source](guides/permission-source.md) — DB-backed permission management: runtime editing, JSON definitions, testing
|
|
90
|
+
- [OIDC Setup](guides/oidc-setup.md) — IdP App registration walkthrough, generator, ENV setup options (export / dotenv / encrypted credentials), role mapping, troubleshooting (CSRF, cookie overflow, redirect URI mismatch, hostname consistency)
|
|
91
|
+
- [Groups](guides/groups.md) — Organizational groups: YAML, DB, host adapter, testing
|
|
92
|
+
- [Hierarchical Authorization](guides/hierarchical-authorization.md) — Multi-level parent-child access control (factory → production line → machine → sensor reading)
|
|
93
|
+
- [Permissions](guides/permissions.md) — `extends:` keyword and coverage merge with `_default`: pattern catalog, anti-patterns, decision tree, validator output reference
|
|
94
|
+
- [Inherited Permissions](guides/inherited-permissions.md) — Declarative `inherits_from:` cascade for visibility (read time) and create-time FK validation; bind_to host classes; soft-delete and transitive chains
|
|
95
|
+
- [Impersonation](guides/impersonation.md) — "View as Role X" for testing permissions
|
|
96
|
+
- [Tiles View](guides/tiles.md) — Card grid layout for index pages: tile configuration, sort dropdown, per-page selector, summary bar
|
|
97
|
+
- [Dashboards](guides/dashboards.md) — Standalone grid pages: KPI cards, text widgets, list widgets, presenter zones, landing page
|
|
98
|
+
- [Composite Pages](guides/composite-pages.md) — Record-bound multi-zone pages: semantic layout, tabs, scope_context, per-zone authorization, index composites, composite dialogs, dialog nesting
|
|
99
|
+
- [Dialogs](guides/dialogs.md) — Quick create/edit dialogs, virtual model dialogs, styled/page-based confirms, composite dialogs, dialog nesting
|
|
100
|
+
- [Rendering Extension Points](guides/rendering-extension-points.md) — Custom render blocks vs. view slots: when to use which, available locals, worked examples
|
|
101
|
+
- [View Slots](guides/view-slots.md) — Extending page layouts: custom toolbar buttons, widgets, conditional components, overriding built-ins
|
|
102
|
+
- [API-Backed Models](guides/api-backed-models.md) — Integrating external REST APIs and host-provided data sources: setup, cross-source associations, caching, error handling, testing
|
|
103
|
+
- [Host Controller Integration](guides/host-controller-integration.md) — Connecting LCP to existing host AR models with `bind_to:`, routing presenter slugs to host controllers (`controller:` / `action_controllers:`), includable controller concerns, `lcp_ruby:host_controller` generator
|
|
104
|
+
- [Monitoring](guides/monitoring.md) — Health check, Prometheus + Grafana, error log, custom collectors, testing
|
|
105
|
+
- [Export](guides/export.md) — Data export setup: CSV/XLSX, field selection, profiles, history, permissions
|
|
106
|
+
- [Import](guides/import.md) — Data import setup: CSV/XLSX upload, strategies, nested has_one associations, profiles, permissions
|
|
107
|
+
- [Theming](guides/theming.md) — Dark mode, UI density, border radius, CSS variables, theme persistence
|
|
108
|
+
- [Developer Tools](guides/developer-tools.md) — `lcp_ruby:validate`, `lcp_ruby:erd`, `lcp_ruby:permissions`, `lcp_ruby:create_admin`, `lcp_ruby:i18n_lint` rake tasks + `LcpRuby/NoHardcodedI18nString` RuboCop cop
|
|
109
|
+
- [Adding a Locale](guides/adding-locale.md) — Workflow for adding a new language: engine UI vs host-app domain layers, step-by-step checklist, plural forms, devise, tooling, troubleshooting
|
|
110
|
+
|
|
111
|
+
## Debugging
|
|
112
|
+
|
|
113
|
+
Practical `rails runner` recipes for inspecting LCP internals at runtime:
|
|
114
|
+
|
|
115
|
+
- [Overview](guides/debugging/README.md) — Entry points, general tips
|
|
116
|
+
- [Models](guides/debugging/models.md) — Columns, validations, scopes, associations, inheritance, schema comparison
|
|
117
|
+
- [Controllers](guides/debugging/controllers.md) — Routing, callbacks, auth chain, Warden vs controller, layout
|
|
118
|
+
- [Permissions](guides/debugging/permissions.md) — Role checks, field access, record rules, condition evaluation
|
|
119
|
+
- [Presenters](guides/debugging/presenters.md) — Columns, layout, actions, search, view groups, tiles
|
|
120
|
+
- [Metadata](guides/debugging/metadata.md) — Loader, registry, boot validation, configuration, workflows, types
|
|
121
|
+
- [Data](guides/debugging/data.md) — DB state, duplicates, custom fields, workflow state, audit logs, seeds verification
|
|
122
|
+
|
|
123
|
+
## Design Documents
|
|
124
|
+
|
|
125
|
+
Implemented:
|
|
126
|
+
|
|
127
|
+
- [Record Positioning](design/record_positioning.md) — Drag-and-drop reordering of top-level records with the `positioning` gem
|
|
128
|
+
- [External Field Accessors](design/fields_accessors.md) — Virtual fields with `source: external` and `source: { service: }` accessor delegation
|
|
129
|
+
- [Unified Condition Operators](design/unified_condition_operators.md) — Strict condition evaluation, shared 12-operator set across all contexts
|
|
130
|
+
- [Record Rules Action Visibility](design/record_rules_action_visibility.md) — Automatic hiding of edit/destroy buttons based on record_rules
|
|
131
|
+
- [Inline Collection Editor](design/inline_collection_editor.md) — Unified editing for nested associations, JSON arrays, and bulk records: row-scoped conditions, JSON field source, virtual models, sub-sections, presenter-driven manage page
|
|
132
|
+
- [Groups, Roles & Org Structure](design/groups_roles_and_org_structure.md) — Enterprise organizational units, groups, and group-to-role mapping
|
|
133
|
+
- [Model Options Infrastructure](design/model_options_infrastructure.md) — Shared patterns for model-level feature flags (soft_delete, auditing, userstamps, tree)
|
|
134
|
+
- [Userstamps](design/userstamps.md) — Automatic `created_by_id` / `updated_by_id` tracking
|
|
135
|
+
- [Soft Delete](design/soft_delete.md) — Discard/restore support with `discarded_at` timestamp, cascade discard/undiscard, archive presenters
|
|
136
|
+
- [Auditing](design/auditing.md) — Native change tracking and audit trail
|
|
137
|
+
- [Tree Structures](design/tree_structures.md) — Declarative parent-child hierarchies with traversal, cycle detection, and tree index view
|
|
138
|
+
- [Saved Filters & Parameterized Scopes](design/saved_filters.md) — User-persistent named filters with visibility levels, parameterized scopes with typed parameters, generator, CRUD API
|
|
139
|
+
- [Aggregate Columns](design/aggregate_columns.md) — Virtual computed columns (COUNT, SUM, MIN, MAX, AVG) from associated records, custom SQL, service-based aggregates
|
|
140
|
+
- [Virtual Columns](design/virtual_columns.md) — Generalized query extensions: expressions, JOINs, GROUP BY, auto-include, backward-compatible with aggregates
|
|
141
|
+
- [Tiles View](design/tiles_view.md) — Card grid layout for index pages with sort dropdown, per-page selector, and summary bar
|
|
142
|
+
- [Row Styling](design/row_styling.md) — Conditional CSS classes on index rows (tables, trees, tiles) based on field conditions or services
|
|
143
|
+
- [Array Field Type](design/array_field_type.md) — Native array fields with typed items, array-specific operators, and auto-generated scopes
|
|
144
|
+
- [API-Backed Models](design/api_backed_models.md) — External data sources (REST JSON, host adapters): read-only access, cross-source associations, caching, graceful degradation
|
|
145
|
+
- [Pages — Unified Rendering Abstraction](design/composite_pages_v2.md) — Tier 1 + Tier 1b + Tier 2 Phase A: pages, zones, auto-pages, grid layout, widget zones, dashboard convergence, composite pages with semantic layout and tabs
|
|
146
|
+
- [Modal Dialogs](design/modal_dialogs.md) — Dialog actions, virtual model flow, confirm variants, routing, authorization
|
|
147
|
+
- [Dashboards](design/dashboards.md) — Tier 1b: standalone grid pages with KPI cards, text, list widgets, presenter zones
|
|
148
|
+
- [Chart Widget — Multi-Series and Configuration Options](design/chart_widget_multi_series.md) — Multi-series `series:` array, `column` chart type, declarative Chartkick options (legend, stacked, axis titles, value formatting, colors, sort, library escape hatch), Okabe-Ito default palette, empty-state banner, defensive payload guards
|
|
149
|
+
- [Workflow State Machine](design/workflow_state_machine.md) — Metadata-driven state machine: states, transitions, guards, audit log, three definition sources
|
|
150
|
+
- [Background Jobs](design/background_jobs.md) — Async job execution: declarative/class handlers, multi-step jobs, retry, cancellation, triggers, scheduling, three definition sources
|
|
151
|
+
- [Grouped Query Presenter](design/grouped_query_presenter.md) — GROUP BY queries with aggregates, date period grouping, HAVING, row_click drill-through
|
|
152
|
+
- [Nested Menu Dropdowns](design/nested_menu_dropdowns.md) — Sub-groups in top menu and sidebar dropdowns
|
|
153
|
+
- [Responsive Menu](design/responsive-menu.md) — Phase 0–2 implementation: lcp-dropdown primitive (touch/keyboard), top-nav modes (none/wrap/overflow_more/hamburger), sidebar rail + off-canvas, cookie persistence, auto-injected sidebar_toggle, mobile header, rail-collapsed flyouts
|
|
154
|
+
- [Dev Toolbar](design/dev_toolbar.md) — Developer tools overlay for metadata inspection
|
|
155
|
+
- [HR Demo App](design/demo-app-hr.md) — HR management system demo application design
|
|
156
|
+
- [Workflow Renderers](design/workflow_renderers.md) — Built-in workflow visualization: `workflow_timeline` (linear progress), `workflow_badge` (colored status badge), `workflow_graph` (Mermaid.js state diagram), auto-detection
|
|
157
|
+
- [Model Inheritance](design/model_inheritance.md) — Abstract base models and Single Table Inheritance (STI)
|
|
158
|
+
- [Sequence Fields](design/sequences.md) — Gap-free auto-numbering with scoped counters, format templates, and counter management
|
|
159
|
+
- [Deep Filter Enhancements](design/recursive_association_field_picker.md) — Recursive association field picker and recursive condition nesting (AND/OR tree)
|
|
160
|
+
- [Advanced Conditions](design/advanced_conditions.md) — Compound conditions (all/any/not), dynamic value references, dot-path fields, collection quantifiers, value services, lookup value references
|
|
161
|
+
- [Workflow Approvals](design/workflow_approvals.md) — Multi-step approval engine on top of the state machine: steps, strategies, delegation, rework
|
|
162
|
+
- [Context-Aware View Switcher](design/view_switcher_context.md) — View switcher integration with context-aware presenters
|
|
163
|
+
- [Custom Render Blocks](design/custom_render_blocks.md) — Host-app partial delegation: custom sections, custom zones, page-level render_with
|
|
164
|
+
- [Monitoring & Metrics](design/monitoring.md) — Health check, Prometheus metrics, error log, AS::Notifications instrumentation
|
|
165
|
+
- [Export](design/export.md) — Data export: collection/batch export, field picker, formatting, profiles, history
|
|
166
|
+
- [Pagination Footer](design/pagination_footer.md) — Unified pagination bar: per-page selector, record count, styled page links, First/Last toggle
|
|
167
|
+
- [Import](design/import.md) — Server-side data import with file upload, column mapping, strategy selection, association lookup, profiles, background execution
|
|
168
|
+
- [Import Nested has_one](design/import_nested_has_one.md) — Import flat CSV rows into parent + has_one associations: dot-notation mapping, nested_blank_strategy, auto-mapping, permission filtering
|
|
169
|
+
- [Search Parameter Controls](design/search_parameter_controls.md) — Typed filter controls (dropdowns, toggles, ranges) in the presenter search toolbar, generating Ransack `?f[...]` params
|
|
170
|
+
- [Theming](design/theming.md) — Dark mode, CSS custom property system, UI density, border radius, theme persistence, vendor CSS dark variants
|
|
171
|
+
- [Host App Controller Integration](design/host_app_controller_integration.md) — `bind_to:` for existing host AR models (Phase A), controller concern extraction (Phase B1), `controller:` / `action_controllers:` per-presenter routing (Phase B2), `lcp_ruby:host_controller` generator (Phase B3)
|
|
172
|
+
- [bind_to Managed Fields and Associations](design/bind_to_managed_fields_and_associations.md) — Per-item `lcp_managed: true` flag on `fields:` and `associations:` of `bind_to:` models so LCP can additively add columns and declare AR macros on host classes (resolves school audit issue #22 and the deferred `bind_to_associations:` future from the original `bind_to` design)
|
|
173
|
+
- [Association `primary_key`](design/association_primary_key.md) — Per-association override of the target join column so `belongs_to` / `has_many` / `has_one` can join on a business key (`vema_code`, `iso_code`, `sku`) instead of the surrogate `id`; FK column type inferred from the referenced column; Layer B consumers (form selects, cascading selects, tree selects, page parameters [retired in PR 5; replaced by [page filters](reference/page_filters.md)], import/export field trees, virtual columns) updated end-to-end for string business keys
|
|
174
|
+
- [Record Aliases](design/record_aliases.md) — Presenter-level alias resolution (`/preferences/me`, `/issues/last`) and model-level slug fields (`/articles/quarterly-report`): resolve chain, strategies, URL preservation, validation pipeline
|
|
175
|
+
- [Permission `_default` Coverage Merge](design/permissions_default_role_coverage.md) — `extends:` keyword and coverage-merge default for per-model permission YAML files (roles, field_overrides, record_rules inherit from `_default`); pre/post-merge validators; `lcp_ruby:permissions:resolve` rake task
|
|
176
|
+
- [`lcp_ruby:entity` Generator](design/entity_generator.md) — Single-command scaffold of model + presenter + permissions + view group from a CLI field grammar (v1: types/associations, v2: DB constraints + feature flags, v3: sections/renderers/color_map/link/polymorphic). Includes auto-link of belongs_to in index/show, synthetic `position`/`parent_id` fields for `--positioning`/`--tree`, polymorphic skip from index/show, reverse-association post-install hints (and optional `--auto-add-inverses` for DSL targets), and bash-brace-expansion guidance.
|
|
177
|
+
- [Entity Generator `--menu` Flag](design/entity_generator_menu_flag.md) — `rails g lcp_ruby:entity … --menu=[<section>:]ROOT|<DropdownLabel>[:bottom|:right] --menu-icon=<lucide>` writes a `- view_group: <name>` entry into `config/lcp_ruby/menu.yml` at scaffold time above the seeded `# lcp:menu` marker. Pairs with `lcp_ruby:install --menu-layout=top|sidebar|both` (and `lcp new`'s wizard prompt) for marker seeding.
|
|
178
|
+
- [Menu Modes + Auto-Append Polish](design/menu_modes_and_skeleton.md) — `:auto` (default) vs `:strict` mode semantics, auto-append transparency log surfacing every auto-appended view group at boot, B59 cross-presenter dedup, `presenter.menu_position` deprecation info-warning.
|
|
179
|
+
- [Boot / Reload Lifecycle](design/boot_reload_lifecycle.md) — Dev-mode metadata watcher (closes school-audit B1 + B2: permission YAML reload + Duplicate-presenter), `db:prepare` / `db:setup` enhanced with `lcp_ruby:ensure_tables` post-action that idempotently materialises platform tables in topological order (closes B4 — `db:drop && db:prepare && db:seed` works in one process), `reload.lcp_ruby` AS::Notifications event symmetric to `boot.lcp_ruby`. Builds on the `LcpRuby.on_models_loaded` hook and `RELOAD_MUTEX` from authorization hardening v1.
|
|
180
|
+
- [Generator Prerequisites Registry & `lcp_ruby:doctor`](design/generator_prerequisites_registry.md) — Declarative `FeatureRegistry` + `Prerequisites` Thor concern collapse three ad-hoc prereq checks (import/entity/api_tokens) into one source of truth. `lcp new` writes an install manifest; the `lcp_ruby:doctor` rake task replays it and reports feature state, environment leaks, and seed hygiene. `install_auth` now ships the `user.rb` metadata model directly (replacing `api_tokens`' buggy fallback).
|
|
181
|
+
|
|
182
|
+
In Progress:
|
|
183
|
+
|
|
184
|
+
- [Advanced Search & Filter Builder](design/advanced_search.md) — Type-aware quick search, Ransack-based filter builder, custom filter methods, query language (Phase 0–4 implemented)
|
|
185
|
+
- [Page Layouts & View Slots](design/page_layout_and_slots.md) — Extensible page layout system: slot registry (Phase 1 implemented), layout variants (planned)
|
|
186
|
+
- [Multiselect and Batch Actions](design/multiselect_and_batch_infrastructure.md) — Checkbox selection, batch delete/restore/permanently_destroy, selection modes, result logging (infrastructure + batch delete implemented; background execution deferred)
|
|
187
|
+
|
|
188
|
+
Partially Implemented:
|
|
189
|
+
- [Form Submit Actions](design/form_submit_actions.md) — Configurable form submit buttons with redirect, set_fields, pipeline execution, cross-presenter redirect, overflow dropdown (Phase 1–3 implemented)
|
|
190
|
+
- [AJAX Error Handling](design/ajax_error_handling.md) — Graceful error handling for Turbo/fetch requests
|
|
191
|
+
- [~~Workflow & Approvals~~](design/workflow_and_approvals.md) — Outdated, superseded by the two documents above
|
|
192
|
+
|
|
193
|
+
Proposed:
|
|
194
|
+
|
|
195
|
+
- [Agent Affordances](design/agent_affordances.md) — *(Draft)* Make skills + curated docs + an AGENTS.md/CLAUDE.md entrypoint available to AI agents in installed-gem host apps (not just inside this repo)
|
|
196
|
+
- [Cached Aggregates](design/cached_aggregates.md) — Materialized aggregate values with automatic invalidation
|
|
197
|
+
- [Context-Aware Presenters](design/context_aware_presenters.md) — Parent-context-dependent presenter resolution for polymorphic sub-resources
|
|
198
|
+
- [Data Retention](design/data_retention.md) — Automatic purge policies for audit logs, soft-deleted records, and attachments
|
|
199
|
+
- [Derived Associations](design/derived_associations.md) — Computed associations derived from aggregate/virtual columns
|
|
200
|
+
- [Document Management](design/document_management.md) — File-centric document management (versioning, preview, metadata, workflows)
|
|
201
|
+
- [Dynamic Presenters](design/dynamic_presenters.md) — DB-backed presenter overrides (user/role/system personalization layer)
|
|
202
|
+
- [Hub Pages](design/hub_pages.md) — Hero banner + navigation cards landing pages
|
|
203
|
+
- [Import & Export](design/import_export.md) — Data import and export (CSV, Excel, JSON)
|
|
204
|
+
- [Multi-Step Forms](design/multi_step_forms.md) — Wizard-style forms with step navigation
|
|
205
|
+
- [PaaS — AI-Powered App Builder](design/paas.md) — AI agent builds LCP apps from natural language; container management, chat UI, code-server
|
|
206
|
+
- [Workflow Async Completion](design/workflow_async_completion.md) — Declarative `async_completion` on transitions for long-running operations
|
|
207
|
+
- [Scoped Permissions](design/scoped_permissions.md) — Context-dependent permission definitions for polymorphic sub-resources
|
|
208
|
+
- [Timeline View](design/timeline_view.md) — Timeline index layout for chronological data
|
|
209
|
+
- [User Menu](design/user-menu.md) — User menu dropdown (profile, settings, logout)
|
|
210
|
+
- [Chess Demo App](design/demo-app-chess.md) — Chess training academy demo application design
|
|
211
|
+
- [E-Shop Demo App](design/demo-app-eshop.md) — E-shop demo application design
|
|
212
|
+
- [External Database Models](design/external_database_models.md) — External DB tables (read-only and writable), local overlay extensions, cross-DB filtering, feature compatibility, unified presenter
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
Research:
|
|
216
|
+
|
|
217
|
+
- [Basepack Search Lessons](design/basepack_lessons.md) — Lessons learned from Basepack search system for advanced search design
|
|
218
|
+
|
|
219
|
+
## Internals
|
|
220
|
+
|
|
221
|
+
- [Architecture](architecture.md) — Module structure, data flow, controllers, views
|
|
222
|
+
|
|
223
|
+
## Examples
|
|
224
|
+
|
|
225
|
+
- [Example Apps](examples.md) — TODO and CRM app walkthroughs
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
LCP Ruby is a Rails mountable engine that generates full CRUD information systems from YAML metadata. Models, presenters (UI config), and permissions are defined in YAML files. The engine dynamically builds ActiveRecord models, database tables, controllers, and views at runtime.
|
|
6
|
+
|
|
7
|
+
## Data Flow
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
YAML metadata (config/lcp_ruby/)
|
|
11
|
+
├── types/*.yml → Metadata::Loader → TypeDefinition → TypeRegistry
|
|
12
|
+
├── models/*.yml → Metadata::Loader → ModelInheritanceResolver → ModelDefinition
|
|
13
|
+
├── presenters/*.yml → Metadata::Loader → PresenterDefinition
|
|
14
|
+
├── permissions/*.yml → Metadata::Loader → PermissionDefinition
|
|
15
|
+
├── jobs/*.yml → Metadata::Loader → BackgroundJobs::Definition
|
|
16
|
+
└── menu.yml → Metadata::Loader → MenuDefinition → MenuItem (with badges)
|
|
17
|
+
↓
|
|
18
|
+
ModelFactory::Builder.build → LcpRuby::Dynamic::<Name>
|
|
19
|
+
(creates AR class + DB table + validations + transforms + associations + scopes)
|
|
20
|
+
(virtual models with table_name: _virtual are skipped — metadata only, no AR class)
|
|
21
|
+
(API models → ApiBuilder creates ActiveModel class, skips DB/AR-specific applicators)
|
|
22
|
+
↓
|
|
23
|
+
LcpRuby.registry.register(name, model_class)
|
|
24
|
+
↓
|
|
25
|
+
DataSource::Setup.apply!(loader) → instantiate adapters, wrap with cache/resilient,
|
|
26
|
+
attach to API model classes, apply cross-source associations
|
|
27
|
+
↓
|
|
28
|
+
CustomFields::Setup.apply!(loader) → contract validation, registry, handlers, accessors, scopes
|
|
29
|
+
↓
|
|
30
|
+
Roles::Setup.apply!(loader) → contract validation, registry, change handler (if role_source == :model)
|
|
31
|
+
↓
|
|
32
|
+
Permissions::Setup.apply!(loader) → contract validation, registry, change handler, definition validator (if permission_source == :model)
|
|
33
|
+
↓
|
|
34
|
+
Groups::Setup.apply!(loader) → YAML/DB/host loader, registry, change handler (if group_source != :none)
|
|
35
|
+
↓
|
|
36
|
+
Auditing::Setup.apply!(loader) → contract validation, registry mark_available! (if any model has auditing: true)
|
|
37
|
+
↓
|
|
38
|
+
Pages::Setup.apply!(loader) → contract validation, registry, change handler, definition validator (if page_source == :model)
|
|
39
|
+
loader.merge_db_pages! → loads DB page definitions, overrides YAML/auto pages, recreates auto-pages
|
|
40
|
+
↓
|
|
41
|
+
BackgroundJobs::Setup.apply!(loader) → contract validation, sources, resolver,
|
|
42
|
+
triggers, schedule sync (if job definitions exist)
|
|
43
|
+
↓
|
|
44
|
+
Export::Setup.apply!(loader) → register export_config virtual model,
|
|
45
|
+
export_dialog page/presenter, ExportHandler event handler
|
|
46
|
+
↓
|
|
47
|
+
Metrics::Setup.apply!(loader) → resolve :auto error_log_enabled, register Prometheus metrics,
|
|
48
|
+
activate AS::Notifications subscriber, discover custom collectors from app/lcp_metrics/
|
|
49
|
+
↓
|
|
50
|
+
ConditionServiceRegistry.discover! → condition services from app/condition_services/
|
|
51
|
+
Services::Registry.discover! → data providers from app/lcp_services/data_providers/
|
|
52
|
+
Display::RendererRegistry.register_built_ins! → 28 built-in renderers + badge renderers
|
|
53
|
+
Display::RendererRegistry.discover! → custom renderers from app/renderers/
|
|
54
|
+
ViewSlots::Registry.register_built_ins! → 11 built-in slot components (toolbar, filters, pagination)
|
|
55
|
+
↓
|
|
56
|
+
Pages::Resolver → slug/name lookup → PageDefinition → zones → presenters
|
|
57
|
+
↓
|
|
58
|
+
Engine routes (/:lcp_slug/*) → ResourcesController
|
|
59
|
+
Dialog routes (/lcp_dialog/:page_name/*) → DialogsController
|
|
60
|
+
(CRUD with Pundit authorization, presenter-driven UI, conditional rendering,
|
|
61
|
+
composite pages with semantic layout, tabs, scope_context scoping)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Key Modules
|
|
65
|
+
|
|
66
|
+
| Module | Location | Purpose |
|
|
67
|
+
|--------|----------|---------|
|
|
68
|
+
| `Metadata` | `lib/lcp_ruby/metadata/` | Parses YAML into definition objects (ModelDefinition, PresenterDefinition, etc.). ModelHashMerger + ModelInheritanceResolver handle abstract model inheritance (two-pass load, topological sort, hash merge, abstract exclusion) |
|
|
69
|
+
| `Types` | `lib/lcp_ruby/types/` | TypeRegistry, TypeDefinition, ServiceRegistry, built-in types (email, phone, url, color), transforms (strip, downcase, normalize_url, normalize_phone) |
|
|
70
|
+
| `ModelFactory` | `lib/lcp_ruby/model_factory/` | Builds dynamic AR models: Builder orchestrates SchemaManager, ValidationApplicator, TransformApplicator, AssociationApplicator, VirtualColumnApplicator, ScopeApplicator, PositioningApplicator, UserstampsApplicator, SoftDeleteApplicator, AuditingApplicator, TreeApplicator, SequenceApplicator (gap-free auto-numbering with scoped counters). ApiBuilder builds ActiveModel classes for API-backed models. ApiAssociationApplicator creates cross-source association accessors |
|
|
71
|
+
| `Sequences` | `lib/lcp_ruby/sequences/` | SequenceManager (admin API: set/current/list counter values), `build_scope_key` (scope hash to string key). Counter table via generator (`lcp_ruby:gapfree_sequences`) |
|
|
72
|
+
| `DataSource` | `lib/lcp_ruby/data_source/` | API-backed model infrastructure: Base (contract), RestJson (HTTP adapter), Host (provider delegation), CachedWrapper (Rails.cache TTL), ResilientWrapper (error handling), ApiModelConcern (ActiveModel mixin), ApiFilterTranslator (Ransack→portable filter translation), ApiPreloader (batch N+1 prevention), ApiErrorPlaceholder (graceful degradation), Registry, Setup (boot orchestration) |
|
|
73
|
+
| `VirtualColumns` | `lib/lcp_ruby/virtual_columns/` | Builder: injects SQL subqueries, expressions, JOINs, and GROUP BY into ActiveRecord scopes. Collector: auto-detects needed VCs from presenter metadata per context. Supports declarative aggregates, expression columns, JOIN-based columns, service-based VCs with `:current_user` placeholder, soft-delete filtering, and COALESCE defaults. `Aggregates::QueryBuilder` is a backward-compat alias |
|
|
74
|
+
| `Presenter` | `lib/lcp_ruby/presenter/` | UI layer: Resolver (find by slug), LayoutBuilder (form/show sections + normalize_json_field_section for json_field: sources + sub-section enrichment), ColumnSet (visible columns), ActionSet (visible actions with record_rules integration via action_permitted_for_record?), IncludesResolver (auto-detects and applies eager loading from presenter metadata), FieldValueResolver (dot-path, template, FK, and simple field resolution with permission checks) |
|
|
75
|
+
| `CustomFields` | `lib/lcp_ruby/custom_fields/` | Registry (per-model definition cache), Applicator (dynamic accessors + validations + defaults + stale cleanup), ContractValidator (boot-time model contract checks), Query (DB-portable JSON queries with field name validation), DefinitionChangeHandler (cache invalidation), Setup (shared boot logic with contract validation), Utils (env-aware JSON/numeric parsing) |
|
|
76
|
+
| `Roles` | `lib/lcp_ruby/roles/` | Registry (thread-safe role name cache), ContractValidator (boot-time model contract checks), ChangeHandler (after_commit cache invalidation), Setup (boot orchestration). Only active when `role_source == :model` |
|
|
77
|
+
| `Permissions` | `lib/lcp_ruby/permissions/` | Registry (per-model PermissionDefinition cache), ContractValidator (boot-time model contract checks), ChangeHandler (after_commit cache invalidation + PolicyFactory clear), DefinitionValidator (JSON validation on save), SourceResolver (DB → YAML priority chain), Setup (boot orchestration). Only active when `permission_source == :model` |
|
|
78
|
+
| `Groups` | `lib/lcp_ruby/groups/` | Contract (interface), Registry (thread-safe, delegates to loader), YamlLoader (static groups from YAML), ModelLoader (DB queries), HostLoader (adapter delegation), ContractValidator (group/membership/mapping models), ChangeHandler (after_commit cache invalidation), Setup (boot orchestration by group_source). Integrates with PermissionEvaluator via role_resolution_strategy |
|
|
79
|
+
| `Display` | `lib/lcp_ruby/display/` | BaseRenderer (base class), 28 built-in renderer classes in `renderers/` (incl. WorkflowBadge, WorkflowTimeline), badge renderers (CountBadge, TextBadge, IconBadge), RendererRegistry (registers built-ins + auto-discovers host renderers from `app/renderers/`) |
|
|
80
|
+
| `Authorization` | `lib/lcp_ruby/authorization/` | PolicyFactory (dynamic Pundit policies), PermissionEvaluator (can?, can_for_record? with alias resolution, readable_fields, writable_fields, with optional role validation via Roles::Registry), ScopeBuilder |
|
|
81
|
+
| `Events` | `lib/lcp_ruby/events/` | Dispatcher + HandlerRegistry. Host apps define handlers in `app/event_handlers/` |
|
|
82
|
+
| `Actions` | `lib/lcp_ruby/actions/` | ActionExecutor + ActionRegistry. Host apps define custom actions in `app/actions/` |
|
|
83
|
+
| `Conditions` | `lib/lcp_ruby/condition_evaluator.rb`, `lib/lcp_ruby/condition_service_registry.rb`, `lib/lcp_ruby/dsl/condition_builder.rb` | ConditionEvaluator (strict: 15 operators, raises ConditionError on unknown operator/missing field), ConditionServiceRegistry. Supports compound (all/any/not), dot-path fields, collection quantifiers, dynamic value references (field_ref, current_user, date, service, lookup). DSL via `ConditionBuilder.build` block and `ConditionBuilder.lookup` helper. All condition callers (PermissionEvaluator, ActionSet, views) delegate to ConditionEvaluator. Host apps define condition services in `app/condition_services/` |
|
|
84
|
+
| `Search` | `lib/lcp_ruby/search/` | QuickSearch (type-aware text search), ParamSanitizer (filter param cleanup), FilterParamBuilder (LCP operators to Ransack predicates), OperatorRegistry (type-to-operator mapping), CustomFilterInterceptor (filter_* method detection and interception), CustomFieldFilter (JSON column queries with type casting), FilterMetadataBuilder (permission-aware JSON metadata for the visual filter builder), QueryLanguageParser (recursive descent QL parser), QueryLanguageSerializer (condition tree to QL text), ParameterizedScopeApplicator (typed parameter casting, min/max clamping, filter_*/scope dispatch). Ransack model setup (`ransackable_attributes`, `ransackable_associations`) handled by `ModelFactory::RansackApplicator` at boot |
|
|
85
|
+
| `SavedFilters` | `lib/lcp_ruby/saved_filters/` | Generator-based saved filter model (not hardcoded). SavedFiltersGenerator creates model/presenter/permissions YAML. Presenter config via `saved_filters` block inside `advanced_filter` (enabled, display mode, max_visible_pinned). Visibility: personal/role/group/global with ownership record_rules |
|
|
86
|
+
| `Attachments` | `lib/lcp_ruby/model_factory/attachment_applicator.rb` | Applies Active Storage macros (has_one_attached/has_many_attached), validations (size, content_type, max_files), and variant config to dynamic models |
|
|
87
|
+
| `Positioning` | `lib/lcp_ruby/model_factory/positioning_applicator.rb` | Applies `positioning` gem macro to positioned models; SchemaManager creates unique indices on scope + position columns (except SQLite) |
|
|
88
|
+
| `Auditing` | `lib/lcp_ruby/auditing/` | Registry (available? flag), ContractValidator (audit model contract checks), AuditWriter (field diffs, JSON/custom field expansion, nested changes), Setup (boot orchestration). AuditingApplicator installs AR callbacks on audited models |
|
|
89
|
+
| `UserSnapshot` | `lib/lcp_ruby/user_snapshot.rb` | Captures `{id, email, name, role}` from user objects; used by auditing and userstamps |
|
|
90
|
+
| `BulkUpdater` | `lib/lcp_ruby/bulk_updater.rb` | `tracked_update_all` wrapper with yield hook for post-update callbacks (auditing, events) |
|
|
91
|
+
| `Pages` | `lib/lcp_ruby/pages/` | Resolver (slug/name lookup), ScopeContextResolver (delegates to `LcpRuby::DynamicReferences::Resolver` — see [Dynamic References](reference/dynamic-references.md) for the dotted-string gramatika and depth limits), auto-page creation from presenters, PageDefinition (name, slug, model, layout, dialog_config, zones; composite helpers: `composite?`, `semantic?`, `zones_for_area`, `tab_zones`, `has_tabs?`, `has_sidebar?`, `has_below?`, `grid_template_columns`, `form_zone`, `main_zone`), ZoneDefinition (presenter/widget zones, grid positioning, visible_when, scope_context, label_key, `default_scope`, `width` (1-12), `filters` (`:full`/`:quick`/`:none`), `record_click` (`:navigate`/`:dialog`/`:none`), `submit_redirect` (`:self`), `record_source` (`param` key); predicates: `filterable?`, `filters_quick?`, `filters_full?`, `record_click_navigate?`, `record_click_dialog?`, `record_click_none?`, `form_zone?`, `submit_redirect_self?`, `record_source?`, `record_source_param`). DB-backed pages: ContractValidator (page_config model contract), Registry (thread-safe cache), ChangeHandler (after_commit invalidation), DefinitionValidator (JSON validation on save), Setup (boot orchestration when `page_source == :model`) |
|
|
92
|
+
| `Widgets` | `lib/lcp_ruby/widgets/` | DataResolver (kpi_card aggregate, text i18n, list records, workflow_graph Mermaid diagram, approval_status; accepts scope_context and record; applies default_scope before zone scope), PresenterZoneResolver (scope pipeline: policy_scope → soft_delete → default_scope → zone_scope → scope_context → zone_filters → eager_loading → sort → paginate; returns zone, zone_record_slug in result), RecordSourceResolver (loads single record by ID from URL param; scope pipeline: policy_scope → soft_delete → eager_loading → find_by; returns record, presenter, layout_builder, column_set, field_value_resolver), ScopeApplicator (shared scope/model resolution, policy scope, soft delete filtering, `apply_default_scope`, scope_context WHERE/filter_* application) |
|
|
93
|
+
| `ViewSlots` | `lib/lcp_ruby/view_slots/` | Registry (page+slot component store with position ordering), SlotComponent (immutable value object: name, partial, position, enabled callback), SlotContext (immutable data bag for slot partials: presenter, evaluator, params, records, record, locals). ViewSlotHelper provides `render_slot` for ERB templates. 11 built-in components registered at boot + `approval_status` slot registered dynamically by `Workflow::Approval::Setup` |
|
|
94
|
+
| `BackgroundJobs` | `lib/lcp_ruby/background_jobs/` | Registry (thread-safe, resolver-backed), Definition (value object from YAML/DSL/DB), Setup (boot orchestration with contract validation), ExecutorJob (ActiveJob wrapper with retry/cancellation/timeout), BaseHandler (progress, logging, cancellation API), HandlerFactory (class/declarative/steps routing), StepsExecutor (multi-step sequential), Enqueue (public API with unique key dedup), 4 declarative actions (run_scope, fire_event, call_webhook, send_notification), event triggers, schedule adapter interface. Three sources: StaticSource, ModelSource, HostSource with Resolver priority merge |
|
|
95
|
+
| `GroupedQuery` | `lib/lcp_ruby/grouped_query/` | Builder (GROUP BY + aggregate SELECT + HAVING from presenter config), Row (value object for group rows), ResultWrapper (enum labels, null display). Supports count/sum/avg/min/max, DISTINCT, date period truncation, dot-path JOINs, row_click filter URL generation |
|
|
96
|
+
| `Sort` | `lib/lcp_ruby/sort/` | EnumSortOrder: CASE WHEN SQL for enum definition-order sorting, strategy resolution (definition_order/value). Used by both `apply_sort` (non-grouped) and `apply_grouped_sort` (grouped) |
|
|
97
|
+
| `Export` | `lib/lcp_ruby/export/` | Setup (virtual model + dialog page registration + event handler), ExportHandler (builds query, generates CSV/XLSX, saves profile/history), FieldTreeBuilder (permission-aware field picker tree with association traversal), DataGenerator (CSV with BOM + XLSX via caxlsx), ValueFormatter (enum/date/boolean/decimal formatting options) |
|
|
98
|
+
| `BatchActions` | `lib/lcp_ruby/batch_actions/` | BaseService (shared constructor, `each_record`, `log_item`, `finalize_batch_operation`, message builder), DestroyService (soft/hard delete with per-record permission), RestoreService (undiscard), PermanentlyDestroyService (hard delete discarded), CustomActionDispatcher (per-record iteration vs bulk execution based on `batch_capable?`, with auth checks, error handling, progress callbacks, result log). All services accept `records:, evaluator:, model_definition:, current_user:, batch_operation: nil, &progress` |
|
|
99
|
+
| `JsonItemWrapper` | `lib/lcp_ruby/json_item_wrapper.rb` | ActiveModel wrapper for JSON hash items; dynamic getter/setter per field from ModelDefinition; type coercion (integer, float, boolean); `validate_with_model_rules!` (presence, length, numericality, format); `to_hash` for persistence. Used by `json_field:` + `target_model:` nested sections |
|
|
100
|
+
| `Metrics` | `lib/lcp_ruby/metrics/` | PrometheusCheck (soft dependency), MetricDefinitions (metric constants incl. boot gauges: models/presenters/pages, request metrics with model label, permission_checks_total), Subscriber (AS::Notifications → Prometheus, view_group+model labels on requests, permission.lcp_ruby events, exception excluded from error log context), Collector (base class for host collectors with `subscribe` DSL for AS::Notifications), CollectorRegistry (auto-discovery from `app/lcp_metrics/`, subscription lifecycle), Fingerprint (error normalization), RateLimiter (in-memory throttle), ErrorRecorder (atomic upsert to error log), JsonQuery (portable JSON column queries), Setup (boot orchestration, `:auto` resolution) |
|
|
101
|
+
|
|
102
|
+
## Controller Stack
|
|
103
|
+
|
|
104
|
+
`ApplicationController` (`app/controllers/lcp_ruby/application_controller.rb`):
|
|
105
|
+
- Inherits from host app's controller (configurable via `parent_controller`)
|
|
106
|
+
- Thin assembler that includes 9 modular concerns from `LcpRuby::Controller::*` (see below)
|
|
107
|
+
- Cross-cutting `instrument_request` around_action for AS::Notifications
|
|
108
|
+
|
|
109
|
+
Includable concerns (`lib/lcp_ruby/controller/`):
|
|
110
|
+
- `ErrorHandling` — `rescue_from MetadataError`, `RecordNotFound`
|
|
111
|
+
- `Authentication` — `current_user`, `effective_user` base impl, Warden integration
|
|
112
|
+
- `PresenterSetup` — resolves presenter + model from `:lcp_slug`, auto-registers ~11 LCP view helpers
|
|
113
|
+
- `Impersonation` — overrides `effective_user` when impersonating
|
|
114
|
+
- `Authorization` — Pundit integration, `current_evaluator`, `policy`, `policy_scope`
|
|
115
|
+
- `PathHelpers` — `resource_path`, `resources_path`, `edit_resource_path`, etc.
|
|
116
|
+
- `ViewHelpers` — sort, breadcrumbs, view group methods
|
|
117
|
+
- `Search` — `apply_advanced_search`, `apply_sort`, filter helpers
|
|
118
|
+
- `CrudHelpers` — `permitted_params`, `set_record`, `setup_show_view_objects`, `setup_index_view_objects`
|
|
119
|
+
|
|
120
|
+
Each concern has dependency guards via `method_defined?` checks in its `included do` block — including in wrong order raises a descriptive error at class load time. Host app controllers can include any subset of these concerns via the `lcp_ruby:host_controller` generator or manually.
|
|
121
|
+
|
|
122
|
+
`ResourcesController` (`app/controllers/lcp_ruby/resources_controller.rb`):
|
|
123
|
+
- Standard CRUD (index/show/new/create/edit/update/destroy)
|
|
124
|
+
- Composite pages: `show` branches on `current_page.composite?` → `load_composite_page` resolves main zone (show or form via `form_zone?`) + delegates to `load_secondary_zones` for sidebar/below/tabs; tab zones are loaded lazily via `zone` action (Turbo Frames). `zone` action at `/:slug/:id/zones/:zone_name` calls `resolve_zone_data` for unified zone dispatch (widget/record_source/presenter). `zone_params(zone)` conditionally permits `qs` (when `zone.filterable?`), `f`/`cf` (when `zone.filters_full?`). Form zones: `update` uses `submit_redirect_self?` to redirect back to show page; on validation error, `load_composite_page_for_form_error` re-renders with dirty VCs. Show-in-dialog: `show` renders `_dialog_show_frame` when `dialog_context?` (`?_dialog=1`)
|
|
125
|
+
- `permitted_params` filters by writable fields + association FK fields
|
|
126
|
+
- `apply_advanced_search` 7-step pipeline: default scope, predefined filter scope, param sanitization, custom filter interception, Ransack query, quick search (`?qs=`), custom field filters (`?cf[...]`)
|
|
127
|
+
- Authorization via Pundit on every action
|
|
128
|
+
|
|
129
|
+
`CustomFieldsController` (`app/controllers/lcp_ruby/custom_fields_controller.rb`):
|
|
130
|
+
- Nested under `/:lcp_slug/custom-fields` for managing custom field definitions
|
|
131
|
+
- Dual context: parent model from `:lcp_slug`, CFD model + generated presenter for views
|
|
132
|
+
- Records scoped by `target_model` from parent URL context (prevents cross-model access)
|
|
133
|
+
- Reuses `lcp_ruby/resources` views via `controller_path` override
|
|
134
|
+
- Separate authorization via `custom_field_definition` permissions
|
|
135
|
+
|
|
136
|
+
`ApprovalTasksController` (`app/controllers/lcp_ruby/approval_tasks_controller.rb`):
|
|
137
|
+
- 5 POST actions: `approve`, `reject`, `return_task`, `claim`, `delegate`
|
|
138
|
+
- Nested under `/:lcp_slug/:id/approval_tasks/:task_id/<action>`
|
|
139
|
+
- Authorizes via `show?` on the record (task-level auth handled by `TaskManager`)
|
|
140
|
+
- Validates task belongs to record's active approval request
|
|
141
|
+
- Rescues `TaskActionError`, `DelegationError` → redirect with alert flash
|
|
142
|
+
|
|
143
|
+
`DialogsController` (`app/controllers/lcp_ruby/dialogs_controller.rb`):
|
|
144
|
+
- Handles dialog-only pages (no slug) at `/lcp_dialog/:page_name/*`
|
|
145
|
+
- Resolves presenter and model from the page definition
|
|
146
|
+
- Supports both persistent models (AR create/update) and virtual models (JsonItemWrapper validation + `dialog_submit` event)
|
|
147
|
+
- Uses `DialogRendering` concern for dialog frame rendering and success responses
|
|
148
|
+
- `DialogRendering` concern also mixed into `ResourcesController` for `?_dialog=1` context detection
|
|
149
|
+
|
|
150
|
+
## Routing
|
|
151
|
+
|
|
152
|
+
Engine mounts at a configurable path (default `/`). All resources use a slug-based pattern:
|
|
153
|
+
```
|
|
154
|
+
/:lcp_slug → resources#index
|
|
155
|
+
/:lcp_slug/new → resources#new
|
|
156
|
+
/:lcp_slug/:id → resources#show
|
|
157
|
+
/:lcp_slug/:id/zones/:zone_name → resources#zone (GET, Turbo Frame zone content)
|
|
158
|
+
/:lcp_slug/:id/edit → resources#edit
|
|
159
|
+
/:lcp_slug/filter_fields → resources#filter_fields (GET, JSON filter metadata)
|
|
160
|
+
/:lcp_slug/batch_count → resources#batch_count (GET, JSON count for "select all matching")
|
|
161
|
+
/:lcp_slug/export_fields → resources#export_fields (GET, JSON field tree for picker)
|
|
162
|
+
/:lcp_slug/batch_selection → resources#batch_selection (POST, session token for large ID sets)
|
|
163
|
+
/:lcp_slug/batch_actions/:action_name → actions#execute_batch (POST, batch action dispatch)
|
|
164
|
+
/:lcp_slug/parse_ql → resources#parse_ql (POST, QL text → condition tree)
|
|
165
|
+
/:lcp_slug/:id/approval_tasks/:task_id/<action> → approval_tasks#<action> (POST, 5 actions)
|
|
166
|
+
/:lcp_slug/custom-fields → custom_fields#index
|
|
167
|
+
/:lcp_slug/custom-fields/manage → custom_fields#manage (bulk editor)
|
|
168
|
+
/:lcp_slug/custom-fields/:id → custom_fields#show
|
|
169
|
+
/lcp_dialog/:page_name/new → dialogs#new (dialog-only page)
|
|
170
|
+
/lcp_dialog/:page_name → dialogs#create (POST)
|
|
171
|
+
/lcp_dialog/:page_name/:id/edit → dialogs#edit
|
|
172
|
+
/lcp_dialog/:page_name/:id → dialogs#update (PATCH)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The slug comes from the presenter YAML (e.g., `slug: deals` → `/deals`). Dialog routes use page names instead of slugs.
|
|
176
|
+
|
|
177
|
+
**Custom controller routing.** Presenters can declare `controller: "checkouts"` (full override) or `action_controllers: { new: "wizard#new" }` (per-action override) to route to host app controllers instead of LCP's `ResourcesController`. `LcpRuby::Routing::PresenterRoutes.draw_custom_controller_routes` generates explicit slug-scoped routes for these presenters and is called **before** the catch-all `scope ":lcp_slug"` block. Rails matches top-down so explicit literal-slug routes win. All custom routes set `defaults: { lcp_slug, lcp_presenter }` so existing `set_presenter_and_model` works unchanged. Ancillary routes (saved filters, custom fields, actions, transitions, approval tasks) always remain on LCP controllers. See the [Host Controller Integration reference](reference/host-controller-integration.md).
|
|
178
|
+
|
|
179
|
+
**Connecting to existing host AR models.** A model YAML can declare `bind_to: "::Employee"` to use an existing ActiveRecord class instead of creating a new dynamic model. For `bind_to:` models, both `SchemaManager` and `ModelFactory::Builder` are skipped — the existing class is registered in `LcpRuby.registry` as-is. Optional features can be opt-in via `bind_to_apply: [ransack, scopes, validations, ...]`. See the [Host Controller Integration reference](reference/host-controller-integration.md#bind_to--connecting-to-an-existing-ar-model).
|
|
180
|
+
|
|
181
|
+
## How Association Selects Work
|
|
182
|
+
|
|
183
|
+
When a form field has `input_type: association_select` (e.g., `todo_list_id`):
|
|
184
|
+
1. `LayoutBuilder.normalize_section` matches the FK field name against `association.foreign_key` metadata
|
|
185
|
+
2. Creates a synthetic `FieldDefinition` (type: integer) and attaches the `AssociationDefinition`
|
|
186
|
+
3. `_form.html.erb` renders a `<select>` populated from the target model's records via `LcpRuby.registry.model_for(assoc.target_model)`
|
|
187
|
+
4. FK fields bypass the `field_writable?` check (they're permitted separately in the controller)
|
|
188
|
+
|
|
189
|
+
## Permission System
|
|
190
|
+
|
|
191
|
+
Permissions YAML defines roles with: `crud` list, `fields` (readable/writable), `actions`, `scope`, `presenters`. The `PermissionEvaluator.can?` method maps action aliases (`edit` → `update`, `new` → `create`) before checking the CRUD list. Record-level rules (`record_rules`) can deny specific CRUD operations based on field conditions with role exceptions. `can_for_record?` resolves action aliases and delegates condition evaluation to `ConditionEvaluator.evaluate_any` (all 15 operators, compound/collection/dot-path/lookup). Record rules automatically hide built-in `edit`/`destroy` action buttons on index pages via `ActionSet#action_permitted_for_record?`.
|
|
192
|
+
|
|
193
|
+
## Test Structure
|
|
194
|
+
|
|
195
|
+
- **Unit tests**: `spec/lib/lcp_ruby/` — test individual subsystems against YAML fixtures in `spec/fixtures/metadata/`
|
|
196
|
+
- **Integration tests**: `spec/integration/` — test full HTTP request cycle using fixtures in `spec/fixtures/integration/{todo,crm}/`
|
|
197
|
+
- **Dummy app**: `spec/dummy/` — minimal Rails app that mounts the engine at `/`
|
|
198
|
+
- **Integration helper**: `spec/support/integration_helper.rb` — provides `load_integration_metadata!` and `stub_current_user` for request specs
|
|
199
|
+
- Each test resets `LcpRuby.reset!` and clears Dynamic constants before running (see `spec_helper.rb`)
|
|
200
|
+
|
|
201
|
+
### Generator regression coverage
|
|
202
|
+
|
|
203
|
+
Every platform generator's output must pass `ConfigurationValidator` clean (the same validator that `rake lcp_ruby:validate` runs in production). The harness:
|
|
204
|
+
|
|
205
|
+
- **Test harness**: `spec/support/generator_fixture.rb` — `build_minimal_app(tier:)`, `run_generator`, `validate_metadata`. Two tiers: `:tier1` (bare `config/lcp_ruby/` directories) and `:tier2` (tier1 + minimal Rails skeleton for generators that patch host files).
|
|
206
|
+
- **Shared example**: `spec/support/shared_examples/generator_validates_clean.rb` — runs DSL + YAML, supports `prerequisites:`, `args:`, `stub_active_storage:`.
|
|
207
|
+
- **Per-generator coverage**: `spec/lib/generators/lcp_ruby/all_generators_validate_spec.rb` — registry of every shipped generator. Adding a new generator means adding one entry to the `GENERATORS` array.
|
|
208
|
+
- **Preset stack coverage**: `preset_minimal_validate_spec.rb`, `preset_standard_validate_spec.rb`, `preset_full_validate_spec.rb` — run the full generator chain that `lcp new --preset=<name>` would invoke, on a single destination. These catch cross-generator collisions (view group positions, duplicate permission rules) that single-generator specs miss.
|
|
209
|
+
- **Service reference coverage**: `services_coverage_spec.rb` — static-analysis sweep that ensures every `service: <name>` reference in any template resolves to a registered built-in.
|
|
210
|
+
- **CI gate**: `.github/workflows/ci.yml` runs `bundle exec rspec spec/lib/generators spec/lib/lcp_ruby/metadata` on every push and pull request — new specs under `spec/lib/generators/lcp_ruby/` are picked up automatically.
|
|
211
|
+
|
|
212
|
+
Background: see `docs/improve-tasks/aggregated.md` cross-cutting theme #1 ("generator regression") and item C10.
|