ApiLogicServer 15.0.65__py3-none-any.whl → 15.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (519) hide show
  1. api_logic_server_cli/api_logic_server.py +2 -2
  2. api_logic_server_cli/database/basic_demo.sqlite +0 -0
  3. api_logic_server_cli/prototypes/base/.github/.copilot-instructions.md +25 -2
  4. api_logic_server_cli/prototypes/basic_demo/customizations/database/db.sqlite +0 -0
  5. api_logic_server_cli/prototypes/basic_demo/iteration/database/db.sqlite +0 -0
  6. api_logic_server_cli/prototypes/manager/.vscode/launch.json +2 -1
  7. api_logic_server_cli/prototypes/manager/samples/basic_demo/.devcontainer-option/For_VSCode.dockerfile +10 -0
  8. api_logic_server_cli/prototypes/manager/samples/basic_demo/.devcontainer-option/devcontainer.json +64 -0
  9. api_logic_server_cli/prototypes/manager/samples/basic_demo/.devcontainer-option/readme.md +1 -0
  10. api_logic_server_cli/prototypes/manager/samples/basic_demo/.devcontainer-option/setup.sh +10 -0
  11. api_logic_server_cli/prototypes/manager/samples/basic_demo/.env +4 -0
  12. api_logic_server_cli/prototypes/manager/samples/basic_demo/.github/.copilot-instructions.md +581 -0
  13. api_logic_server_cli/prototypes/manager/samples/basic_demo/.gitignore +9 -0
  14. api_logic_server_cli/prototypes/manager/samples/basic_demo/.idea/runConfigurations/ApiLogicServer.xml +24 -0
  15. api_logic_server_cli/prototypes/manager/samples/basic_demo/.idea/runConfigurations/Report_Behave_Logic.xml +24 -0
  16. api_logic_server_cli/prototypes/manager/samples/basic_demo/.idea/runConfigurations/Run_Behave.xml +24 -0
  17. api_logic_server_cli/prototypes/manager/samples/basic_demo/.idea/runConfigurations/Windows_Run_Behave.xml +24 -0
  18. api_logic_server_cli/prototypes/manager/samples/basic_demo/.idea/runConfigurations/run___No_Security.xml +25 -0
  19. api_logic_server_cli/prototypes/manager/samples/basic_demo/.idea/runConfigurations/run_docker.xml +59 -0
  20. api_logic_server_cli/prototypes/manager/samples/basic_demo/.vscode/launch.json +314 -0
  21. api_logic_server_cli/prototypes/manager/samples/basic_demo/.vscode/settings.json +40 -0
  22. api_logic_server_cli/prototypes/manager/samples/basic_demo/.vscode/venv_init.sh +64 -0
  23. api_logic_server_cli/prototypes/manager/samples/basic_demo/_config.yml +8 -0
  24. api_logic_server_cli/prototypes/manager/samples/basic_demo/_layouts/redirect.html +15 -0
  25. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/__init__.py +0 -0
  26. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/auto_discovery.py +27 -0
  27. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/mcp_discovery.py +97 -0
  28. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/mcp_expose_api_models.py +53 -0
  29. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/new_service.py +21 -0
  30. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/newer_service.py +21 -0
  31. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/ontimize_api.py +495 -0
  32. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/order_b2b_service.py +60 -0
  33. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/api_discovery/system.py +77 -0
  34. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/customize_api.py +63 -0
  35. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/expose_api_models.py +52 -0
  36. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/json_encoder.py +17 -0
  37. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/readme_customize_api.md +103 -0
  38. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/system/api_utils.py +171 -0
  39. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/system/custom_endpoint.py +1085 -0
  40. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/system/expression_parser.py +685 -0
  41. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/system/gen_csv_report.py +41 -0
  42. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/system/gen_pdf_report.py +215 -0
  43. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/system/opt_locking/opt_locking.py +158 -0
  44. api_logic_server_cli/prototypes/manager/samples/basic_demo/api/system/opt_locking/readme.md +225 -0
  45. api_logic_server_cli/prototypes/manager/samples/basic_demo/api_logic_server_run.py +162 -0
  46. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/__init__.py +0 -0
  47. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/activate_logicbank.py +46 -0
  48. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/config.py +772 -0
  49. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/default.env +16 -0
  50. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/logging-reduced.yml +112 -0
  51. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/logging.yml +123 -0
  52. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/mypy.ini +25 -0
  53. api_logic_server_cli/prototypes/manager/samples/basic_demo/config/server_setup.py +459 -0
  54. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/api/api_discovery/openapi.py +92 -0
  55. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/config/default.env +13 -0
  56. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/database/db.sqlite +0 -0
  57. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/database/models.py +130 -0
  58. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/docs/mcp_learning/mcp_discovery.json +108 -0
  59. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/logic/cocktail-napkin.jpg +0 -0
  60. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/logic/declare_logic.py +106 -0
  61. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/logic/logic_discovery/email_request.py +49 -0
  62. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/logic/logic_discovery/simple_constraints.py +25 -0
  63. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/security/declare_security.py +60 -0
  64. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/admin/admin.yaml +162 -0
  65. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/admin/home.js +48 -0
  66. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/README.md +17 -0
  67. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/README_create_react_app.md +70 -0
  68. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/package-lock.json +18469 -0
  69. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/package.json +47 -0
  70. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/public/favicon.ico +0 -0
  71. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/public/index.html +43 -0
  72. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/public/logo192.png +0 -0
  73. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/public/logo512.png +0 -0
  74. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/public/manifest.json +25 -0
  75. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/public/robots.txt +3 -0
  76. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/App.css +38 -0
  77. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/App.js +61 -0
  78. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/App.test.js +8 -0
  79. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/Config-reference.js +527 -0
  80. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/Config.js +527 -0
  81. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/Customer-reference.js +216 -0
  82. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/Customer.js +230 -0
  83. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/Item.js +170 -0
  84. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/Order.js +207 -0
  85. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/Product.js +140 -0
  86. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/SysEmail.js +157 -0
  87. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/SysMcp.js +110 -0
  88. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/app_loader.js +24 -0
  89. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/index.css +13 -0
  90. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/index.js +17 -0
  91. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/logo.svg +1 -0
  92. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/.eslintrc +5 -0
  93. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/.yarnrc.yml +4 -0
  94. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/default-settings.js +25 -0
  95. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/default-settings.ts +25 -0
  96. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/errors.js +116 -0
  97. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/errors.ts +116 -0
  98. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/index.test.tsx +7 -0
  99. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/index.tsx +11 -0
  100. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/ra-jsonapi-client.js +577 -0
  101. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/ra-jsonapi-client.ts +577 -0
  102. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/resourceLookup.js +124 -0
  103. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/resourceLookup.ts +124 -0
  104. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/rav4-jsonapi-client/styles.module.css +9 -0
  105. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/reportWebVitals.js +13 -0
  106. api_logic_server_cli/prototypes/manager/samples/basic_demo/customizations/ui/reference_react_app/src/setupTests.js +5 -0
  107. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/__init__.py +0 -0
  108. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/alembic/alembic_run.py +98 -0
  109. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/alembic/env.py +78 -0
  110. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/alembic/readme_alembic.md +36 -0
  111. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/alembic/script.py.mako +24 -0
  112. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/alembic/versions/ae6a5c2fdc47_autogenerated.py +34 -0
  113. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/alembic/versions/readme.md +1 -0
  114. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/alembic.ini +103 -0
  115. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/authentication_db.sqlite +0 -0
  116. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/bind_dbs.py +25 -0
  117. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/customize_models.py +19 -0
  118. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/database_discovery/authentication_models.py +183 -0
  119. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/database_discovery/auto_discovery.py +27 -0
  120. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/db.sqlite +0 -0
  121. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/db_debug/db_debug.py +90 -0
  122. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/mcp_db.sqlite +0 -0
  123. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/mcp_models.py +58 -0
  124. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/models.py +132 -0
  125. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/system/SAFRSBaseX.py +139 -0
  126. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/test_data/alp_init.py +40 -0
  127. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/test_data/readme.md +13 -0
  128. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/test_data/response2code.py +148 -0
  129. api_logic_server_cli/prototypes/manager/samples/basic_demo/database/test_data/test_data_preamble.py +83 -0
  130. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/auth-db/authdb_mysql.Dockerfile +65 -0
  131. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/auth-db/authdb_mysql.sql +112 -0
  132. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/auth-db/authdb_postgres.sql +57 -0
  133. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-compose-dev-azure/azure-deploy.sh +98 -0
  134. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-compose-dev-local/docker-compose-dev-local.yml +38 -0
  135. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-compose-dev-local/docker-compose.sh +34 -0
  136. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-image/build_image.dockerfile +20 -0
  137. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-image/build_image.sh +67 -0
  138. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-image/env.list +35 -0
  139. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-image/run_image.sh +23 -0
  140. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-standard-image/docker-compose-standard-image.yml +33 -0
  141. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/docker-standard-image/env.list +55 -0
  142. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/data/h2/keycloakdb.mv.db +0 -0
  143. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/data/h2/keycloakdb.trace.db +236 -0
  144. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/data/import/kcals-realm.json +1807 -0
  145. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/data/import/kcals-users-0.json +24 -0
  146. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/data/import/master-realm.json +1953 -0
  147. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/data/import/master-users-0.json +23 -0
  148. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/data/tmp/kc-gzip-cache/nnbna/js/keycloak.js.gz +0 -0
  149. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/docker-compose-dev-network.yml +31 -0
  150. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/docker-compose-nginx.yml +48 -0
  151. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/docker-compose.yml +24 -0
  152. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/import/kcals-realm.json +1898 -0
  153. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/import/kcals-users-0.json +319 -0
  154. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/import/master-realm.json +1953 -0
  155. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/import/master-users-0.json +23 -0
  156. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/nginx/cert.pem +25 -0
  157. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/nginx/key.pem +28 -0
  158. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/nginx/nginx.conf +73 -0
  159. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/startup_log_nginx.txt +0 -0
  160. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/startup_log_no_nginx.txt +0 -0
  161. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/unused/auth_provider.py +80 -0
  162. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/keycloak/unused/unused-docker-compose-keycloak.sh +13 -0
  163. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/python-anywhere/python_anywhere_wsgi.py +116 -0
  164. api_logic_server_cli/prototypes/manager/samples/basic_demo/devops/readme-devops.md +31 -0
  165. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/db.dbml +14 -0
  166. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/graphics/readme.md +12 -0
  167. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/logic/readme.md +19 -0
  168. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/logic_suggestions/readme_logic_suggestions.md +3 -0
  169. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/mcp_learning/mcp.prompt +39 -0
  170. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/mcp_learning/mcp_schema.json +30 -0
  171. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/models-not-code.png +0 -0
  172. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/runtime engines.png +0 -0
  173. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/system-creation-vibe.md +158 -0
  174. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/training/admin_app_1_context.prompt.md +43 -0
  175. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/training/admin_app_2_functionality.prompt.md +69 -0
  176. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/training/admin_app_3_architecture.prompt.md +29 -0
  177. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/training/logic_bank_api.prompt +342 -0
  178. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/training/logic_example.py +41 -0
  179. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/training/react_map.prompt.md +13 -0
  180. api_logic_server_cli/prototypes/manager/samples/basic_demo/docs/training/react_tree.prompt.md +10 -0
  181. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/kafka/kafka_consumer.py +60 -0
  182. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/kafka/kafka_producer.py +127 -0
  183. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/kafka/kafka_readme.md +3 -0
  184. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/examples/mcp_context_results.txt +142 -0
  185. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/examples/mcp_discovery_response.json +150 -0
  186. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/examples/mcp_request.prompt +46 -0
  187. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/examples/mcp_schema.txt +47 -0
  188. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/examples/mcp_tool_context_response.json +34 -0
  189. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/examples/mcp_tool_context_response_get.json +18 -0
  190. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/mcp_client_executor.py +545 -0
  191. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/mcp_server_discovery.json +9 -0
  192. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/mcp/readme-mcp.md +9 -0
  193. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/n8n/N8N_WebHook_from_ApiLogicServer.json +394 -0
  194. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/n8n/n8n_producer.py +172 -0
  195. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/n8n/n8n_readme.md +67 -0
  196. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/row_dict_maps/OrderB2BMapper.py +54 -0
  197. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/row_dict_maps/row_dict_maps_readme.md +3 -0
  198. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/system/FlaskKafka.py +105 -0
  199. api_logic_server_cli/prototypes/manager/samples/basic_demo/integration/system/RowDictMapper.py +416 -0
  200. api_logic_server_cli/prototypes/manager/samples/basic_demo/iteration/api/api_discovery/order_b2b.py +92 -0
  201. api_logic_server_cli/prototypes/manager/samples/basic_demo/iteration/database/db.sqlite +0 -0
  202. api_logic_server_cli/prototypes/manager/samples/basic_demo/iteration/docs/er_diagram.png +0 -0
  203. api_logic_server_cli/prototypes/manager/samples/basic_demo/iteration/integration/row_dict_maps/OrderB2B.py +36 -0
  204. api_logic_server_cli/prototypes/manager/samples/basic_demo/iteration/integration/row_dict_maps/OrderShipping.py +30 -0
  205. api_logic_server_cli/prototypes/manager/samples/basic_demo/iteration/logic/declare_logic.py +147 -0
  206. api_logic_server_cli/prototypes/manager/samples/basic_demo/iteration/ui/admin/admin.yaml +175 -0
  207. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/declarative-vs-procedural-comparison.html +110 -0
  208. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/declare_logic.py +81 -0
  209. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/load_verify_rules.py +217 -0
  210. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/logic_discovery/app_integration.py +23 -0
  211. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/logic_discovery/auto_discovery.py +52 -0
  212. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/logic_discovery/check_credit.py +44 -0
  213. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/logic_discovery/mcp_client_executor_request.py +50 -0
  214. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/logic_discovery/readme_logic_discovery.md +9 -0
  215. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/logic_discovery/use_case.py +31 -0
  216. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/procedural/credit_service.py +204 -0
  217. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/procedural/declarative-vs-procedural-comparison.md +295 -0
  218. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/procedural/declarative-vs-procedural-comparison.png +0 -0
  219. api_logic_server_cli/prototypes/manager/samples/basic_demo/logic/readme_logic.md +249 -0
  220. api_logic_server_cli/prototypes/manager/samples/basic_demo/readme.md +495 -0
  221. api_logic_server_cli/prototypes/manager/samples/basic_demo/readme_project.md +43 -0
  222. api_logic_server_cli/prototypes/manager/samples/basic_demo/readme_standard.md +492 -0
  223. api_logic_server_cli/prototypes/manager/samples/basic_demo/readme_vibe.md +353 -0
  224. api_logic_server_cli/prototypes/manager/samples/basic_demo/requirements.txt +3 -0
  225. api_logic_server_cli/prototypes/manager/samples/basic_demo/run.ps1 +30 -0
  226. api_logic_server_cli/prototypes/manager/samples/basic_demo/run.sh +55 -0
  227. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/__init__.py +0 -0
  228. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/authentication_provider/__init__.py +0 -0
  229. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/authentication_provider/abstract_authentication_provider.py +34 -0
  230. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/authentication_provider/keycloak/auth_provider.py +238 -0
  231. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/authentication_provider/memory/auth_provider.py +161 -0
  232. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/authentication_provider/memory/auth_provider_no_swagger.py +98 -0
  233. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/authentication_provider/sql/auth_provider.py +127 -0
  234. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/declare_security.py +49 -0
  235. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/readme_security.md +16 -0
  236. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/system/authentication.py +129 -0
  237. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/system/authorization.py +473 -0
  238. api_logic_server_cli/prototypes/manager/samples/basic_demo/security/system/custom_swagger.json +62 -0
  239. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/__init__.py +0 -0
  240. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/__init__.py +0 -0
  241. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/behave_logic_report.py +256 -0
  242. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/behave_run.py +64 -0
  243. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/features/about.feature +12 -0
  244. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/features/steps/about.py +20 -0
  245. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/features/steps/test_utils.py +133 -0
  246. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/logs/behave.log +0 -0
  247. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/reports/Behave Logic Report Intro micro.md +4 -0
  248. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/reports/Behave Logic Report Intro.md +75 -0
  249. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/api_logic_server_behave/reports/Behave Logic Report Sample.md +1180 -0
  250. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/basic/server_test.py +33 -0
  251. api_logic_server_cli/prototypes/manager/samples/basic_demo/test/readme_test.md +395 -0
  252. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/__init__.py +0 -0
  253. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/admin/admin.yaml +173 -0
  254. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/admin/admin_loader.py +217 -0
  255. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/admin/authentication_admin.yaml +99 -0
  256. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/admin/home.js +48 -0
  257. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/admin/mcp_admin.yaml +53 -0
  258. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/.browserslistrc +12 -0
  259. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/.dockerignore +47 -0
  260. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/.editorconfig +16 -0
  261. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/.eslintrc.json +51 -0
  262. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/.gitignore +47 -0
  263. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/README.md +42 -0
  264. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/angular.json +206 -0
  265. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/app_model.yaml +303 -0
  266. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/docker-compose-ontimize.yml +54 -0
  267. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/e2e/protractor.conf.js +32 -0
  268. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/e2e/src/app.e2e-spec.ts +23 -0
  269. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/e2e/src/app.po.ts +11 -0
  270. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/e2e/tsconfig.json +13 -0
  271. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/karma.conf.js +32 -0
  272. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/nginx/nginx.conf +29 -0
  273. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/ngsw-config.json +29 -0
  274. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/package-lock.json +22651 -0
  275. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/package.json +69 -0
  276. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/app-routing.module.ts +25 -0
  277. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/app.component.html +1 -0
  278. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/app.component.scss +1 -0
  279. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/app.component.spec.ts +35 -0
  280. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/app.component.ts +9 -0
  281. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/app.config.ts +43 -0
  282. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/app.module.ts +37 -0
  283. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/login/login-routing.module.ts +12 -0
  284. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/login/login.component.html +58 -0
  285. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/login/login.component.scss +155 -0
  286. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/login/login.component.ts +81 -0
  287. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/login/login.module.ts +18 -0
  288. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/login/login.theme.scss +51 -0
  289. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/Customer-routing.module.ts +37 -0
  290. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/Customer.module.ts +19 -0
  291. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/detail/Customer-detail.component.html +90 -0
  292. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/detail/Customer-detail.component.scss +0 -0
  293. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/detail/Customer-detail.component.ts +32 -0
  294. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/home/Customer-home.component.html +44 -0
  295. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/home/Customer-home.component.scss +0 -0
  296. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/home/Customer-home.component.ts +23 -0
  297. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/new/Customer-new.component.html +26 -0
  298. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/new/Customer-new.component.scss +0 -0
  299. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Customer/new/Customer-new.component.ts +18 -0
  300. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/Item-routing.module.ts +30 -0
  301. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/Item.module.ts +19 -0
  302. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/detail/Item-detail.component.html +72 -0
  303. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/detail/Item-detail.component.scss +0 -0
  304. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/detail/Item-detail.component.ts +32 -0
  305. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/home/Item-home.component.html +55 -0
  306. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/home/Item-home.component.scss +0 -0
  307. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/home/Item-home.component.ts +23 -0
  308. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/new/Item-new.component.html +60 -0
  309. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/new/Item-new.component.scss +0 -0
  310. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Item/new/Item-new.component.ts +18 -0
  311. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/Order-routing.module.ts +37 -0
  312. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/Order.module.ts +19 -0
  313. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/detail/Order-detail.component.html +114 -0
  314. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/detail/Order-detail.component.scss +0 -0
  315. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/detail/Order-detail.component.ts +32 -0
  316. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/home/Order-home.component.html +48 -0
  317. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/home/Order-home.component.scss +0 -0
  318. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/home/Order-home.component.ts +23 -0
  319. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/new/Order-new.component.html +43 -0
  320. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/new/Order-new.component.scss +0 -0
  321. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Order/new/Order-new.component.ts +18 -0
  322. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/Product-routing.module.ts +37 -0
  323. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/Product.module.ts +19 -0
  324. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/detail/Product-detail.component.html +91 -0
  325. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/detail/Product-detail.component.scss +0 -0
  326. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/detail/Product-detail.component.ts +32 -0
  327. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/home/Product-home.component.html +35 -0
  328. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/home/Product-home.component.scss +0 -0
  329. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/home/Product-home.component.ts +23 -0
  330. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/new/Product-new.component.html +20 -0
  331. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/new/Product-new.component.scss +0 -0
  332. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/Product/new/Product-new.component.ts +18 -0
  333. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/about/about-routing.module.ts +13 -0
  334. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/about/about.component.html +39 -0
  335. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/about/about.component.scss +35 -0
  336. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/about/about.component.ts +17 -0
  337. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/about/about.module.ts +18 -0
  338. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/about/about.theme.scss +14 -0
  339. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/home/home-routing.module.ts +17 -0
  340. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/home/home.component.html +1 -0
  341. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/home/home.component.scss +3 -0
  342. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/home/home.component.ts +21 -0
  343. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/home/home.module.ts +18 -0
  344. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/main-routing.module.ts +32 -0
  345. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/main-theme.scss +56 -0
  346. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/main.component.html +8 -0
  347. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/main.component.scss +1 -0
  348. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/main.component.ts +20 -0
  349. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/main.module.ts +22 -0
  350. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/settings/settings-routing.module.ts +14 -0
  351. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/settings/settings.component.html +14 -0
  352. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/settings/settings.component.scss +44 -0
  353. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/settings/settings.component.ts +46 -0
  354. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/main/settings/settings.module.ts +18 -0
  355. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Customer-card/Customer-card.component.html +1 -0
  356. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Customer-card/Customer-card.component.scss +0 -0
  357. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Customer-card/Customer-card.component.ts +16 -0
  358. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Item-card/Item-card.component.html +1 -0
  359. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Item-card/Item-card.component.scss +0 -0
  360. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Item-card/Item-card.component.ts +16 -0
  361. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Order-card/Order-card.component.html +1 -0
  362. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Order-card/Order-card.component.scss +0 -0
  363. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Order-card/Order-card.component.ts +16 -0
  364. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Product-card/Product-card.component.html +1 -0
  365. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Product-card/Product-card.component.scss +0 -0
  366. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/Product-card/Product-card.component.ts +16 -0
  367. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/app.menu.config.ts +45 -0
  368. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/app.services.config.ts +5 -0
  369. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/constant.ts +4 -0
  370. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/app/shared/shared.module.ts +15 -0
  371. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/.gitkeep +0 -0
  372. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/css/app.scss +20 -0
  373. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/css/loader.css +173 -0
  374. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/i18n/en.json +44 -0
  375. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/i18n/es.json +42 -0
  376. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize128.png +0 -0
  377. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize16.png +0 -0
  378. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize256.png +0 -0
  379. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize32.png +0 -0
  380. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize48.png +0 -0
  381. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize64.png +0 -0
  382. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize72.png +0 -0
  383. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/icons/ontimize96.png +0 -0
  384. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/github.png +0 -0
  385. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/login_bg.png +0 -0
  386. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/no-image-transparent.png +0 -0
  387. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/no-image.png +0 -0
  388. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/ontimize.png +0 -0
  389. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/ontimize_web_log.png +0 -0
  390. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/sidenav-closed.png +0 -0
  391. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/sidenav-closed.svg +1 -0
  392. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/sidenav-opened.png +0 -0
  393. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/sidenav-opened.svg +1 -0
  394. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/images/user_profile.png +0 -0
  395. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/js/domchange.js +110 -0
  396. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/assets/js/keyboard.js +24 -0
  397. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/environments/environment.prod.ts +11 -0
  398. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/environments/environment.ts +15 -0
  399. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/favicon.ico +0 -0
  400. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/index.html +30 -0
  401. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/main.ts +15 -0
  402. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/manifest.webmanifest +59 -0
  403. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/polyfills.ts +66 -0
  404. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/styles.scss +1 -0
  405. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/src/test.ts +16 -0
  406. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/tsconfig.app.json +18 -0
  407. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/tsconfig.json +25 -0
  408. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/app/tsconfig.spec.json +18 -0
  409. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/andrew.jpg +0 -0
  410. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/anne.jpg +0 -0
  411. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/janet.jpg +0 -0
  412. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/laura.jpg +0 -0
  413. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/margaret.jpg +0 -0
  414. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/michael.jpg +0 -0
  415. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/nancy.jpg +0 -0
  416. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/robert.jpg +0 -0
  417. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Employee/steven.jpg +0 -0
  418. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/beverages.gif +0 -0
  419. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/cereals.gif +0 -0
  420. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/condiments.gif +0 -0
  421. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/confections.gif +0 -0
  422. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/diary.gif +0 -0
  423. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/meat.gif +0 -0
  424. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/produce.gif +0 -0
  425. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/images/Product/seafood.gif +0 -0
  426. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/README.md +16 -0
  427. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/README_create_react_app.md +70 -0
  428. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/package-lock.json +18469 -0
  429. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/package.json +47 -0
  430. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/public/favicon.ico +0 -0
  431. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/public/index.html +43 -0
  432. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/public/logo192.png +0 -0
  433. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/public/logo512.png +0 -0
  434. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/public/manifest.json +25 -0
  435. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/public/robots.txt +3 -0
  436. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/App.css +38 -0
  437. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/App.js +80 -0
  438. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/App.test.js +8 -0
  439. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/Config.js +527 -0
  440. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/Customer.js +218 -0
  441. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/Item.js +190 -0
  442. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/Order.js +189 -0
  443. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/Product.js +159 -0
  444. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/app_loader.js +24 -0
  445. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/index.css +13 -0
  446. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/index.js +17 -0
  447. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/logo.svg +1 -0
  448. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/.eslintrc +5 -0
  449. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/.yarnrc.yml +4 -0
  450. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/default-settings.js +25 -0
  451. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/default-settings.ts +25 -0
  452. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/errors.js +116 -0
  453. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/errors.ts +116 -0
  454. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/index.test.tsx +7 -0
  455. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/index.tsx +11 -0
  456. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/ra-jsonapi-client.js +577 -0
  457. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/ra-jsonapi-client.ts +577 -0
  458. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/resourceLookup.js +124 -0
  459. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/resourceLookup.ts +124 -0
  460. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/rav4-jsonapi-client/styles.module.css +9 -0
  461. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/reportWebVitals.js +13 -0
  462. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app/src/setupTests.js +5 -0
  463. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/README.md +20 -0
  464. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/README_create_react_app.md +72 -0
  465. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/package-lock.json +18469 -0
  466. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/package.json +47 -0
  467. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/product-cards.png +0 -0
  468. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/public/favicon.ico +0 -0
  469. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/public/index.html +43 -0
  470. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/public/logo192.png +0 -0
  471. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/public/logo512.png +0 -0
  472. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/public/manifest.json +25 -0
  473. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/public/robots.txt +3 -0
  474. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/App.css +38 -0
  475. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/App.js +80 -0
  476. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/App.test.js +8 -0
  477. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/Config.js +527 -0
  478. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/Customer.js +218 -0
  479. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/Item.js +190 -0
  480. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/Order.js +189 -0
  481. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/Product.js +241 -0
  482. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/app_loader.js +24 -0
  483. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/index.css +13 -0
  484. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/index.js +17 -0
  485. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/logo.svg +1 -0
  486. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/.eslintrc +5 -0
  487. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/.yarnrc.yml +4 -0
  488. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/default-settings.js +25 -0
  489. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/default-settings.ts +25 -0
  490. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/errors.js +116 -0
  491. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/errors.ts +116 -0
  492. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/index.test.tsx +7 -0
  493. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/index.tsx +11 -0
  494. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/ra-jsonapi-client.js +577 -0
  495. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/ra-jsonapi-client.ts +577 -0
  496. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/resourceLookup.js +124 -0
  497. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/resourceLookup.ts +124 -0
  498. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/rav4-jsonapi-client/styles.module.css +9 -0
  499. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/reportWebVitals.js +13 -0
  500. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/my-react-app-cards/src/setupTests.js +5 -0
  501. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/templates/bar_chart.jinja +64 -0
  502. api_logic_server_cli/prototypes/manager/samples/basic_demo/ui/templates/content.html +3 -0
  503. api_logic_server_cli/prototypes/manager/samples/basic_demo/venv_setup/py.py +121 -0
  504. api_logic_server_cli/prototypes/manager/samples/basic_demo/venv_setup/readme_venv.md +20 -0
  505. api_logic_server_cli/prototypes/manager/samples/basic_demo/venv_setup/requirements-no-cli.txt +33 -0
  506. api_logic_server_cli/prototypes/manager/samples/basic_demo/venv_setup/venv-linux.sh +28 -0
  507. api_logic_server_cli/prototypes/manager/samples/basic_demo/venv_setup/venv.ps1 +21 -0
  508. api_logic_server_cli/prototypes/manager/samples/basic_demo/venv_setup/venv.sh +28 -0
  509. api_logic_server_cli/prototypes/manager/samples/dbs/readme_dbs.md +4 -4
  510. api_logic_server_cli/prototypes/manager/samples/readme_samples.md +13 -6
  511. api_logic_server_cli/prototypes/manager/system/Manager_workspace.code-workspace +3 -2
  512. {apilogicserver-15.0.65.dist-info → apilogicserver-15.1.0.dist-info}/METADATA +1 -1
  513. {apilogicserver-15.0.65.dist-info → apilogicserver-15.1.0.dist-info}/RECORD +517 -17
  514. api_logic_server_cli/prototypes/manager/.vscode/.copilot-instructions.md +0 -58
  515. api_logic_server_cli/prototypes/manager/.vscode/ApiLogicServer.code-workspace +0 -15
  516. {apilogicserver-15.0.65.dist-info → apilogicserver-15.1.0.dist-info}/WHEEL +0 -0
  517. {apilogicserver-15.0.65.dist-info → apilogicserver-15.1.0.dist-info}/entry_points.txt +0 -0
  518. {apilogicserver-15.0.65.dist-info → apilogicserver-15.1.0.dist-info}/licenses/LICENSE +0 -0
  519. {apilogicserver-15.0.65.dist-info → apilogicserver-15.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1180 @@
1
+ # Behave Creates Executable Test Suite, Documentation
2
+
3
+ You can optionally use the Behave test framework to:
4
+
5
+ 1. **Create and Run an Executable Test Suite:** in your IDE, create test definitions (similar to what is shown in the report below), and Python code to execute tests. You can then execute your test suite with 1 command.
6
+
7
+ 2. **Requirements and Test Documentation:** as shown below, you can then create a wiki report that documents your requirements, and the tests (**Scenarios**) that confirm their proper operation.
8
+
9
+ * **Logic Documentation:** the report integrates your logic, including a logic report showing your logic (rules and Python), and a Logic Log that shows exactly how the rules executed. Logic Doc can further contribute to Agile Collaboration.
10
+
11
+ <figure><img src="https://raw.githubusercontent.com/ApiLogicServer/Docs/main/docs/images/behave/behave-summary.png" height="600"></figure>
12
+
13
+
14
+
15
+ [Behave](https://behave.readthedocs.io/en/stable/tutorial.html) is a framework for defining and executing tests. It is based on [TDD (Test Driven Development)](http://dannorth.net/introducing-bdd/), an Agile approach for defining system requirements as executable tests.
16
+
17
+ &nbsp;&nbsp;
18
+
19
+ # Using Behave
20
+
21
+ <figure><img src="https://raw.githubusercontent.com/ApiLogicServer/Docs/main/docs/images/behave/TDD-ide.png?raw=true"></figure>
22
+
23
+ Behave is pre-installed with API Logic Server. Use it as shown above:
24
+
25
+ 1. Create `.feature` files to define ***Scenarios*** (aka tests) for ***Features*** (aka Stories)
26
+
27
+ 2. Code `.py` files to implement Scenario tests
28
+
29
+ 3. Run Test Suite: Launch Configuration `Behave Run`. This runs all your Scenarios, and produces a summary report of your Features and the test results.
30
+
31
+ 4. Report: Launch Configuration `Behave Report` to create the wiki file shown at the top of this page.
32
+
33
+ These steps are further defined, below. Explore the samples in the sample project.
34
+
35
+ &nbsp;&nbsp;
36
+
37
+ ## 1. Create `.feature` file to define Scenario
38
+
39
+ Feature (aka Story) files are designed to promote IT / business user collaboration.
40
+
41
+ &nbsp;&nbsp;
42
+
43
+ ## 2. Code `.py` file to implement test
44
+
45
+ Implement your tests in Python. Here, the tests are largely _read existing data_, _run transaction_, and _test results_, using the API. You can obtain the URLs from the swagger.
46
+
47
+ Key points:
48
+
49
+ * Link your scenario / implementations with annotations, as shown for _Order Placed with excessive quantity_.
50
+
51
+ * Include the `test_utils.prt()` call; be sure to use specify the scenario name as the 2nd argument. This is what drives the name of the Logic Log file, discussed below.
52
+
53
+ * Optionally, include a Python docstring on your `when` implementation as shown above, delimited by `"""` strings (see _"Familiar logic pattern"_ in the screen shot, above). If provided, this will be written into the wiki report.
54
+
55
+ * Important: the system assumes the following line identifies the scenario_name; be sure to include it.
56
+
57
+ &nbsp;&nbsp;
58
+
59
+ ## 3. Run Test Suite: Launch Configuration `Behave Run`
60
+
61
+ You can now execute your Test Suite. Run the `Behave Run` Launch Configuration, and Behave will run all of the tests, producing the outputs (`behave.log` and `<scenario.logs>` shown above.
62
+
63
+ * Windows users will need to run `Windows Behave Run`
64
+
65
+ * You can run just 1 scenario using `Behave Scenario`
66
+
67
+ * You can set breakpoints in your tests
68
+
69
+ The server must be running for these tests. Use the Launch Configuration `ApiLogicServer`, or `python api_logic_server_run.py`. The latter does not run the debugger, which you may find more convenient since changes to your test code won't restart the server.
70
+
71
+ &nbsp;&nbsp;
72
+
73
+ ## 4. Report: Launch Configuration `Behave Report'
74
+
75
+ Run this to create the wiki reports from the logs in step 3.
76
+
77
+
78
+ &nbsp;
79
+ &nbsp;
80
+
81
+
82
+ # Behave Logic Report
83
+ &nbsp;
84
+ &nbsp;
85
+ ## Feature: About Sample
86
+
87
+ &nbsp;
88
+ &nbsp;
89
+ ### Scenario: Transaction Processing
90
+ &emsp; Scenario: Transaction Processing
91
+ &emsp;&emsp; Given Sample Database
92
+ &emsp;&emsp; When Transactions are submitted
93
+ &emsp;&emsp; Then Enforce business policies with Logic (rules + code)
94
+ <details markdown>
95
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
96
+
97
+
98
+ &nbsp;
99
+ &nbsp;
100
+
101
+
102
+ **Rules Used** in Scenario: Transaction Processing
103
+ ```
104
+ Category
105
+ 1. Constraint Function: <function declare_logic.<locals>.valid_category_description at 0x10b83fba0>
106
+
107
+ ```
108
+ **Logic Log** in Scenario: Transaction Processing
109
+ ```
110
+
111
+ The following rules have been activate
112
+ - 2024-07-12 14:57:05,237 - logic_logger - DEBU
113
+ Rule Bank[0x10a431ca0] (loaded 2024-07-12 14:56:46.929015
114
+ Mapped Class[Customer] rules
115
+ Constraint Function: None
116
+ Constraint Function: None
117
+ Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>
118
+ RowEvent Customer.customer_defaults()
119
+ Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>
120
+ Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None
121
+ Mapped Class[Employee] rules
122
+ Constraint Function: None
123
+ Constraint Function: <function declare_logic.<locals>.raise_over_20_percent at 0x10b959940>
124
+ Copy to: EmployeeAudi
125
+ Mapped Class[Category] rules
126
+ Constraint Function: <function declare_logic.<locals>.valid_category_description at 0x10b83fba0>
127
+ Mapped Class[Order] rules
128
+ Derive Order.AmountTotal as Sum(OrderDetail.Amount Where None
129
+ RowEvent Order.send_order_to_shipping()
130
+ RowEvent Order.congratulate_sales_rep()
131
+ RowEvent Order.do_not_ship_empty_orders()
132
+ Constraint Function: <function declare_logic.<locals>.ship_ready_orders_only at 0x10b9591c0>
133
+ RowEvent Order.order_defaults()
134
+ Derive Order.OrderDetailCount as Count(<class 'database.models.OrderDetail'> Where None
135
+ RowEvent Order.clone_order()
136
+ Derive Order.OrderDate as Formula (1): as_expression=lambda row: datetime.datetime.now()
137
+ Mapped Class[OrderDetail] rules
138
+ Derive OrderDetail.Amount as Formula (1): as_expression=lambda row: row.UnitPrice * row.Qua [...
139
+ Derive OrderDetail.UnitPrice as Copy(Product.UnitPrice
140
+ RowEvent OrderDetail.order_detail_defaults()
141
+ Derive OrderDetail.ShippedDate as Formula (2): row.Order.ShippedDat
142
+ Mapped Class[Product] rules
143
+ Derive Product.UnitsInStock as Formula (1): <function
144
+ Derive Product.UnitsShipped as Sum(OrderDetail.Quantity Where <function declare_logic.<locals>.<lambda> at 0x10b959580>
145
+ Logic Bank - 32 rules loaded - 2024-07-12 14:57:05,243 - logic_logger - INF
146
+ Logic Bank - 32 rules loaded - 2024-07-12 14:57:05,243 - logic_logger - INF
147
+
148
+ Logic Phase: ROW LOGIC (session=0x10dbbc710) (sqlalchemy before_flush) - 2024-07-12 14:57:06,076 - logic_logger - INF
149
+ ..Shipper[1] {Delete - client} Id: 1, CompanyName: Speedy Express, Phone: (503) 555-9831 row: 0x10dbbce30 session: 0x10dbbc710 ins_upd_dlt: dlt - 2024-07-12 14:57:06,077 - logic_logger - INF
150
+
151
+ Logic Phase: ROW LOGIC (session=0x10dcac9e0) (sqlalchemy before_flush) - 2024-07-12 14:57:06,151 - logic_logger - INF
152
+ ..Category[1] {Update - client} Id: 1, CategoryName: Beverages, Description: [Soft drinks, coffees, teas, beers, and ales-->] x, Client_id: 1 row: 0x10dcad6a0 session: 0x10dcac9e0 ins_upd_dlt: upd - 2024-07-12 14:57:06,151 - logic_logger - INF
153
+ ..Category[1] {Constraint Failure: Description cannot be 'x'} Id: 1, CategoryName: Beverages, Description: [Soft drinks, coffees, teas, beers, and ales-->] x, Client_id: 1 row: 0x10dcad6a0 session: 0x10dcac9e0 ins_upd_dlt: upd - 2024-07-12 14:57:06,152 - logic_logger - INF
154
+
155
+ ```
156
+ </details>
157
+
158
+ &nbsp;
159
+ &nbsp;
160
+ ## Feature: Application Integration
161
+
162
+ &nbsp;
163
+ &nbsp;
164
+ ### Scenario: GET Customer
165
+ &emsp; Scenario: GET Customer
166
+ &emsp;&emsp; Given Customer Account: VINET
167
+ &emsp;&emsp; When GET Orders API
168
+ &emsp;&emsp; Then VINET retrieved
169
+
170
+ &nbsp;
171
+ &nbsp;
172
+ ### Scenario: GET Department
173
+ &emsp; Scenario: GET Department
174
+ &emsp;&emsp; Given Department 2
175
+ &emsp;&emsp; When GET Department with SubDepartments API
176
+ &emsp;&emsp; Then SubDepartments returned
177
+
178
+ &nbsp;
179
+ &nbsp;
180
+ ## Feature: Authorization
181
+
182
+ &nbsp;
183
+ &nbsp;
184
+ ### Scenario: Grant
185
+ &emsp; Scenario: Grant
186
+ &emsp;&emsp; Given NW Test Database
187
+ &emsp;&emsp; When u1 GETs Categories
188
+ &emsp;&emsp; Then Only 1 is returned
189
+
190
+ &nbsp;
191
+ &nbsp;
192
+ ### Scenario: Multi-tenant
193
+ &emsp; Scenario: Multi-tenant
194
+ &emsp;&emsp; Given NW Test Database
195
+ &emsp;&emsp; When sam GETs Customers
196
+ &emsp;&emsp; Then only 3 are returned
197
+
198
+ &nbsp;
199
+ &nbsp;
200
+ ### Scenario: Global Filters
201
+ &emsp; Scenario: Global Filters
202
+ &emsp;&emsp; Given NW Test Database
203
+ &emsp;&emsp; When sam GETs Departments
204
+ &emsp;&emsp; Then only 8 are returned
205
+
206
+ &nbsp;
207
+ &nbsp;
208
+ ### Scenario: Global Filters With Grants
209
+ &emsp; Scenario: Global Filters With Grants
210
+ &emsp;&emsp; Given NW Test Database
211
+ &emsp;&emsp; When s1 GETs Customers
212
+ &emsp;&emsp; Then only 1 customer is returned
213
+
214
+ &nbsp;
215
+ &nbsp;
216
+ ### Scenario: CRUD Permissions
217
+ &emsp; Scenario: CRUD Permissions
218
+ &emsp;&emsp; Given NW Test Database
219
+ &emsp;&emsp; When r1 deletes a Shipper
220
+ &emsp;&emsp; Then Operation is Refused
221
+
222
+ &nbsp;
223
+ &nbsp;
224
+ ## Feature: Optimistic Locking
225
+
226
+ &nbsp;
227
+ &nbsp;
228
+ ### Scenario: Get Category
229
+ &emsp; Scenario: Get Category
230
+ &emsp;&emsp; Given Category: 1
231
+ &emsp;&emsp; When Get Cat1
232
+ &emsp;&emsp; Then Expected Cat1 Checksum
233
+
234
+ &nbsp;
235
+ &nbsp;
236
+ ### Scenario: Valid Checksum
237
+ &emsp; Scenario: Valid Checksum
238
+ &emsp;&emsp; Given Category: 1
239
+ &emsp;&emsp; When Patch Valid Checksum
240
+ &emsp;&emsp; Then Valid Checksum, Invalid Description
241
+
242
+ &nbsp;
243
+ &nbsp;
244
+ ### Scenario: Missing Checksum
245
+ &emsp; Scenario: Missing Checksum
246
+ &emsp;&emsp; Given Category: 1
247
+ &emsp;&emsp; When Patch Missing Checksum
248
+ &emsp;&emsp; Then Valid Checksum, Invalid Description
249
+
250
+ &nbsp;
251
+ &nbsp;
252
+ ### Scenario: Invalid Checksum
253
+ &emsp; Scenario: Invalid Checksum
254
+ &emsp;&emsp; Given Category: 1
255
+ &emsp;&emsp; When Patch Invalid Checksum
256
+ &emsp;&emsp; Then Invalid Checksum
257
+
258
+ &nbsp;
259
+ &nbsp;
260
+ ## Feature: Place Order
261
+
262
+ &nbsp;
263
+ &nbsp;
264
+ ### Scenario: Order Made Not Ready
265
+ &emsp; Scenario: Order Made Not Ready
266
+ &emsp;&emsp; Given Customer Account: ALFKI
267
+ &emsp;&emsp; When Ready Flag is Reset
268
+ &emsp;&emsp; Then Logic Decreases Balance
269
+ <details markdown>
270
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
271
+
272
+
273
+ &nbsp;
274
+ &nbsp;
275
+
276
+
277
+ **Logic Doc** for scenario: Order Made Not Ready
278
+
279
+ We reset `Order.Ready`.
280
+
281
+ This removes the order from contingent derivations (e.g., the `Customer.Balance`),
282
+ and constraints.
283
+
284
+ > **Key Takeaway:** adjustment from change in qualification condition
285
+
286
+
287
+
288
+ &nbsp;
289
+ &nbsp;
290
+
291
+
292
+ **Rules Used** in Scenario: Order Made Not Ready
293
+ ```
294
+ Customer
295
+ 1. RowEvent Customer.customer_defaults()
296
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
297
+ 3. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
298
+ 4. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
299
+ Order
300
+ 5. RowEvent Order.do_not_ship_empty_orders()
301
+ 6. RowEvent Order.send_order_to_shipping()
302
+ 7. RowEvent Order.congratulate_sales_rep()
303
+ 8. RowEvent Order.clone_order()
304
+ 9. RowEvent Order.order_defaults()
305
+
306
+ ```
307
+ **Logic Log** in Scenario: Order Made Not Ready
308
+ ```
309
+
310
+ Logic Phase: ROW LOGIC (session=0x10d963020) (sqlalchemy before_flush) - 2024-07-12 14:57:06,406 - logic_logger - INF
311
+ ..Order[11011] {Update - client} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [True-->] False, OrderDetailCount: 2, CloneFromOrder: None row: 0x10db4e060 session: 0x10d963020 ins_upd_dlt: upd - 2024-07-12 14:57:06,407 - logic_logger - INF
312
+ ..Order[11011] {Prune Formula: OrderDate [[]]} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [True-->] False, OrderDetailCount: 2, CloneFromOrder: None row: 0x10db4e060 session: 0x10d963020 ins_upd_dlt: upd - 2024-07-12 14:57:06,408 - logic_logger - INF
313
+ ....Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 1142.0000000000, CreditLimit: 2300.0000000000, OrderCount: 15, UnpaidOrderCount: 10, Client_id: 1 row: 0x10dcaf890 session: 0x10d963020 ins_upd_dlt: upd - 2024-07-12 14:57:06,412 - logic_logger - INF
314
+ Logic Phase: COMMIT LOGIC (session=0x10d963020) - 2024-07-12 14:57:06,416 - logic_logger - INF
315
+ ..Order[11011] {Commit Event} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [True-->] False, OrderDetailCount: 2, CloneFromOrder: None row: 0x10db4e060 session: 0x10d963020 ins_upd_dlt: upd - 2024-07-12 14:57:06,416 - logic_logger - INF
316
+ ..Order[11011] {Commit Event} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [True-->] False, OrderDetailCount: 2, CloneFromOrder: None row: 0x10db4e060 session: 0x10d963020 ins_upd_dlt: upd - 2024-07-12 14:57:06,417 - logic_logger - INF
317
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10d963020) - 2024-07-12 14:57:06,422 - logic_logger - INF
318
+ ..Order[11011] {AfterFlush Event} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [True-->] False, OrderDetailCount: 2, CloneFromOrder: None row: 0x10db4e060 session: 0x10d963020 ins_upd_dlt: upd - 2024-07-12 14:57:06,423 - logic_logger - INF
319
+
320
+ ```
321
+ </details>
322
+
323
+ &nbsp;
324
+ &nbsp;
325
+ ### Scenario: Order Made Ready
326
+ &emsp; Scenario: Order Made Ready
327
+ &emsp;&emsp; Given Customer Account: ALFKI
328
+ &emsp;&emsp; When Ready Flag is Set
329
+ &emsp;&emsp; Then Logic Increases Balance
330
+ <details markdown>
331
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
332
+
333
+
334
+ &nbsp;
335
+ &nbsp;
336
+
337
+
338
+ **Logic Doc** for scenario: Order Made Ready
339
+
340
+ This illustrates the _ready flag_ pattern:
341
+ 1. Add a ready flag to the Order
342
+ 2. Make logic contingent on the ready flag:
343
+ * Customer.Balance is increased only if the Order is ready
344
+ * Empty Orders are not rejected
345
+
346
+ This enables the user to submit multiple transactions (add order details, alter them etc),
347
+ before making the order ready (like a checkout).
348
+
349
+ Until then, Customer's Balance adjustments, or empty orders constraints do not fire.
350
+
351
+ > **Key Takeaway:** the ready flag defers constraints/derivations until the user is ready.
352
+
353
+ > **Key Takeaway:** adjustment from change in qualification condition
354
+
355
+
356
+
357
+ &nbsp;
358
+ &nbsp;
359
+
360
+
361
+ **Rules Used** in Scenario: Order Made Ready
362
+ ```
363
+ Customer
364
+ 1. RowEvent Customer.customer_defaults()
365
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
366
+ 3. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
367
+ 4. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
368
+ Order
369
+ 5. RowEvent Order.do_not_ship_empty_orders()
370
+ 6. RowEvent Order.send_order_to_shipping()
371
+ 7. RowEvent Order.congratulate_sales_rep()
372
+ 8. RowEvent Order.clone_order()
373
+ 9. RowEvent Order.order_defaults()
374
+
375
+ ```
376
+ **Logic Log** in Scenario: Order Made Ready
377
+ ```
378
+
379
+ Logic Phase: ROW LOGIC (session=0x10dd240b0) (sqlalchemy before_flush) - 2024-07-12 14:57:06,786 - logic_logger - INF
380
+ ..Order[11011] {Update - client} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [False-->] True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd27740 session: 0x10dd240b0 ins_upd_dlt: upd - 2024-07-12 14:57:06,787 - logic_logger - INF
381
+ ..Order[11011] {Prune Formula: OrderDate [[]]} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [False-->] True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd27740 session: 0x10dd240b0 ins_upd_dlt: upd - 2024-07-12 14:57:06,788 - logic_logger - INF
382
+ ....Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [1142.0000000000-->] 2102.0000000000, CreditLimit: 2300.0000000000, OrderCount: 15, UnpaidOrderCount: 10, Client_id: 1 row: 0x10dcae1b0 session: 0x10dd240b0 ins_upd_dlt: upd - 2024-07-12 14:57:06,790 - logic_logger - INF
383
+ Logic Phase: COMMIT LOGIC (session=0x10dd240b0) - 2024-07-12 14:57:06,794 - logic_logger - INF
384
+ ..Order[11011] {Commit Event} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [False-->] True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd27740 session: 0x10dd240b0 ins_upd_dlt: upd - 2024-07-12 14:57:06,794 - logic_logger - INF
385
+ ..Order[11011] {Commit Event} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [False-->] True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd27740 session: 0x10dd240b0 ins_upd_dlt: upd - 2024-07-12 14:57:06,794 - logic_logger - INF
386
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10dd240b0) - 2024-07-12 14:57:06,796 - logic_logger - INF
387
+ ..Order[11011] {AfterFlush Event} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [False-->] True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd27740 session: 0x10dd240b0 ins_upd_dlt: upd - 2024-07-12 14:57:06,797 - logic_logger - INF
388
+ ..Order[11011] {Sending Order to Shipping << not activated >>} Id: 11011, CustomerId: ALFKI, EmployeeId: 3, OrderDate: 2014-04-09, RequiredDate: 2014-05-07, ShippedDate: None, ShipVia: 1, Freight: 1.2100000000, ShipName: Alfred's Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 960.00, Country: None, City: None, Ready: [False-->] True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd27740 session: 0x10dd240b0 ins_upd_dlt: upd - 2024-07-12 14:57:06,806 - logic_logger - INF
389
+
390
+ ```
391
+ </details>
392
+
393
+ &nbsp;
394
+ &nbsp;
395
+ ### Scenario: Good Order Custom Service
396
+ &emsp; Scenario: Good Order Custom Service
397
+ &emsp;&emsp; Given Customer Account: ALFKI
398
+ &emsp;&emsp; When Good Order Placed
399
+ &emsp;&emsp; Then Logic adjusts Balance (demo: chain up)
400
+ &emsp;&emsp; Then Logic adjusts Products Reordered
401
+ &emsp;&emsp; Then Logic sends email to salesrep
402
+ &emsp;&emsp; Then Logic sends kafka message
403
+ &emsp;&emsp; Then Logic adjusts aggregates down on delete order
404
+ <details markdown>
405
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
406
+
407
+
408
+ &nbsp;
409
+ &nbsp;
410
+
411
+
412
+ **Logic Doc** for scenario: Good Order Custom Service
413
+
414
+ Familiar logic patterns:
415
+
416
+ * Constrain a derived result (Check Credit)
417
+ * Chain up, to adjust parent sum/count aggregates (AmountTotal, Balance)
418
+ * Events for Lib Access (Kafka, email messages)
419
+
420
+ Logic Design ("Cocktail Napkin Design")
421
+
422
+ * Customer.Balance <= CreditLimit
423
+ * Customer.Balance = Sum(Order.AmountTotal where unshipped)
424
+ * Order.AmountTotal = Sum(OrderDetail.Amount)
425
+ * OrderDetail.Amount = Quantity * UnitPrice
426
+ * OrderDetail.UnitPrice = copy from Product
427
+
428
+ We place an Order with an Order Detail. It's one transaction.
429
+
430
+ Note how the `Order.AmountTotal` and `Customer.Balance` are *adjusted* as Order Details are processed.
431
+ Similarly, the `Product.UnitsShipped` is adjusted, and used to recompute `UnitsInStock`
432
+
433
+ <figure><img src="https://github.com/valhuber/ApiLogicServer/wiki/images/behave/declare-logic.png?raw=true"></figure>
434
+
435
+ > **Key Takeaway:** sum/count aggregates (e.g., `Customer.Balance`) automate ***chain up*** multi-table transactions.
436
+
437
+ **Events - Extensible Logic**
438
+
439
+ Inspect the log for __Hi, Andrew - Congratulate Nancy on their new order__.
440
+
441
+ The `congratulate_sales_rep` event illustrates logic
442
+ [Extensibility](https://apilogicserver.github.io/Docs/Logic/#extensibility-python-events)
443
+ - using Python to provide logic not covered by rules,
444
+ like non-database operations such as sending email or messages.
445
+
446
+ <figure><img src="https://github.com/valhuber/ApiLogicServer/wiki/images/behave/send-email.png?raw=true"></figure>
447
+
448
+ There are actually multiple kinds of events:
449
+
450
+ * *Before* row logic
451
+ * *After* row logic
452
+ * On *commit,* after all row logic has completed (as here), so that your code "sees" the full logic results
453
+
454
+ Events are passed the `row` and `old_row`, as well as `logic_row` which enables you to test the actual operation, chaining nest level, etc.
455
+
456
+ You can set breakpoints in events, and inspect these.
457
+
458
+ #als: Behave Test, Invoking API from Python
459
+
460
+
461
+
462
+ &nbsp;
463
+ &nbsp;
464
+
465
+
466
+ **Rules Used** in Scenario: Good Order Custom Service
467
+ ```
468
+ Customer
469
+ 1. RowEvent Customer.customer_defaults()
470
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
471
+ 3. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
472
+ 4. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
473
+ Order
474
+ 5. RowEvent Order.do_not_ship_empty_orders()
475
+ 6. Derive Order.AmountTotal as Sum(OrderDetail.Amount Where None)
476
+ 7. RowEvent Order.congratulate_sales_rep()
477
+ 8. RowEvent Order.send_order_to_shipping()
478
+ 9. RowEvent Order.clone_order()
479
+ 10. Derive Order.OrderDetailCount as Count(<class 'database.models.OrderDetail'> Where None)
480
+ 11. Derive Order.OrderDate as Formula (1): as_expression=lambda row: datetime.datetime.now())
481
+ 12. RowEvent Order.order_defaults()
482
+ OrderDetail
483
+ 13. Derive OrderDetail.Amount as Formula (1): as_expression=lambda row: row.UnitPrice * row.Qua [...]
484
+ 14. Derive OrderDetail.ShippedDate as Formula (2): row.Order.ShippedDate
485
+ 15. RowEvent OrderDetail.order_detail_defaults()
486
+ 16. Derive OrderDetail.UnitPrice as Copy(Product.UnitPrice)
487
+ Product
488
+ 17. Derive Product.UnitsInStock as Formula (1): <function>
489
+ 18. Derive Product.UnitsShipped as Sum(OrderDetail.Quantity Where <function declare_logic.<locals>.<lambda> at 0x10b959580>)
490
+
491
+ ```
492
+ **Logic Log** in Scenario: Good Order Custom Service
493
+ ```
494
+
495
+ Logic Phase: ROW LOGIC (session=0x10dd24320) (sqlalchemy before_flush) - 2024-07-12 14:57:07,152 - logic_logger - INF
496
+ ..Order[None] {Insert - client} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: None, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,153 - logic_logger - INF
497
+ ..Order[None] {server_defaults: OrderDetailCount -- skipped: Ready[BOOLEAN (not handled)] } Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,154 - logic_logger - INF
498
+ ..Order[None] {Formula OrderDate} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,162 - logic_logger - INF
499
+ ....Customer[ALFKI] {Update - Adjusting Customer: UnpaidOrderCount, OrderCount} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: 2102.0000000000, CreditLimit: 2300.0000000000, OrderCount: [15-->] 16, UnpaidOrderCount: [10-->] 11, Client_id: 1 row: 0x10dbbcd10 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,163 - logic_logger - INF
500
+ ..OrderDetail[None] {Insert - client} Id: None, OrderId: None, ProductId: 1, UnitPrice: None, Quantity: 1, Discount: 0, Amount: None, ShippedDate: None row: 0x10db4eea0 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,166 - logic_logger - INF
501
+ ..OrderDetail[None] {copy_rules for role: Product - UnitPrice} Id: None, OrderId: None, ProductId: 1, UnitPrice: 18.0000000000, Quantity: 1, Discount: 0, Amount: None, ShippedDate: None row: 0x10db4eea0 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,169 - logic_logger - INF
502
+ ..OrderDetail[None] {Formula Amount} Id: None, OrderId: None, ProductId: 1, UnitPrice: 18.0000000000, Quantity: 1, Discount: 0, Amount: 18.0000000000, ShippedDate: None row: 0x10db4eea0 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,170 - logic_logger - INF
503
+ ....Order[None] {Update - Adjusting Order: AmountTotal, OrderDetailCount} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [0-->] 18.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [0-->] 1, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,171 - logic_logger - INF
504
+ ....Order[None] {Prune Formula: OrderDate [[]]} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [0-->] 18.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [0-->] 1, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,172 - logic_logger - INF
505
+ ......Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 2120.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11, Client_id: 1 row: 0x10dbbcd10 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,172 - logic_logger - INF
506
+ ....Product[1] {Update - Adjusting Product: UnitsShipped} Id: 1, ProductName: Chai, SupplierId: 1, CategoryId: 1, QuantityPerUnit: 10 boxes x 20 bags, UnitPrice: 18.0000000000, UnitsInStock: 39, UnitsOnOrder: 0, ReorderLevel: 10, Discontinued: 0, UnitsShipped: [0-->] 1 row: 0x10dd268d0 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,176 - logic_logger - INF
507
+ ....Product[1] {Formula UnitsInStock} Id: 1, ProductName: Chai, SupplierId: 1, CategoryId: 1, QuantityPerUnit: 10 boxes x 20 bags, UnitPrice: 18.0000000000, UnitsInStock: [39-->] 38, UnitsOnOrder: 0, ReorderLevel: 10, Discontinued: 0, UnitsShipped: [0-->] 1 row: 0x10dd268d0 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,176 - logic_logger - INF
508
+ ..OrderDetail[None] {Insert - client} Id: None, OrderId: None, ProductId: 2, UnitPrice: None, Quantity: 2, Discount: 0, Amount: None, ShippedDate: None row: 0x10dbbfd70 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,177 - logic_logger - INF
509
+ ..OrderDetail[None] {copy_rules for role: Product - UnitPrice} Id: None, OrderId: None, ProductId: 2, UnitPrice: 19.0000000000, Quantity: 2, Discount: 0, Amount: None, ShippedDate: None row: 0x10dbbfd70 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,179 - logic_logger - INF
510
+ ..OrderDetail[None] {Formula Amount} Id: None, OrderId: None, ProductId: 2, UnitPrice: 19.0000000000, Quantity: 2, Discount: 0, Amount: 38.0000000000, ShippedDate: None row: 0x10dbbfd70 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,180 - logic_logger - INF
511
+ ....Order[None] {Update - Adjusting Order: AmountTotal, OrderDetailCount} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [18.0000000000-->] 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [1-->] 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,181 - logic_logger - INF
512
+ ....Order[None] {Prune Formula: OrderDate [[]]} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [18.0000000000-->] 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [1-->] 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,182 - logic_logger - INF
513
+ ......Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2120.0000000000-->] 2158.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11, Client_id: 1 row: 0x10dbbcd10 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,182 - logic_logger - INF
514
+ ....Product[2] {Update - Adjusting Product: UnitsShipped} Id: 2, ProductName: Chang, SupplierId: 1, CategoryId: 1, QuantityPerUnit: 24 - 12 oz bottles, UnitPrice: 19.0000000000, UnitsInStock: 17, UnitsOnOrder: 40, ReorderLevel: 25, Discontinued: 0, UnitsShipped: [0-->] 2 row: 0x10dcad370 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,186 - logic_logger - INF
515
+ ....Product[2] {Formula UnitsInStock} Id: 2, ProductName: Chang, SupplierId: 1, CategoryId: 1, QuantityPerUnit: 24 - 12 oz bottles, UnitPrice: 19.0000000000, UnitsInStock: [17-->] 15, UnitsOnOrder: 40, ReorderLevel: 25, Discontinued: 0, UnitsShipped: [0-->] 2 row: 0x10dcad370 session: 0x10dd24320 ins_upd_dlt: upd - 2024-07-12 14:57:07,186 - logic_logger - INF
516
+ Logic Phase: COMMIT LOGIC (session=0x10dd24320) - 2024-07-12 14:57:07,187 - logic_logger - INF
517
+ ..Order[None] {Commit Event} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,188 - logic_logger - INF
518
+ ..Order[None] {Hi, Andrew - Congratulate Nancy on their new order} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,190 - logic_logger - INF
519
+ ..Order[None] {Illustrate database access} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,192 - logic_logger - INF
520
+ ..Order[None] {Commit Event} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,193 - logic_logger - INF
521
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10dd24320) - 2024-07-12 14:57:07,206 - logic_logger - INF
522
+ ..Order[11078] {AfterFlush Event} Id: 11078, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,207 - logic_logger - INF
523
+ ..Order[11078] {Sending Order to Shipping << not activated >>} Id: 11078, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.162349, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 56.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 2, CloneFromOrder: None row: 0x10dd25520 session: 0x10dd24320 ins_upd_dlt: ins - 2024-07-12 14:57:07,211 - logic_logger - INF
524
+
525
+ ```
526
+ </details>
527
+
528
+ &nbsp;
529
+ &nbsp;
530
+ ### Scenario: Bad Ship of Empty Order
531
+ &emsp; Scenario: Bad Ship of Empty Order
532
+ &emsp;&emsp; Given Customer Account: ALFKI
533
+ &emsp;&emsp; When Order Shipped with no Items
534
+ &emsp;&emsp; Then Rejected per Do Not Ship Empty Orders
535
+ <details markdown>
536
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
537
+
538
+
539
+ &nbsp;
540
+ &nbsp;
541
+
542
+
543
+ **Logic Doc** for scenario: Bad Ship of Empty Order
544
+
545
+ Reuse the rules for Good Order...
546
+
547
+ Familiar logic patterns:
548
+
549
+ * Constrain a derived result
550
+ * Counts as existence checks
551
+
552
+ Logic Design ("Cocktail Napkin Design")
553
+
554
+ * Constraint: do_not_ship_empty_orders()
555
+ * Order.OrderDetailCount = count(OrderDetail)
556
+
557
+
558
+
559
+ &nbsp;
560
+ &nbsp;
561
+
562
+
563
+ **Rules Used** in Scenario: Bad Ship of Empty Order
564
+ ```
565
+ ```
566
+ **Logic Log** in Scenario: Bad Ship of Empty Order
567
+ ```
568
+
569
+ Logic Phase: ROW LOGIC (session=0x10dbbd370) (sqlalchemy before_flush) - 2024-07-12 14:57:07,836 - logic_logger - INF
570
+ ..Order[None] {Insert - client} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: 2013-10-13, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: None, CloneFromOrder: None row: 0x10dd409b0 session: 0x10dbbd370 ins_upd_dlt: ins - 2024-07-12 14:57:07,837 - logic_logger - INF
571
+ ..Order[None] {server_defaults: OrderDetailCount -- skipped: Ready[BOOLEAN (not handled)] } Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: 2013-10-13, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd409b0 session: 0x10dbbd370 ins_upd_dlt: ins - 2024-07-12 14:57:07,837 - logic_logger - INF
572
+ ..Order[None] {Formula OrderDate} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.841810, RequiredDate: None, ShippedDate: 2013-10-13, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd409b0 session: 0x10dbbd370 ins_upd_dlt: ins - 2024-07-12 14:57:07,842 - logic_logger - INF
573
+ ....Customer[ALFKI] {Update - Adjusting Customer: OrderCount} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: 2102.0000000000, CreditLimit: 2300.0000000000, OrderCount: [15-->] 16, UnpaidOrderCount: 10, Client_id: 1 row: 0x10dd276e0 session: 0x10dbbd370 ins_upd_dlt: upd - 2024-07-12 14:57:07,842 - logic_logger - INF
574
+ Logic Phase: COMMIT LOGIC (session=0x10dbbd370) - 2024-07-12 14:57:07,845 - logic_logger - INF
575
+ ..Order[None] {Commit Event} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.841810, RequiredDate: None, ShippedDate: 2013-10-13, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd409b0 session: 0x10dbbd370 ins_upd_dlt: ins - 2024-07-12 14:57:07,846 - logic_logger - INF
576
+ ..Order[None] {Hi, Andrew - Congratulate Nancy on their new order} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.841810, RequiredDate: None, ShippedDate: 2013-10-13, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd409b0 session: 0x10dbbd370 ins_upd_dlt: ins - 2024-07-12 14:57:07,847 - logic_logger - INF
577
+ ..Order[None] {Illustrate database access} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.841810, RequiredDate: None, ShippedDate: 2013-10-13, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd409b0 session: 0x10dbbd370 ins_upd_dlt: ins - 2024-07-12 14:57:07,848 - logic_logger - INF
578
+ ..Order[None] {Commit Event} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:07.841810, RequiredDate: None, ShippedDate: 2013-10-13, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd409b0 session: 0x10dbbd370 ins_upd_dlt: ins - 2024-07-12 14:57:07,849 - logic_logger - INF
579
+ ```
580
+ </details>
581
+
582
+ &nbsp;
583
+ &nbsp;
584
+ ### Scenario: Bad Order Custom Service
585
+ &emsp; Scenario: Bad Order Custom Service
586
+ &emsp;&emsp; Given Customer Account: ALFKI
587
+ &emsp;&emsp; When Order Placed with excessive quantity
588
+ &emsp;&emsp; Then Rejected per Check Credit
589
+ <details markdown>
590
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
591
+
592
+
593
+ &nbsp;
594
+ &nbsp;
595
+
596
+
597
+ **Logic Doc** for scenario: Bad Order Custom Service
598
+
599
+ Reuse the rules for Good Order...
600
+
601
+ Familiar logic patterns:
602
+
603
+ * Constrain a derived result
604
+ * Chain up, to adjust parent sum/count aggregates
605
+
606
+ Logic Design ("Cocktail Napkin Design")
607
+
608
+ * Customer.Balance <= CreditLimit
609
+ * Customer.Balance = Sum(Order.AmountTotal where unshipped)
610
+ * Order.AmountTotal = Sum(OrderDetail.Amount)
611
+ * OrderDetail.Amount = Quantity * UnitPrice
612
+ * OrderDetail.UnitPrice = copy from Product
613
+
614
+
615
+
616
+ &nbsp;
617
+ &nbsp;
618
+
619
+
620
+ **Rules Used** in Scenario: Bad Order Custom Service
621
+ ```
622
+ Customer
623
+ 1. RowEvent Customer.customer_defaults()
624
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
625
+ 3. Constraint Function: None
626
+ 4. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
627
+ 5. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
628
+ Order
629
+ 6. Derive Order.AmountTotal as Sum(OrderDetail.Amount Where None)
630
+ 7. RowEvent Order.clone_order()
631
+ 8. Derive Order.OrderDetailCount as Count(<class 'database.models.OrderDetail'> Where None)
632
+ 9. Derive Order.OrderDate as Formula (1): as_expression=lambda row: datetime.datetime.now())
633
+ 10. RowEvent Order.order_defaults()
634
+ OrderDetail
635
+ 11. Derive OrderDetail.Amount as Formula (1): as_expression=lambda row: row.UnitPrice * row.Qua [...]
636
+ 12. Derive OrderDetail.ShippedDate as Formula (2): row.Order.ShippedDate
637
+ 13. RowEvent OrderDetail.order_detail_defaults()
638
+ 14. Derive OrderDetail.UnitPrice as Copy(Product.UnitPrice)
639
+ Product
640
+ 15. Derive Product.UnitsInStock as Formula (1): <function>
641
+ 16. Derive Product.UnitsShipped as Sum(OrderDetail.Quantity Where <function declare_logic.<locals>.<lambda> at 0x10b959580>)
642
+ ```
643
+ **Logic Log** in Scenario: Bad Order Custom Service
644
+ ```
645
+
646
+ Logic Phase: ROW LOGIC (session=0x10dd260c0) (sqlalchemy before_flush) - 2024-07-12 14:57:08,015 - logic_logger - INF
647
+ ..Order[None] {Insert - client} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: None, CloneFromOrder: None row: 0x10dd27680 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,016 - logic_logger - INF
648
+ ..Order[None] {server_defaults: OrderDetailCount -- skipped: Ready[BOOLEAN (not handled)] } Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd27680 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,016 - logic_logger - INF
649
+ ..Order[None] {Formula OrderDate} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:08.020499, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: None row: 0x10dd27680 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,020 - logic_logger - INF
650
+ ....Customer[ALFKI] {Update - Adjusting Customer: UnpaidOrderCount, OrderCount} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: 2102.0000000000, CreditLimit: 2300.0000000000, OrderCount: [15-->] 16, UnpaidOrderCount: [10-->] 11, Client_id: 1 row: 0x10dd76a20 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,021 - logic_logger - INF
651
+ ..OrderDetail[None] {Insert - client} Id: None, OrderId: None, ProductId: 2, UnitPrice: None, Quantity: 2, Discount: 0, Amount: None, ShippedDate: None row: 0x10dd76180 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,024 - logic_logger - INF
652
+ ..OrderDetail[None] {copy_rules for role: Product - UnitPrice} Id: None, OrderId: None, ProductId: 2, UnitPrice: 19.0000000000, Quantity: 2, Discount: 0, Amount: None, ShippedDate: None row: 0x10dd76180 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,027 - logic_logger - INF
653
+ ..OrderDetail[None] {Formula Amount} Id: None, OrderId: None, ProductId: 2, UnitPrice: 19.0000000000, Quantity: 2, Discount: 0, Amount: 38.0000000000, ShippedDate: None row: 0x10dd76180 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,028 - logic_logger - INF
654
+ ....Order[None] {Update - Adjusting Order: AmountTotal, OrderDetailCount} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:08.020499, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [0-->] 38.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [0-->] 1, CloneFromOrder: None row: 0x10dd27680 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,029 - logic_logger - INF
655
+ ....Order[None] {Prune Formula: OrderDate [[]]} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:08.020499, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [0-->] 38.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [0-->] 1, CloneFromOrder: None row: 0x10dd27680 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,030 - logic_logger - INF
656
+ ......Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 2140.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11, Client_id: 1 row: 0x10dd76a20 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,031 - logic_logger - INF
657
+ ....Product[2] {Update - Adjusting Product: UnitsShipped} Id: 2, ProductName: Chang, SupplierId: 1, CategoryId: 1, QuantityPerUnit: 24 - 12 oz bottles, UnitPrice: 19.0000000000, UnitsInStock: 17, UnitsOnOrder: 40, ReorderLevel: 25, Discontinued: 0, UnitsShipped: [0-->] 2 row: 0x10dd772c0 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,035 - logic_logger - INF
658
+ ....Product[2] {Formula UnitsInStock} Id: 2, ProductName: Chang, SupplierId: 1, CategoryId: 1, QuantityPerUnit: 24 - 12 oz bottles, UnitPrice: 19.0000000000, UnitsInStock: [17-->] 15, UnitsOnOrder: 40, ReorderLevel: 25, Discontinued: 0, UnitsShipped: [0-->] 2 row: 0x10dd772c0 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,035 - logic_logger - INF
659
+ ..OrderDetail[None] {Insert - client} Id: None, OrderId: None, ProductId: 1, UnitPrice: None, Quantity: 1111, Discount: 0, Amount: None, ShippedDate: None row: 0x10dd76270 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,036 - logic_logger - INF
660
+ ..OrderDetail[None] {copy_rules for role: Product - UnitPrice} Id: None, OrderId: None, ProductId: 1, UnitPrice: 18.0000000000, Quantity: 1111, Discount: 0, Amount: None, ShippedDate: None row: 0x10dd76270 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,038 - logic_logger - INF
661
+ ..OrderDetail[None] {Formula Amount} Id: None, OrderId: None, ProductId: 1, UnitPrice: 18.0000000000, Quantity: 1111, Discount: 0, Amount: 19998.0000000000, ShippedDate: None row: 0x10dd76270 session: 0x10dd260c0 ins_upd_dlt: ins - 2024-07-12 14:57:08,038 - logic_logger - INF
662
+ ....Order[None] {Update - Adjusting Order: AmountTotal, OrderDetailCount} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:08.020499, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [38.0000000000-->] 20036.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [1-->] 2, CloneFromOrder: None row: 0x10dd27680 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,039 - logic_logger - INF
663
+ ....Order[None] {Prune Formula: OrderDate [[]]} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:08.020499, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 10, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [38.0000000000-->] 20036.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [1-->] 2, CloneFromOrder: None row: 0x10dd27680 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,040 - logic_logger - INF
664
+ ......Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2140.0000000000-->] 22138.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11, Client_id: 1 row: 0x10dd76a20 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,041 - logic_logger - INF
665
+ ......Customer[ALFKI] {Constraint Failure: balance (22138.00) exceeds credit (2300.00)} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2140.0000000000-->] 22138.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11, Client_id: 1 row: 0x10dd76a20 session: 0x10dd260c0 ins_upd_dlt: upd - 2024-07-12 14:57:08,042 - logic_logger - INF
666
+
667
+ ```
668
+ </details>
669
+
670
+ &nbsp;
671
+ &nbsp;
672
+ ### Scenario: Alter Item Qty to exceed credit
673
+ &emsp; Scenario: Alter Item Qty to exceed credit
674
+ &emsp;&emsp; Given Customer Account: ALFKI
675
+ &emsp;&emsp; When Order Detail Quantity altered very high
676
+ &emsp;&emsp; Then Rejected per Check Credit
677
+ <details markdown>
678
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
679
+
680
+
681
+ &nbsp;
682
+ &nbsp;
683
+
684
+
685
+ **Logic Doc** for scenario: Alter Item Qty to exceed credit
686
+
687
+ Same constraint as above.
688
+
689
+ > **Key Takeaway:** Automatic Reuse (_design one, solve many_)
690
+
691
+
692
+ &nbsp;
693
+ &nbsp;
694
+
695
+
696
+ **Rules Used** in Scenario: Alter Item Qty to exceed credit
697
+ ```
698
+ Customer
699
+ 1. RowEvent Customer.customer_defaults()
700
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
701
+ 3. Constraint Function: None
702
+ 4. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
703
+ 5. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
704
+ Order
705
+ 6. Derive Order.AmountTotal as Sum(OrderDetail.Amount Where None)
706
+ 7. Derive Order.OrderDetailCount as Count(<class 'database.models.OrderDetail'> Where None)
707
+ 8. RowEvent Order.order_defaults()
708
+ OrderDetail
709
+ 9. RowEvent OrderDetail.order_detail_defaults()
710
+ 10. Derive OrderDetail.Amount as Formula (1): as_expression=lambda row: row.UnitPrice * row.Qua [...]
711
+ ```
712
+ **Logic Log** in Scenario: Alter Item Qty to exceed credit
713
+ ```
714
+
715
+ Logic Phase: ROW LOGIC (session=0x10df71280) (sqlalchemy before_flush) - 2024-07-12 14:57:08,230 - logic_logger - INF
716
+ ..OrderDetail[1040] {Update - client} Id: 1040, OrderId: 10643, ProductId: 28, UnitPrice: 45.6000000000, Quantity: [15-->] 1110, Discount: 0.25, Amount: 684.0000000000, ShippedDate: None row: 0x10dd76000 session: 0x10df71280 ins_upd_dlt: upd - 2024-07-12 14:57:08,231 - logic_logger - INF
717
+ ..OrderDetail[1040] {Formula Amount} Id: 1040, OrderId: 10643, ProductId: 28, UnitPrice: 45.6000000000, Quantity: [15-->] 1110, Discount: 0.25, Amount: [684.0000000000-->] 50616.0000000000, ShippedDate: None row: 0x10dd76000 session: 0x10df71280 ins_upd_dlt: upd - 2024-07-12 14:57:08,232 - logic_logger - INF
718
+ ..OrderDetail[1040] {Prune Formula: ShippedDate [['Order.ShippedDate']]} Id: 1040, OrderId: 10643, ProductId: 28, UnitPrice: 45.6000000000, Quantity: [15-->] 1110, Discount: 0.25, Amount: [684.0000000000-->] 50616.0000000000, ShippedDate: None row: 0x10dd76000 session: 0x10df71280 ins_upd_dlt: upd - 2024-07-12 14:57:08,232 - logic_logger - INF
719
+ ....Order[10643] {Update - Adjusting Order: AmountTotal} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-09-22, ShippedDate: None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: [1086.00-->] 51018.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df718b0 session: 0x10df71280 ins_upd_dlt: upd - 2024-07-12 14:57:08,235 - logic_logger - INF
720
+ ....Order[10643] {Prune Formula: OrderDate [[]]} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-09-22, ShippedDate: None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: [1086.00-->] 51018.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df718b0 session: 0x10df71280 ins_upd_dlt: upd - 2024-07-12 14:57:08,236 - logic_logger - INF
721
+ ......Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 52034.0000000000, CreditLimit: 2300.0000000000, OrderCount: 15, UnpaidOrderCount: 10, Client_id: 1 row: 0x10df71760 session: 0x10df71280 ins_upd_dlt: upd - 2024-07-12 14:57:08,238 - logic_logger - INF
722
+ ......Customer[ALFKI] {Constraint Failure: balance (52034.00) exceeds credit (2300.00)} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 52034.0000000000, CreditLimit: 2300.0000000000, OrderCount: 15, UnpaidOrderCount: 10, Client_id: 1 row: 0x10df71760 session: 0x10df71280 ins_upd_dlt: upd - 2024-07-12 14:57:08,239 - logic_logger - INF
723
+
724
+ ```
725
+ </details>
726
+
727
+ &nbsp;
728
+ &nbsp;
729
+ ### Scenario: Alter Required Date - adjust logic pruned
730
+ &emsp; Scenario: Alter Required Date - adjust logic pruned
731
+ &emsp;&emsp; Given Customer Account: ALFKI
732
+ &emsp;&emsp; When Order RequiredDate altered (2013-10-13)
733
+ &emsp;&emsp; Then Balance not adjusted
734
+ <details markdown>
735
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
736
+
737
+
738
+ &nbsp;
739
+ &nbsp;
740
+
741
+
742
+ **Logic Doc** for scenario: Alter Required Date - adjust logic pruned
743
+
744
+ We set `Order.RequiredDate`.
745
+
746
+ This is a normal update. Nothing depends on the columns altered, so this has no effect on the related Customer, Order Details or Products. Contrast this to the *Cascade Update Test* and the *Custom Service* test, where logic chaining affects related rows. Only the commit event fires.
747
+
748
+ > **Key Takeaway:** rule pruning automatically avoids unnecessary SQL overhead.
749
+
750
+
751
+
752
+ &nbsp;
753
+ &nbsp;
754
+
755
+
756
+ **Rules Used** in Scenario: Alter Required Date - adjust logic pruned
757
+ ```
758
+ Customer
759
+ 1. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
760
+ 2. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
761
+ 3. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
762
+ Order
763
+ 4. RowEvent Order.do_not_ship_empty_orders()
764
+ 5. RowEvent Order.send_order_to_shipping()
765
+ 6. RowEvent Order.congratulate_sales_rep()
766
+ 7. RowEvent Order.clone_order()
767
+ 8. RowEvent Order.order_defaults()
768
+
769
+ ```
770
+ **Logic Log** in Scenario: Alter Required Date - adjust logic pruned
771
+ ```
772
+
773
+ Logic Phase: ROW LOGIC (session=0x10df73920) (sqlalchemy before_flush) - 2024-07-12 14:57:08,435 - logic_logger - INF
774
+ ..Order[10643] {Update - client} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: [2013-09-22-->] 2013-10-13 00:00:00, ShippedDate: None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df71f70 session: 0x10df73920 ins_upd_dlt: upd - 2024-07-12 14:57:08,436 - logic_logger - INF
775
+ ..Order[10643] {Prune Formula: OrderDate [[]]} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: [2013-09-22-->] 2013-10-13 00:00:00, ShippedDate: None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df71f70 session: 0x10df73920 ins_upd_dlt: upd - 2024-07-12 14:57:08,437 - logic_logger - INF
776
+ Logic Phase: COMMIT LOGIC (session=0x10df73920) - 2024-07-12 14:57:08,439 - logic_logger - INF
777
+ ..Order[10643] {Commit Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: [2013-09-22-->] 2013-10-13 00:00:00, ShippedDate: None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df71f70 session: 0x10df73920 ins_upd_dlt: upd - 2024-07-12 14:57:08,439 - logic_logger - INF
778
+ ..Order[10643] {Commit Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: [2013-09-22-->] 2013-10-13 00:00:00, ShippedDate: None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df71f70 session: 0x10df73920 ins_upd_dlt: upd - 2024-07-12 14:57:08,440 - logic_logger - INF
779
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10df73920) - 2024-07-12 14:57:08,442 - logic_logger - INF
780
+ ..Order[10643] {AfterFlush Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: [2013-09-22-->] 2013-10-13 00:00:00, ShippedDate: None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df71f70 session: 0x10df73920 ins_upd_dlt: upd - 2024-07-12 14:57:08,442 - logic_logger - INF
781
+
782
+ ```
783
+ </details>
784
+
785
+ &nbsp;
786
+ &nbsp;
787
+ ### Scenario: Set Shipped - adjust logic reuse
788
+ &emsp; Scenario: Set Shipped - adjust logic reuse
789
+ &emsp;&emsp; Given Customer Account: ALFKI
790
+ &emsp;&emsp; When Order ShippedDate altered (2013-10-13)
791
+ &emsp;&emsp; Then Balance reduced 1086
792
+ <details markdown>
793
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
794
+
795
+
796
+ &nbsp;
797
+ &nbsp;
798
+
799
+
800
+ **Logic Doc** for scenario: Set Shipped - adjust logic reuse
801
+
802
+
803
+ Logic Patterns:
804
+
805
+ * Chain Down
806
+
807
+ Logic Design ("Cocktail Napkin Design")
808
+
809
+ * Formula: OrderDetail.ShippedDate = Order.ShippedDate
810
+
811
+ We set `Order.ShippedDate`.
812
+
813
+ This cascades to the Order Details, per the `derive=models.OrderDetail.ShippedDate` rule.
814
+
815
+ This chains to adjust the `Product.UnitsShipped` and recomputes `UnitsInStock`, as above
816
+
817
+ <figure><img src="https://github.com/valhuber/ApiLogicServer/wiki/images/behave/order-shipped-date.png?raw=true"></figure>
818
+
819
+
820
+ > **Key Takeaway:** parent references (e.g., `OrderDetail.ShippedDate`) automate ***chain-down*** multi-table transactions.
821
+
822
+ > **Key Takeaway:** Automatic Reuse (_design one, solve many_)
823
+
824
+
825
+
826
+ &nbsp;
827
+ &nbsp;
828
+
829
+
830
+ **Rules Used** in Scenario: Set Shipped - adjust logic reuse
831
+ ```
832
+ Customer
833
+ 1. RowEvent Customer.customer_defaults()
834
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
835
+ 3. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
836
+ 4. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
837
+ Order
838
+ 5. RowEvent Order.do_not_ship_empty_orders()
839
+ 6. RowEvent Order.send_order_to_shipping()
840
+ 7. RowEvent Order.congratulate_sales_rep()
841
+ 8. RowEvent Order.clone_order()
842
+ 9. RowEvent Order.order_defaults()
843
+
844
+ ```
845
+ **Logic Log** in Scenario: Set Shipped - adjust logic reuse
846
+ ```
847
+
848
+ Logic Phase: ROW LOGIC (session=0x10dd240e0) (sqlalchemy before_flush) - 2024-07-12 14:57:08,810 - logic_logger - INF
849
+ ..Order[10643] {Update - client} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [None-->] 2013-10-13, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10dd75280 session: 0x10dd240e0 ins_upd_dlt: upd - 2024-07-12 14:57:08,810 - logic_logger - INF
850
+ ..Order[10643] {Prune Formula: OrderDate [[]]} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [None-->] 2013-10-13, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10dd75280 session: 0x10dd240e0 ins_upd_dlt: upd - 2024-07-12 14:57:08,811 - logic_logger - INF
851
+ ....Customer[ALFKI] {Update - Adjusting Customer: Balance, UnpaidOrderCount} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 1016.0000000000, CreditLimit: 2300.0000000000, OrderCount: 15, UnpaidOrderCount: [10-->] 9, Client_id: 1 row: 0x10db76ab0 session: 0x10dd240e0 ins_upd_dlt: upd - 2024-07-12 14:57:08,813 - logic_logger - INF
852
+ Logic Phase: COMMIT LOGIC (session=0x10dd240e0) - 2024-07-12 14:57:08,817 - logic_logger - INF
853
+ ..Order[10643] {Commit Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [None-->] 2013-10-13, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10dd75280 session: 0x10dd240e0 ins_upd_dlt: upd - 2024-07-12 14:57:08,818 - logic_logger - INF
854
+ ..Order[10643] {Commit Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [None-->] 2013-10-13, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10dd75280 session: 0x10dd240e0 ins_upd_dlt: upd - 2024-07-12 14:57:08,818 - logic_logger - INF
855
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10dd240e0) - 2024-07-12 14:57:08,822 - logic_logger - INF
856
+ ..Order[10643] {AfterFlush Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [None-->] 2013-10-13, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10dd75280 session: 0x10dd240e0 ins_upd_dlt: upd - 2024-07-12 14:57:08,822 - logic_logger - INF
857
+
858
+ ```
859
+ </details>
860
+
861
+ &nbsp;
862
+ &nbsp;
863
+ ### Scenario: Reset Shipped - adjust logic reuse
864
+ &emsp; Scenario: Reset Shipped - adjust logic reuse
865
+ &emsp;&emsp; Given Shipped Order
866
+ &emsp;&emsp; When Order ShippedDate set to None
867
+ &emsp;&emsp; Then Logic adjusts Balance by -1086
868
+ <details markdown>
869
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
870
+
871
+
872
+ &nbsp;
873
+ &nbsp;
874
+
875
+
876
+ **Logic Doc** for scenario: Reset Shipped - adjust logic reuse
877
+
878
+ Same logic as above.
879
+
880
+ > **Key Takeaway:** Automatic Reuse (_design one, solve many_)
881
+
882
+
883
+ &nbsp;
884
+ &nbsp;
885
+
886
+
887
+ **Rules Used** in Scenario: Reset Shipped - adjust logic reuse
888
+ ```
889
+ Customer
890
+ 1. RowEvent Customer.customer_defaults()
891
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
892
+ 3. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
893
+ 4. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
894
+ Order
895
+ 5. RowEvent Order.do_not_ship_empty_orders()
896
+ 6. RowEvent Order.send_order_to_shipping()
897
+ 7. RowEvent Order.congratulate_sales_rep()
898
+ 8. RowEvent Order.clone_order()
899
+ 9. RowEvent Order.order_defaults()
900
+
901
+ ```
902
+ **Logic Log** in Scenario: Reset Shipped - adjust logic reuse
903
+ ```
904
+
905
+ Logic Phase: ROW LOGIC (session=0x10df9e6c0) (sqlalchemy before_flush) - 2024-07-12 14:57:09,181 - logic_logger - INF
906
+ ..Order[10643] {Update - client} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [2013-10-13-->] None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df70b30 session: 0x10df9e6c0 ins_upd_dlt: upd - 2024-07-12 14:57:09,182 - logic_logger - INF
907
+ ..Order[10643] {Prune Formula: OrderDate [[]]} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [2013-10-13-->] None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df70b30 session: 0x10df9e6c0 ins_upd_dlt: upd - 2024-07-12 14:57:09,183 - logic_logger - INF
908
+ ....Customer[ALFKI] {Update - Adjusting Customer: Balance, UnpaidOrderCount} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [1016.0000000000-->] 2102.0000000000, CreditLimit: 2300.0000000000, OrderCount: 15, UnpaidOrderCount: [9-->] 10, Client_id: 1 row: 0x10df9cd70 session: 0x10df9e6c0 ins_upd_dlt: upd - 2024-07-12 14:57:09,185 - logic_logger - INF
909
+ Logic Phase: COMMIT LOGIC (session=0x10df9e6c0) - 2024-07-12 14:57:09,189 - logic_logger - INF
910
+ ..Order[10643] {Commit Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [2013-10-13-->] None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df70b30 session: 0x10df9e6c0 ins_upd_dlt: upd - 2024-07-12 14:57:09,189 - logic_logger - INF
911
+ ..Order[10643] {Commit Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [2013-10-13-->] None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df70b30 session: 0x10df9e6c0 ins_upd_dlt: upd - 2024-07-12 14:57:09,190 - logic_logger - INF
912
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10df9e6c0) - 2024-07-12 14:57:09,192 - logic_logger - INF
913
+ ..Order[10643] {AfterFlush Event} Id: 10643, CustomerId: ALFKI, EmployeeId: 6, OrderDate: 2013-08-25, RequiredDate: 2013-10-13, ShippedDate: [2013-10-13-->] None, ShipVia: 1, Freight: 29.4600000000, ShipName: Alfreds Futterkiste, ShipAddress: Obere Str. 57, ShipCity: Berlin, ShipRegion: Western Europe, ShipZip: 12209, ShipCountry: Germany, AmountTotal: 1086.00, Country: None, City: None, Ready: True, OrderDetailCount: 3, CloneFromOrder: None row: 0x10df70b30 session: 0x10df9e6c0 ins_upd_dlt: upd - 2024-07-12 14:57:09,192 - logic_logger - INF
914
+
915
+ ```
916
+ </details>
917
+
918
+ &nbsp;
919
+ &nbsp;
920
+ ### Scenario: Clone Existing Order
921
+ &emsp; Scenario: Clone Existing Order
922
+ &emsp;&emsp; Given Shipped Order
923
+ &emsp;&emsp; When Cloning Existing Order
924
+ &emsp;&emsp; Then Logic Copies ClonedFrom OrderDetails
925
+ <details markdown>
926
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
927
+
928
+
929
+ &nbsp;
930
+ &nbsp;
931
+
932
+
933
+ **Logic Doc** for scenario: Clone Existing Order
934
+
935
+ We create an order, setting CloneFromOrder.
936
+
937
+ This copies the CloneFromOrder OrderDetails to our new Order.
938
+
939
+ The copy operation is automated using `logic_row.copy_children()`:
940
+
941
+ 1. `place_order.feature` defines the test
942
+
943
+ 2. `place_order.py` implements the test. It uses the API to Post an Order, setting `CloneFromOrder` to trigger the copy logic
944
+
945
+ 3. `declare_logic.py` implements the logic, by invoking `logic_row.copy_children()`. `which` defines which children to copy, here just `OrderDetailList`
946
+
947
+ <figure><img src="https://github.com/valhuber/ApiLogicServer/wiki/images/behave/clone-order.png?raw=true"></figure>
948
+
949
+ `CopyChildren` For more information, [see here](https://github.com/valhuber/LogicBank/wiki/Copy-Children)
950
+
951
+ Useful in row event handlers to copy multiple children types to self from copy_from children.
952
+
953
+ child-spec := < ‘child-list-name’ | < ‘child-list-name = parent-list-name’ >
954
+ child-list-spec := [child-spec | (child-spec, child-list-spec)]
955
+
956
+ Eg. RowEvent on Order
957
+ which = ["OrderDetailList"]
958
+ logic_row.copy_children(copy_from=row.parent, which_children=which)
959
+
960
+ Eg, test/copy_children:
961
+ child_list_spec = [
962
+ ("MileStoneList",
963
+ ["DeliverableList"] # for each Milestone, get the Deliverables
964
+ ),
965
+ "StaffList"
966
+ ]
967
+
968
+ > **Key Takeaway:** copy_children provides a deep-copy service.
969
+
970
+
971
+
972
+ &nbsp;
973
+ &nbsp;
974
+
975
+
976
+ **Rules Used** in Scenario: Clone Existing Order
977
+ ```
978
+ Customer
979
+ 1. RowEvent Customer.customer_defaults()
980
+ 2. Derive Customer.UnpaidOrderCount as Count(<class 'database.models.Order'> Where <function declare_logic.<locals>.<lambda> at 0x10b9596c0>)
981
+ 3. Constraint Function: None
982
+ 4. Derive Customer.Balance as Sum(Order.AmountTotal Where <function declare_logic.<locals>.<lambda> at 0x10b83fd80>)
983
+ 5. Derive Customer.OrderCount as Count(<class 'database.models.Order'> Where None)
984
+ Order
985
+ 6. Derive Order.AmountTotal as Sum(OrderDetail.Amount Where None)
986
+ 7. RowEvent Order.clone_order()
987
+ 8. Derive Order.OrderDetailCount as Count(<class 'database.models.OrderDetail'> Where None)
988
+ 9. Derive Order.OrderDate as Formula (1): as_expression=lambda row: datetime.datetime.now())
989
+ 10. RowEvent Order.order_defaults()
990
+ OrderDetail
991
+ 11. Derive OrderDetail.Amount as Formula (1): as_expression=lambda row: row.UnitPrice * row.Qua [...]
992
+ 12. Derive OrderDetail.ShippedDate as Formula (2): row.Order.ShippedDate
993
+ 13. RowEvent OrderDetail.order_detail_defaults()
994
+ 14. Derive OrderDetail.UnitPrice as Copy(Product.UnitPrice)
995
+ ```
996
+ **Logic Log** in Scenario: Clone Existing Order
997
+ ```
998
+
999
+ Logic Phase: ROW LOGIC (session=0x10df9d8b0) (sqlalchemy before_flush) - 2024-07-12 14:57:09,533 - logic_logger - INF
1000
+ ..Order[None] {Insert - client} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: None, CloneFromOrder: 10643 row: 0x10dfbaff0 session: 0x10df9d8b0 ins_upd_dlt: ins - 2024-07-12 14:57:09,534 - logic_logger - INF
1001
+ ..Order[None] {server_defaults: OrderDetailCount -- skipped: Ready[BOOLEAN (not handled)] } Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: None, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: None, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: 10643 row: 0x10dfbaff0 session: 0x10df9d8b0 ins_upd_dlt: ins - 2024-07-12 14:57:09,534 - logic_logger - INF
1002
+ ..Order[None] {Formula OrderDate} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:09.541507, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: 10643 row: 0x10dfbaff0 session: 0x10df9d8b0 ins_upd_dlt: ins - 2024-07-12 14:57:09,541 - logic_logger - INF
1003
+ ....Customer[ALFKI] {Update - Adjusting Customer: UnpaidOrderCount, OrderCount} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: 2102.0000000000, CreditLimit: 2300.0000000000, OrderCount: [15-->] 16, UnpaidOrderCount: [10-->] 11, Client_id: 1 row: 0x10df9fe60 session: 0x10df9d8b0 ins_upd_dlt: upd - 2024-07-12 14:57:09,542 - logic_logger - INF
1004
+ ..Order[None] {Begin copy_children} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:09.541507, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: 0, Country: None, City: None, Ready: True, OrderDetailCount: 0, CloneFromOrder: 10643 row: 0x10dfbaff0 session: 0x10df9d8b0 ins_upd_dlt: ins - 2024-07-12 14:57:09,545 - logic_logger - INF
1005
+ ....OrderDetail[None] {Insert - Copy Children OrderDetailList} Id: None, OrderId: None, ProductId: [None-->] 28, UnitPrice: None, Quantity: [None-->] 15, Discount: [None-->] 0.25, Amount: None, ShippedDate: None row: 0x10df9da90 session: 0x10df9d8b0 ins_upd_dlt: ins - 2024-07-12 14:57:09,547 - logic_logger - INF
1006
+ ....OrderDetail[None] {copy_rules for role: Product - UnitPrice} Id: None, OrderId: None, ProductId: [None-->] 28, UnitPrice: [None-->] 45.6000000000, Quantity: [None-->] 15, Discount: [None-->] 0.25, Amount: None, ShippedDate: None row: 0x10df9da90 session: 0x10df9d8b0 ins_upd_dlt: ins - 2024-07-12 14:57:09,549 - logic_logger - INF
1007
+ ....OrderDetail[None] {Formula Amount} Id: None, OrderId: None, ProductId: [None-->] 28, UnitPrice: [None-->] 45.6000000000, Quantity: [None-->] 15, Discount: [None-->] 0.25, Amount: [None-->] 684.0000000000, ShippedDate: None row: 0x10df9da90 session: 0x10df9d8b0 ins_upd_dlt: ins - 2024-07-12 14:57:09,550 - logic_logger - INF
1008
+ ......Order[None] {Update - Adjusting Order: AmountTotal, OrderDetailCount} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:09.541507, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [0-->] 684.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [0-->] 1, CloneFromOrder: 10643 row: 0x10dfbaff0 session: 0x10df9d8b0 ins_upd_dlt: upd - 2024-07-12 14:57:09,551 - logic_logger - INF
1009
+ ......Order[None] {Prune Formula: OrderDate [[]]} Id: None, CustomerId: ALFKI, EmployeeId: 1, OrderDate: 2024-07-12 14:57:09.541507, RequiredDate: None, ShippedDate: None, ShipVia: None, Freight: 11, ShipName: None, ShipAddress: None, ShipCity: None, ShipRegion: None, ShipZip: None, ShipCountry: None, AmountTotal: [0-->] 684.0000000000, Country: None, City: None, Ready: True, OrderDetailCount: [0-->] 1, CloneFromOrder: 10643 row: 0x10dfbaff0 session: 0x10df9d8b0 ins_upd_dlt: upd - 2024-07-12 14:57:09,551 - logic_logger - INF
1010
+ ........Customer[ALFKI] {Update - Adjusting Customer: Balance} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 2786.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11, Client_id: 1 row: 0x10df9fe60 session: 0x10df9d8b0 ins_upd_dlt: upd - 2024-07-12 14:57:09,552 - logic_logger - INF
1011
+ ........Customer[ALFKI] {Constraint Failure: balance (2786.00) exceeds credit (2300.00)} Id: ALFKI, CompanyName: Alfreds Futterkiste, ContactName: Maria Anders, ContactTitle: Sales Representative, Address: Obere Str. 57A, City: Berlin, Region: Western Europe, PostalCode: 12209, Country: Germany, Phone: 030-0074321, Fax: 030-0076545, Balance: [2102.0000000000-->] 2786.0000000000, CreditLimit: 2300.0000000000, OrderCount: 16, UnpaidOrderCount: 11, Client_id: 1 row: 0x10df9fe60 session: 0x10df9d8b0 ins_upd_dlt: upd - 2024-07-12 14:57:09,553 - logic_logger - INF
1012
+
1013
+ ```
1014
+ </details>
1015
+
1016
+ &nbsp;
1017
+ &nbsp;
1018
+ ## Feature: Salary Change
1019
+
1020
+ &nbsp;
1021
+ &nbsp;
1022
+ ### Scenario: Audit Salary Change
1023
+ &emsp; Scenario: Audit Salary Change
1024
+ &emsp;&emsp; Given Employee 5 (Buchanan) - Salary 95k
1025
+ &emsp;&emsp; When Patch Salary to 200k
1026
+ &emsp;&emsp; Then Salary_audit row created
1027
+ <details markdown>
1028
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
1029
+
1030
+
1031
+ &nbsp;
1032
+ &nbsp;
1033
+
1034
+
1035
+ **Logic Doc** for scenario: Audit Salary Change
1036
+
1037
+ Logic Patterns:
1038
+
1039
+ * Auditing
1040
+
1041
+ Logic Design ("Cocktail Napkin Design")
1042
+
1043
+ * copy_row(copy_to=models.EmployeeAudit...)
1044
+
1045
+ Observe the logic log to see that it creates audit rows:
1046
+
1047
+ 1. **Discouraged:** you can implement auditing with events. But auditing is a common pattern, and this can lead to repetitive, tedious code
1048
+ 2. **Preferred:** approaches use [extensible rules](https://github.com/valhuber/LogicBank/wiki/Rule-Extensibility#generic-event-handlers).
1049
+
1050
+ Generic event handlers can also reduce redundant code, illustrated in the time/date stamping `handle_all` logic.
1051
+
1052
+ This is due to the `copy_row` rule. Contrast this to the *tedious* `audit_by_event` alternative:
1053
+
1054
+ <figure><img src="https://github.com/valhuber/ApiLogicServer/wiki/images/behave/salary_change.png?raw=true"></figure>
1055
+
1056
+ > **Key Takeaway:** use **extensible own rule types** to automate pattern you identify; events can result in tedious amounts of code.
1057
+
1058
+
1059
+
1060
+ &nbsp;
1061
+ &nbsp;
1062
+
1063
+
1064
+ **Rules Used** in Scenario: Audit Salary Change
1065
+ ```
1066
+
1067
+ ```
1068
+ **Logic Log** in Scenario: Audit Salary Change
1069
+ ```
1070
+
1071
+ Logic Phase: ROW LOGIC (session=0x10dfbbdd0) (sqlalchemy before_flush) - 2024-07-12 14:57:09,599 - logic_logger - INF
1072
+ ..Employee[5] {Update - client} Id: 5, LastName: Buchanan, FirstName: Steven, Title: Sales Manager, TitleOfCourtesy: Mr., BirthDate: 1987-03-04, HireDate: 2025-10-17, Address: 14 Garrett Hill, City: London, Region: British Isles, PostalCode: SW1 8JR, Country: UK, HomePhone: (71) 555-4848, Extension: 3453, Notes: Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976. Upon joining the company as a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent post in London. He was promoted to sales manager in March 1993. Mr. Buchanan has completed the courses 'Successful Telemarketing' and 'International Sales Management.' He is fluent in French., ReportsTo: 2, PhotoPath: http://localhost:5656/ui/images/Employee/buchanan.jpg, EmployeeType: Commissioned, Salary: [95000.0000000000-->] 200000, WorksForDepartmentId: 3, OnLoanDepartmentId: None, UnionId: None, Dues: None row: 0x10dfbb710 session: 0x10dfbbdd0 ins_upd_dlt: upd - 2024-07-12 14:57:09,600 - logic_logger - INF
1073
+ ..Employee[5] {BEGIN Copy to: EmployeeAudit} Id: 5, LastName: Buchanan, FirstName: Steven, Title: Sales Manager, TitleOfCourtesy: Mr., BirthDate: 1987-03-04, HireDate: 2025-10-17, Address: 14 Garrett Hill, City: London, Region: British Isles, PostalCode: SW1 8JR, Country: UK, HomePhone: (71) 555-4848, Extension: 3453, Notes: Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976. Upon joining the company as a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent post in London. He was promoted to sales manager in March 1993. Mr. Buchanan has completed the courses 'Successful Telemarketing' and 'International Sales Management.' He is fluent in French., ReportsTo: 2, PhotoPath: http://localhost:5656/ui/images/Employee/buchanan.jpg, EmployeeType: Commissioned, Salary: [95000.0000000000-->] 200000, WorksForDepartmentId: 3, OnLoanDepartmentId: None, UnionId: None, Dues: None row: 0x10dfbb710 session: 0x10dfbbdd0 ins_upd_dlt: upd - 2024-07-12 14:57:09,604 - logic_logger - INF
1074
+ ....EmployeeAudit[None] {Insert - Copy EmployeeAudit} Id: None, Title: Sales Manager, Salary: 200000, LastName: Buchanan, FirstName: Steven, EmployeeId: None, CreatedOn: None, UpdatedOn: None, CreatedBy: None, UpdatedBy: None row: 0x10dfba1b0 session: 0x10dfbbdd0 ins_upd_dlt: ins - 2024-07-12 14:57:09,605 - logic_logger - INF
1075
+ ....EmployeeAudit[None] {early_row_event_all_classes - handle_all did stamping} Id: None, Title: Sales Manager, Salary: 200000, LastName: Buchanan, FirstName: Steven, EmployeeId: None, CreatedOn: 2024-07-12 14:57:09.606065, UpdatedOn: None, CreatedBy: aneu, UpdatedBy: None row: 0x10dfba1b0 session: 0x10dfbbdd0 ins_upd_dlt: ins - 2024-07-12 14:57:09,606 - logic_logger - INF
1076
+ Logic Phase: COMMIT LOGIC (session=0x10dfbbdd0) - 2024-07-12 14:57:09,607 - logic_logger - INF
1077
+ Logic Phase: AFTER_FLUSH LOGIC (session=0x10dfbbdd0) - 2024-07-12 14:57:09,612 - logic_logger - INF
1078
+
1079
+ ```
1080
+ </details>
1081
+
1082
+ &nbsp;
1083
+ &nbsp;
1084
+ ### Scenario: Manage ProperSalary
1085
+ &emsp; Scenario: Manage ProperSalary
1086
+ &emsp;&emsp; Given Employee 5 (Buchanan) - Salary 95k
1087
+ &emsp;&emsp; When Retrieve Employee Row
1088
+ &emsp;&emsp; Then Verify Contains ProperSalary
1089
+ <details markdown>
1090
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
1091
+
1092
+
1093
+ &nbsp;
1094
+ &nbsp;
1095
+
1096
+
1097
+ **Logic Doc** for scenario: Manage ProperSalary
1098
+
1099
+ Observe the use of `old_row
1100
+ `
1101
+ > **Key Takeaway:** State Transition Logic enabled per `old_row`
1102
+
1103
+
1104
+
1105
+ &nbsp;
1106
+ &nbsp;
1107
+
1108
+
1109
+ **Rules Used** in Scenario: Manage ProperSalary
1110
+ ```
1111
+ ```
1112
+ **Logic Log** in Scenario: Manage ProperSalary
1113
+ ```
1114
+ ```
1115
+ </details>
1116
+
1117
+ &nbsp;
1118
+ &nbsp;
1119
+ ### Scenario: Raise Must be Meaningful
1120
+ &emsp; Scenario: Raise Must be Meaningful
1121
+ &emsp;&emsp; Given Employee 5 (Buchanan) - Salary 95k
1122
+ &emsp;&emsp; When Patch Salary to 96k
1123
+ &emsp;&emsp; Then Reject - Raise too small
1124
+ <details markdown>
1125
+ <summary>Tests - and their logic - are transparent.. click to see Logic</summary>
1126
+
1127
+
1128
+ &nbsp;
1129
+ &nbsp;
1130
+
1131
+
1132
+ **Logic Doc** for scenario: Raise Must be Meaningful
1133
+
1134
+ Logic Patterns:
1135
+
1136
+ * State Transition Logic
1137
+
1138
+ Logic Design ("Cocktail Napkin Design")
1139
+
1140
+ * Rule.constraint(validate=Employee, calling=raise_over_20_percent...)
1141
+
1142
+ Observe the use of `old_row
1143
+ `
1144
+ > **Key Takeaway:** State Transition Logic enabled per `old_row`
1145
+
1146
+
1147
+
1148
+ &nbsp;
1149
+ &nbsp;
1150
+
1151
+
1152
+ **Rules Used** in Scenario: Raise Must be Meaningful
1153
+ ```
1154
+ Employee
1155
+ 1. Constraint Function: <function declare_logic.<locals>.raise_over_20_percent at 0x10b959940>
1156
+ ```
1157
+ **Logic Log** in Scenario: Raise Must be Meaningful
1158
+ ```
1159
+
1160
+ Logic Phase: ROW LOGIC (session=0x10dfd4b60) (sqlalchemy before_flush) - 2024-07-12 14:57:09,907 - logic_logger - INF
1161
+ ..Employee[5] {Update - client} Id: 5, LastName: Buchanan, FirstName: Steven, Title: Sales Manager, TitleOfCourtesy: Mr., BirthDate: 1987-03-04, HireDate: 2025-10-17, Address: 14 Garrett Hill, City: London, Region: British Isles, PostalCode: SW1 8JR, Country: UK, HomePhone: (71) 555-4848, Extension: 3453, Notes: Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976. Upon joining the company as a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent post in London. He was promoted to sales manager in March 1993. Mr. Buchanan has completed the courses 'Successful Telemarketing' and 'International Sales Management.' He is fluent in French., ReportsTo: 2, PhotoPath: http://localhost:5656/ui/images/Employee/buchanan.jpg, EmployeeType: Commissioned, Salary: [95000.0000000000-->] 96000, WorksForDepartmentId: 3, OnLoanDepartmentId: None, UnionId: None, Dues: None row: 0x10dd75790 session: 0x10dfd4b60 ins_upd_dlt: upd - 2024-07-12 14:57:09,908 - logic_logger - INF
1162
+ ..Employee[5] {Constraint Failure: Buchanan needs a more meaningful raise} Id: 5, LastName: Buchanan, FirstName: Steven, Title: Sales Manager, TitleOfCourtesy: Mr., BirthDate: 1987-03-04, HireDate: 2025-10-17, Address: 14 Garrett Hill, City: London, Region: British Isles, PostalCode: SW1 8JR, Country: UK, HomePhone: (71) 555-4848, Extension: 3453, Notes: Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976. Upon joining the company as a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent post in London. He was promoted to sales manager in March 1993. Mr. Buchanan has completed the courses 'Successful Telemarketing' and 'International Sales Management.' He is fluent in French., ReportsTo: 2, PhotoPath: http://localhost:5656/ui/images/Employee/buchanan.jpg, EmployeeType: Commissioned, Salary: [95000.0000000000-->] 96000, WorksForDepartmentId: 3, OnLoanDepartmentId: None, UnionId: None, Dues: None row: 0x10dd75790 session: 0x10dfd4b60 ins_upd_dlt: upd - 2024-07-12 14:57:09,909 - logic_logger - INF
1163
+
1164
+ ```
1165
+ </details>
1166
+
1167
+ &nbsp;
1168
+ &nbsp;
1169
+ ## Feature: Tests Successful
1170
+
1171
+ &nbsp;
1172
+ &nbsp;
1173
+ ### Scenario: Run Tests
1174
+ &emsp; Scenario: Run Tests
1175
+ &emsp;&emsp; Given Database and Set of Tests
1176
+ &emsp;&emsp; When Run Configuration: Behave Tests
1177
+ &emsp;&emsp; Then No Errors
1178
+
1179
+ &nbsp;&nbsp;
1180
+ Completed at July 12, 2024 14:57:0