ApiLogicServer 15.0.47__py3-none-any.whl → 15.0.54__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.
- api_logic_server_cli/api_logic_server.py +18 -5
- api_logic_server_cli/api_logic_server_info.yaml +3 -3
- api_logic_server_cli/cli.py +20 -16
- api_logic_server_cli/create_from_model/api_logic_server_utils.py +10 -1
- api_logic_server_cli/manager.py +24 -13
- api_logic_server_cli/prototypes/base/.github/.copilot-instructions.md +39 -3
- api_logic_server_cli/prototypes/base/config/config.py +15 -0
- api_logic_server_cli/prototypes/base/database/alembic/alembic_run.py +98 -0
- api_logic_server_cli/prototypes/base/database/alembic/readme_alembic.md +36 -0
- api_logic_server_cli/prototypes/base/docs/training/admin_app_1_context.prompt.md +40 -0
- api_logic_server_cli/prototypes/base/integration/mcp/mcp_client_executor.py +2 -2
- api_logic_server_cli/prototypes/base/venv_setup/requirements-no-cli.txt +5 -4
- api_logic_server_cli/prototypes/basic_demo/_config.yml +8 -0
- api_logic_server_cli/prototypes/basic_demo/_layouts/redirect.html +15 -0
- api_logic_server_cli/prototypes/basic_demo/docs/system-creation-vibe.md +161 -0
- api_logic_server_cli/prototypes/basic_demo/logic/declarative-vs-procedural-comparison.html +110 -0
- api_logic_server_cli/prototypes/basic_demo/logic/procedural/declarative-vs-procedural-comparison.md +295 -0
- api_logic_server_cli/prototypes/manager/.vscode/settings.json +1 -1
- api_logic_server_cli/prototypes/manager/{run_sample.sh → samples/docker_samples/run_sample_docker.sh} +4 -4
- api_logic_server_cli/prototypes/manager/samples/docker_samples/run_web_genai.sh +5 -0
- api_logic_server_cli/prototypes/manager/samples/prompts/add_email.prompt +8 -0
- api_logic_server_cli/prototypes/manager/samples/prompts/elections.prompt +3 -0
- api_logic_server_cli/prototypes/manager/samples/prompts/emp_dept.prompt +4 -0
- api_logic_server_cli/prototypes/manager/samples/prompts/genai_demo.prompt +13 -0
- api_logic_server_cli/prototypes/manager/samples/readme_samples.md +25 -11
- api_logic_server_cli/prototypes/manager/system/app_model_editor/venv_setup/requirements-no-cli.txt +5 -4
- api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-Resource-Learning-Prompt.md +1 -1
- api_logic_server_cli/prototypes/manager/system/genai/app_templates/react-admin-template/package.json +1 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/venv_setup/requirements-no-cli.txt +5 -4
- api_logic_server_cli/prototypes/manager/system/install-ApiLogicServer-dev/install-ApiLogicServer-dev.ps1 +7 -3
- api_logic_server_cli/prototypes/ont_app/ontimize_seed/package.json +2 -2
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/codegen.py +4 -2
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/main.py +25 -5
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen_wrapper.py +30 -10
- {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.54.dist-info}/METADATA +6 -5
- {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.54.dist-info}/RECORD +40 -111
- api_logic_server_cli/create_from_model/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/api_expose_api_models_creator.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/api_logic_server_utils.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/create_db_from_model.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/dbml.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/meta_model.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/model_creation_services.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ont_build.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ont_create.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/ui_admin_creator.cpython-312.pyc +0 -0
- api_logic_server_cli/create_from_model/__pycache__/uri_info.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/base/.devcontainer-option/.copilot-instructions.md +0 -178
- api_logic_server_cli/prototypes/base/database/alembic/readme.md +0 -18
- api_logic_server_cli/prototypes/base/database/system/SAFRSBaseX.pyZ +0 -73
- api_logic_server_cli/prototypes/basic_demo/customizations/database/system/SAFRSBaseX.py +0 -139
- api_logic_server_cli/prototypes/manager/run_web_genai.sh +0 -6
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/__pycache__/api_logic_server_run.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/customize_api.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/expose_api_models.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/__pycache__/json_encoder.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/auto_discovery.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/new_service.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/newer_service.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/ontimize_api.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/api_discovery/__pycache__/system.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/api_utils.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/custom_endpoint.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/expression_parser.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/gen_csv_report.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/__pycache__/gen_pdf_report.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/api/system/opt_locking/__pycache__/opt_locking.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/activate_logicbank.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/config.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/config/__pycache__/server_setup.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/bind_dbs.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/customize_models.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/__pycache__/models.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/alembic/__pycache__/env.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/database_discovery/__pycache__/authentication_models.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/database_discovery/__pycache__/auto_discovery.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/db_debug/__pycache__/db_debug.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/system/__pycache__/SAFRSBaseX.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/test_data/__pycache__/alp_init.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/test_data/__pycache__/response2code.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/database/test_data/__pycache__/test_data_preamble.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/devops/keycloak/unused/__pycache__/auth_provider.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/devops/python-anywhere/__pycache__/python_anywhere_wsgi.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/kafka/__pycache__/kafka_consumer.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/kafka/__pycache__/kafka_producer.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/n8n/__pycache__/n8n_producer.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/system/__pycache__/FlaskKafka.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/integration/system/__pycache__/RowDictMapper.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/logic/__pycache__/declare_logic.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/logic/__pycache__/load_verify_rules.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/logic/logic_discovery/__pycache__/auto_discovery.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/__pycache__/declare_security.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/__pycache__/abstract_authentication_provider.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/keycloak/__pycache__/auth_provider.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/memory/__pycache__/auth_provider.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/memory/__pycache__/auth_provider_no_swagger.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/authentication_provider/sql/__pycache__/auth_provider.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/system/__pycache__/authentication.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/security/system/__pycache__/authorization.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/__pycache__/behave_logic_report.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/__pycache__/behave_run.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/features/steps/__pycache__/about.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/api_logic_server_behave/features/steps/__pycache__/test_utils.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/test/basic/__pycache__/server_test.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/ui/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/ui/admin/__pycache__/admin_loader.cpython-312.pyc +0 -0
- api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/genai_demo_docs_logic/venv_setup/__pycache__/py.cpython-312.pyc +0 -0
- api_logic_server_cli/sqlacodegen_wrapper/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/sqlacodegen_wrapper/__pycache__/sqlacodegen_wrapper.cpython-312.pyc +0 -0
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/__pycache__/__init__.cpython-312.pyc +0 -0
- api_logic_server_cli/sqlacodegen_wrapper/sqlacodegen/sqlacodegen/__pycache__/codegen.cpython-312.pyc +0 -0
- {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.54.dist-info}/WHEEL +0 -0
- {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.54.dist-info}/entry_points.txt +0 -0
- {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.54.dist-info}/licenses/LICENSE +0 -0
- {apilogicserver-15.0.47.dist-info → apilogicserver-15.0.54.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Vibe MCP / Microservice
|
|
3
|
+
version: 0.23 from docsite 7/11/2025
|
|
4
|
+
---
|
|
5
|
+
<style>
|
|
6
|
+
.md-typeset h1,
|
|
7
|
+
.md-content__button {
|
|
8
|
+
display: none;
|
|
9
|
+
}
|
|
10
|
+
</style>
|
|
11
|
+
|
|
12
|
+
<< Under Construction >>
|
|
13
|
+
|
|
14
|
+
# Vibe an MCP Microservice
|
|
15
|
+
|
|
16
|
+
See the Readme for detailed walk through.
|
|
17
|
+
|
|
18
|
+
Scenario: we have an existing database (customers, order, items and product), and we require:
|
|
19
|
+
|
|
20
|
+
* An MCP-enabled API, for integration
|
|
21
|
+
* MCP client support to send emails for overdue orders
|
|
22
|
+
* Business Logic to check credit by rolling up Items and Orders.
|
|
23
|
+
|
|
24
|
+
This is a record of how we created the system using CoPilot Chat (*Vibe*).
|
|
25
|
+
|
|
26
|
+
<br>
|
|
27
|
+
|
|
28
|
+
## Initialize CoPilot
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Please find and read `.github/.copilot-instructions.md`.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
<br>
|
|
35
|
+
|
|
36
|
+
## Create the System
|
|
37
|
+
|
|
38
|
+
```bash title="Create a project from an existing database"
|
|
39
|
+
# in the GenAI-Logic Manager:
|
|
40
|
+
Create a database project from samples/dbs/basic_demo.sqlite
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
<br>
|
|
44
|
+
|
|
45
|
+
## Verify the API and Admin App
|
|
46
|
+
|
|
47
|
+
The project should automatically open a new window in VSCode. Again, open CoPilot and bootstrap it with: <br>
|
|
48
|
+
|
|
49
|
+
```bash title="Initialize CoPilot"
|
|
50
|
+
Please find and read `.github/.copilot-instructions.md`**.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Verify it as follows:
|
|
54
|
+
|
|
55
|
+
* **Click F5** to start server, open app at http://localhost:5656/
|
|
56
|
+
* **Verify API:** filtering, sorting, pagination, optimistic locking and related data access - see the Swagger
|
|
57
|
+
* **Verify Admin App:** multi-page, multi-table, automatic joins, lookups, cascade add - collaboration-ready
|
|
58
|
+
|
|
59
|
+
<br>
|
|
60
|
+
|
|
61
|
+
## Create a Custom React App
|
|
62
|
+
|
|
63
|
+
**Create Start App**
|
|
64
|
+
```bash title="Create a custom react app"
|
|
65
|
+
Create a react app.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
<br>
|
|
69
|
+
|
|
70
|
+
**Customize - add cards**
|
|
71
|
+
```txt title='Customize using Natural Language'
|
|
72
|
+
In the ui/react app, update the Product list to provide users an option to see results in a list,
|
|
73
|
+
or in cards.
|
|
74
|
+
```
|
|
75
|
+
<br>
|
|
76
|
+
|
|
77
|
+
todo - diagram
|
|
78
|
+
|
|
79
|
+
**Test: verify option for cards on `http://localhost:3000`**
|
|
80
|
+
|
|
81
|
+
<br>
|
|
82
|
+
|
|
83
|
+
## MCP Client - Overdue Orders
|
|
84
|
+
|
|
85
|
+
**Stop the Server**
|
|
86
|
+
|
|
87
|
+
<br>
|
|
88
|
+
|
|
89
|
+
**Create MCP Executor: process request - invokes the LLM to obtain a series of API calls to run, and runs them**
|
|
90
|
+
``` bash title="Create an MCP Client Executor"
|
|
91
|
+
Create the mcp client executor
|
|
92
|
+
```
|
|
93
|
+
<br>
|
|
94
|
+
|
|
95
|
+
**Add a Table to Track Sent Emails**
|
|
96
|
+
``` bash title="Add a Table to Track Sent Emails"
|
|
97
|
+
Create a table SysEmail in `database/db.sqlite` as a child of customer,
|
|
98
|
+
with columns id, message, subject, customer_id and CreatedOn.
|
|
99
|
+
```
|
|
100
|
+
Follow the suggestions to update the admin app.
|
|
101
|
+
|
|
102
|
+
<br>
|
|
103
|
+
|
|
104
|
+
**Create the email service stub using SysEmail as a Request Table**
|
|
105
|
+
``` bash title="Create the email service using SysEmail as a Request Table"
|
|
106
|
+
Add an after_flush event on SysEmail to produce a log message "email sent",
|
|
107
|
+
unless the customer has opted out.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
<br>
|
|
111
|
+
|
|
112
|
+
**Business Logic to Honor Email Opt-out**
|
|
113
|
+
```bash title="Business Logic to Honor Email Opt-out"
|
|
114
|
+
Add an after_flush event on SysEmail to produce a log message "email sent",
|
|
115
|
+
unless the customer has opted out.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
<br>
|
|
119
|
+
|
|
120
|
+
**Test: restart the server/admin app - Click SysMCP >> Create New, and enter:**
|
|
121
|
+
```text title="Test the MCP Client: Click SysMCP >> Create New, and enter"
|
|
122
|
+
List the orders date_shipped is null and CreatedOn before 2023-07-14,
|
|
123
|
+
and send a discount email (subject: 'Discount Offer') to the customer for each one.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
<br>
|
|
127
|
+
todo - diagram
|
|
128
|
+
|
|
129
|
+
**Use the Admin App to Verify the first customer has an email**
|
|
130
|
+
|
|
131
|
+
<br>
|
|
132
|
+
|
|
133
|
+
## Check Credit Business Logic
|
|
134
|
+
|
|
135
|
+
**1. Stop the Server** (Red Stop button, or Shift-F5 -- see Appendix)
|
|
136
|
+
|
|
137
|
+
**2. Add Business Logic**
|
|
138
|
+
|
|
139
|
+
```bash title="Check Credit Logic (instead of 220 lines of code)"
|
|
140
|
+
Use case: Check Credit
|
|
141
|
+
1. The Customer's balance is less than the credit limit
|
|
142
|
+
2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
|
|
143
|
+
3. The Order's amount_total is the sum of the Item amount
|
|
144
|
+
4. The Item amount is the quantity * unit_price
|
|
145
|
+
5. The Item unit_price is copied from the Product unit_price
|
|
146
|
+
|
|
147
|
+
Use case: App Integration
|
|
148
|
+
1. Send the Order to Kafka topic 'order_shipping' if the date_shipped is not None.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
To test the logic:
|
|
152
|
+
|
|
153
|
+
**1. Use the Admin App to access the first order for `Customer Alice`**
|
|
154
|
+
|
|
155
|
+
**2. Edit its first item to a very high quantity**
|
|
156
|
+
|
|
157
|
+
todo - diagram
|
|
158
|
+
|
|
159
|
+
The update is properly rejected because it exceeds the credit limit. Observe the rules firing in the console log - see Logic In Action, below.
|
|
160
|
+
|
|
161
|
+
<br>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page Moved - Declarative vs Procedural Comparison</title>
|
|
6
|
+
<meta http-equiv="refresh" content="3; url=https://apilogicserver.github.io/basic_demo/logic/procedural/declarative-vs-procedural-comparison.html">
|
|
7
|
+
<link rel="canonical" href="https://apilogicserver.github.io/basic_demo/logic/procedural/declarative-vs-procedural-comparison.html">
|
|
8
|
+
<style>
|
|
9
|
+
body {
|
|
10
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
|
|
11
|
+
max-width: 600px;
|
|
12
|
+
margin: 50px auto;
|
|
13
|
+
padding: 20px;
|
|
14
|
+
line-height: 1.6;
|
|
15
|
+
}
|
|
16
|
+
.redirect-box {
|
|
17
|
+
border: 2px solid #007acc;
|
|
18
|
+
padding: 30px;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
|
21
|
+
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
22
|
+
}
|
|
23
|
+
.countdown {
|
|
24
|
+
font-weight: bold;
|
|
25
|
+
color: #007acc;
|
|
26
|
+
font-size: 1.2em;
|
|
27
|
+
}
|
|
28
|
+
.manual-link {
|
|
29
|
+
display: inline-block;
|
|
30
|
+
background: #007acc;
|
|
31
|
+
color: white;
|
|
32
|
+
padding: 12px 24px;
|
|
33
|
+
text-decoration: none;
|
|
34
|
+
border-radius: 5px;
|
|
35
|
+
margin: 10px 0;
|
|
36
|
+
font-weight: bold;
|
|
37
|
+
}
|
|
38
|
+
.manual-link:hover {
|
|
39
|
+
background: #005c99;
|
|
40
|
+
}
|
|
41
|
+
h1 { color: #333; margin-top: 0; }
|
|
42
|
+
.progress-bar {
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 6px;
|
|
45
|
+
background: #ddd;
|
|
46
|
+
border-radius: 3px;
|
|
47
|
+
margin: 15px 0;
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
}
|
|
50
|
+
.progress-fill {
|
|
51
|
+
height: 100%;
|
|
52
|
+
background: #007acc;
|
|
53
|
+
width: 100%;
|
|
54
|
+
transition: width 1s linear;
|
|
55
|
+
}
|
|
56
|
+
</style>
|
|
57
|
+
<script>
|
|
58
|
+
let seconds = 3;
|
|
59
|
+
function redirect() {
|
|
60
|
+
window.location.href = "https://apilogicserver.github.io/basic_demo/logic/procedural/declarative-vs-procedural-comparison.html";
|
|
61
|
+
}
|
|
62
|
+
function updateCountdown() {
|
|
63
|
+
const countdownElement = document.getElementById('countdown');
|
|
64
|
+
const progressElement = document.getElementById('progress-fill');
|
|
65
|
+
|
|
66
|
+
if (countdownElement) {
|
|
67
|
+
countdownElement.textContent = seconds;
|
|
68
|
+
}
|
|
69
|
+
if (progressElement) {
|
|
70
|
+
progressElement.style.width = ((3-seconds)/3 * 100) + '%';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (seconds <= 0) {
|
|
74
|
+
redirect();
|
|
75
|
+
} else {
|
|
76
|
+
seconds--;
|
|
77
|
+
setTimeout(updateCountdown, 1000);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
window.onload = function() {
|
|
81
|
+
updateCountdown();
|
|
82
|
+
// Fallback redirect in case JavaScript fails
|
|
83
|
+
setTimeout(redirect, 3100);
|
|
84
|
+
}
|
|
85
|
+
</script>
|
|
86
|
+
</head>
|
|
87
|
+
<body>
|
|
88
|
+
<div class="redirect-box">
|
|
89
|
+
<h1>📄 Page Moved</h1>
|
|
90
|
+
<p>The <strong>Declarative vs Procedural Logic Comparison</strong> has moved to a new location.</p>
|
|
91
|
+
|
|
92
|
+
<div class="progress-bar">
|
|
93
|
+
<div id="progress-fill" class="progress-fill" style="width: 0%;"></div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<p>Redirecting automatically in <span id="countdown" class="countdown">3</span> seconds...</p>
|
|
97
|
+
|
|
98
|
+
<p><strong>If you are not redirected automatically:</strong></p>
|
|
99
|
+
<a href="https://apilogicserver.github.io/basic_demo/logic/procedural/declarative-vs-procedural-comparison.html" class="manual-link">
|
|
100
|
+
👉 Go to New Location
|
|
101
|
+
</a>
|
|
102
|
+
|
|
103
|
+
<hr style="margin: 25px 0; border: none; border-top: 1px solid #ddd;">
|
|
104
|
+
<p><small>
|
|
105
|
+
<strong>New URL:</strong><br>
|
|
106
|
+
<code>https://apilogicserver.github.io/basic_demo/logic/procedural/declarative-vs-procedural-comparison.html</code>
|
|
107
|
+
</small></p>
|
|
108
|
+
</div>
|
|
109
|
+
</body>
|
|
110
|
+
</html>
|
api_logic_server_cli/prototypes/basic_demo/logic/procedural/declarative-vs-procedural-comparison.md
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Declarative vs. Procedural Business Logic: A Comprehensive Comparison
|
|
2
|
+
|
|
3
|
+
<br>
|
|
4
|
+
|
|
5
|
+
## Foreword
|
|
6
|
+
|
|
7
|
+
This document presents a real-world A/B comparison of two approaches to implementing the **same business logic requirements.** We asked AI to generate both a **procedural** implementation using conventional code, and a **declarative** implementation using the LogicBank rules engine.
|
|
8
|
+
|
|
9
|
+
This experiment highlights fundamental differences between the two approaches, and what they mean for building reliable, maintainable systems. It's important, because business logic typically represents *nearly half the effort* in database projects.
|
|
10
|
+
|
|
11
|
+
When asked to produce logic, AI (by itself) defaults to procedural code — because that’s all it knows. This study uncovered two critical problems with that approach:
|
|
12
|
+
1. **Quality:** The AI-generated procedural code contained subtle but serious bugs, even for just five rules—falling far short of basic reliability.
|
|
13
|
+
2. **Maintainability:** The procedural implementation exploded to over 200 lines — more than 40X the size of its declarative equivalent — creating “Franken-Code” that is brittle, opaque, and costly to maintain.
|
|
14
|
+
|
|
15
|
+
By contrast, the declarative approach was error free, and 5 Python statements.
|
|
16
|
+
|
|
17
|
+
The answer isn’t to reject AI. Its speed and simplicity are transformative. The key is to **teach AI about declarative rules** so it can produce concise, expressive rules instead of hundreds of lines of brittle procedural code. These rules are then executed by an **automated runtime engine** (like LogicBank), ensuring correctness, scalability, and maintainability — while preserving the velocity that makes AI so valuable.
|
|
18
|
+
|
|
19
|
+
By combining AI with declarative automation, GenAI-Logic delivers the best of both worlds: rapid development and enterprise-grade governance.
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
<br>
|
|
24
|
+
|
|
25
|
+
### Deeper Dive
|
|
26
|
+
|
|
27
|
+
[GenAI-Logic](https://www.genai-logic.com) is free and open source, so you can install it to explore declarative logic - [click here](https://apilogicserver.github.io/Docs/Install-Express/). This project is available in github - [click here](https://github.com/ApiLogicServer/basic_demo/blob/main/logic/declarative-vs-procedural-comparison.md).
|
|
28
|
+
|
|
29
|
+
<br>
|
|
30
|
+
|
|
31
|
+
### How this Document Was Created
|
|
32
|
+
|
|
33
|
+
We created this document from the following scenario:
|
|
34
|
+
|
|
35
|
+
1. Built the `basic_demo` project [as described here](https://apilogicserver.github.io/Docs/Sample-Basic-Demo/).
|
|
36
|
+
2. We asked CoPilot to **rebuild the logic *using a procedural approach*** - that is, without the LogicBank rule engine (part of GenAI-Logic).
|
|
37
|
+
* Resulting Procedural Logic: `logic/procedural_logic.py`
|
|
38
|
+
* Declarative logic: `logic/declare_logic.py` (*with LogicBank,* [below](#business-requirements))
|
|
39
|
+
3. We asked Copilot: **what would happen if the orders' customer-id were changed?**
|
|
40
|
+
* Copilot accepted this as a serious error, and made the bug fix.
|
|
41
|
+
4. We then asked Copilot: *what if the items' product-id were changed?*
|
|
42
|
+
* Copilot became agitated at finding yet another serious bug...
|
|
43
|
+
* It fixed it, and - ***unprompted* - provided the following analysis** of *Declarative vs Procedural Business Logic.*
|
|
44
|
+
|
|
45
|
+
<br>
|
|
46
|
+
|
|
47
|
+
> Here's the Copilot analysis, in its own words.
|
|
48
|
+
|
|
49
|
+
<br>
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## TL;DR
|
|
53
|
+
|
|
54
|
+
**LogicBank declarative rules provide a 44X reduction in code complexity** compared to traditional procedural implementations:
|
|
55
|
+
|
|
56
|
+
| Aspect | LogicBank Declarative | Procedural Code |
|
|
57
|
+
|--------|----------------------|-----------------|
|
|
58
|
+
| **Lines of Code** | 5 lines | 220+ lines |
|
|
59
|
+
| **Complexity** | Simple rule declarations | Complex event handling |
|
|
60
|
+
| **Maintenance** | Self-documenting business logic | Implementation details obscure logic |
|
|
61
|
+
| **Performance** | Built-in optimization & pruning | Multiple queries, N+1 problems |
|
|
62
|
+
| **Error Handling** | Automatic cascading | Manual event management |
|
|
63
|
+
| **Business Alignment** | Rules match requirements | Code doesn't reflect business intent |
|
|
64
|
+
|
|
65
|
+
**Bottom Line**: Declarative business logic eliminates complexity while providing better performance, maintainability, and business alignment.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Overview
|
|
70
|
+
|
|
71
|
+
This document compares two approaches to implementing business logic in enterprise applications:
|
|
72
|
+
- **Declarative Logic** using LogicBank rules
|
|
73
|
+
- **Traditional Procedural Logic** using event handlers
|
|
74
|
+
|
|
75
|
+
The comparison is based on implementing the same business requirements using both approaches in an order management system.
|
|
76
|
+
|
|
77
|
+
## Business Requirements
|
|
78
|
+
|
|
79
|
+
Our test case implements these common business rules:
|
|
80
|
+
|
|
81
|
+
1. **Copy unit_price from Product to Item**
|
|
82
|
+
2. **Calculate Item amount = quantity × unit_price**
|
|
83
|
+
3. **Calculate Order total = sum of Item amounts**
|
|
84
|
+
4. **Update Customer balance = sum of unshipped Order totals**
|
|
85
|
+
5. **Ensure Customer balance ≤ credit_limit**
|
|
86
|
+
6. **Validate Item quantity > 0**
|
|
87
|
+
7. **Log order events**
|
|
88
|
+
|
|
89
|
+
## Code Comparison
|
|
90
|
+
|
|
91
|
+
### LogicBank Declarative Rules (~5 lines)
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
# Business logic expressed as simple, readable rules
|
|
95
|
+
def declare_logic():
|
|
96
|
+
# Rule 1: Copy unit price from product to item
|
|
97
|
+
Rule.copy(derive=Item.unit_price, from_parent=Product.unit_price)
|
|
98
|
+
|
|
99
|
+
# Rule 2: Calculate item amount
|
|
100
|
+
Rule.formula(derive=Item.amount, as_expression=lambda row: row.quantity * row.unit_price)
|
|
101
|
+
|
|
102
|
+
# Rule 3: Calculate order total
|
|
103
|
+
Rule.sum(derive=Order.amount_total, as_sum_of=Item.amount)
|
|
104
|
+
|
|
105
|
+
# Rule 4: Update customer balance
|
|
106
|
+
Rule.sum(derive=Customer.balance, as_sum_of=Order.amount_total,
|
|
107
|
+
where=lambda row: row.date_shipped is None)
|
|
108
|
+
|
|
109
|
+
# Rule 5: Validate credit limit
|
|
110
|
+
Rule.constraint(validate=Customer,
|
|
111
|
+
as_condition=lambda row: row.balance <= row.credit_limit,
|
|
112
|
+
error_msg="Customer balance exceeds credit limit")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Procedural Implementation (~220 lines)
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
# Complex event handling with manual cascading
|
|
119
|
+
def handle_item_update(mapper, connection, target: models.Item):
|
|
120
|
+
session = Session.object_session(target)
|
|
121
|
+
|
|
122
|
+
# Get OLD version to detect changes
|
|
123
|
+
old_item = session.query(models.Item).get(target.id)
|
|
124
|
+
|
|
125
|
+
# Validate quantity
|
|
126
|
+
ProceduralBusinessLogic.validate_item_quantity(target)
|
|
127
|
+
|
|
128
|
+
# Handle product changes (CRITICAL BUG FIX)
|
|
129
|
+
if old_item and old_item.product_id != target.product_id:
|
|
130
|
+
ProceduralBusinessLogic.copy_unit_price_from_product(target, session)
|
|
131
|
+
|
|
132
|
+
# Recalculate item amount
|
|
133
|
+
ProceduralBusinessLogic.calculate_item_amount(target)
|
|
134
|
+
|
|
135
|
+
# Handle order changes (another potential bug!)
|
|
136
|
+
if old_item and old_item.order_id != target.order_id:
|
|
137
|
+
# Update OLD order total
|
|
138
|
+
old_order = session.query(models.Order).get(old_item.order_id)
|
|
139
|
+
if old_order:
|
|
140
|
+
ProceduralBusinessLogic.calculate_order_total(old_order, session)
|
|
141
|
+
# Update old customer balance
|
|
142
|
+
old_customer = session.query(models.Customer).get(old_order.customer_id)
|
|
143
|
+
if old_customer:
|
|
144
|
+
ProceduralBusinessLogic.update_customer_balance(old_customer, session)
|
|
145
|
+
ProceduralBusinessLogic.validate_credit_limit(old_customer)
|
|
146
|
+
|
|
147
|
+
# Update NEW order total
|
|
148
|
+
if target.order_id:
|
|
149
|
+
order = session.query(models.Order).get(target.order_id)
|
|
150
|
+
if order:
|
|
151
|
+
ProceduralBusinessLogic.calculate_order_total(order, session)
|
|
152
|
+
customer = session.query(models.Customer).get(order.customer_id)
|
|
153
|
+
if customer:
|
|
154
|
+
ProceduralBusinessLogic.update_customer_balance(customer, session)
|
|
155
|
+
ProceduralBusinessLogic.validate_credit_limit(customer)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Detailed Comparison
|
|
159
|
+
|
|
160
|
+
### 1. **Code Volume**
|
|
161
|
+
| Aspect | LogicBank | Procedural |
|
|
162
|
+
|--------|-----------|------------|
|
|
163
|
+
| Lines of Code | ~5 | ~220 |
|
|
164
|
+
| Complexity | Simple rule declarations | Complex event handling |
|
|
165
|
+
| Ratio | **44X MORE CONCISE** | Baseline |
|
|
166
|
+
|
|
167
|
+
### 2. **Maintainability**
|
|
168
|
+
|
|
169
|
+
**LogicBank:**
|
|
170
|
+
- ✅ Rules are self-documenting
|
|
171
|
+
- ✅ Business logic is immediately recognizable
|
|
172
|
+
- ✅ Changes are localized to specific rules
|
|
173
|
+
- ✅ Easy to add new rules without affecting existing ones
|
|
174
|
+
|
|
175
|
+
**Procedural:**
|
|
176
|
+
- ❌ Business logic buried in implementation details
|
|
177
|
+
- ❌ Hard to understand the complete business flow
|
|
178
|
+
- ❌ Changes require understanding entire event chain
|
|
179
|
+
- ❌ Risk of breaking existing functionality
|
|
180
|
+
|
|
181
|
+
### 3. **Error Handling & Edge Cases**
|
|
182
|
+
|
|
183
|
+
**LogicBank:**
|
|
184
|
+
- ✅ Automatic handling of all change scenarios
|
|
185
|
+
- ✅ Built-in transaction rollback
|
|
186
|
+
- ✅ No need to manually track old/new values
|
|
187
|
+
- ✅ Automatic cascade management
|
|
188
|
+
|
|
189
|
+
**Procedural:**
|
|
190
|
+
- ❌ Manual handling of every edge case
|
|
191
|
+
- ❌ Comments like "CRITICAL BUG FIX" indicate complexity
|
|
192
|
+
- ❌ Must manually track old values for comparison
|
|
193
|
+
- ❌ Easy to miss scenarios (product changes, order moves, etc.)
|
|
194
|
+
|
|
195
|
+
### 4. **Performance**
|
|
196
|
+
|
|
197
|
+
**LogicBank:**
|
|
198
|
+
- ✅ **Pruning**: Rules only fire when dependent attributes change
|
|
199
|
+
- ✅ **Optimization**: Uses SQL "adjustment" updates vs full recalculations
|
|
200
|
+
- ✅ **Minimal SQL**: Optimized query patterns
|
|
201
|
+
- ✅ **No N+1 problems**: Intelligent batching
|
|
202
|
+
|
|
203
|
+
**Procedural:**
|
|
204
|
+
- ❌ Multiple queries per operation
|
|
205
|
+
- ❌ Potential N+1 problems
|
|
206
|
+
- ❌ Full recalculations even for minor changes
|
|
207
|
+
- ❌ No automatic optimization
|
|
208
|
+
|
|
209
|
+
### 5. **Debugging & Observability**
|
|
210
|
+
|
|
211
|
+
**LogicBank:**
|
|
212
|
+
- ✅ Clear rule execution logs
|
|
213
|
+
- ✅ Shows rule chains and dependencies
|
|
214
|
+
- ✅ Easy to trace business logic flow
|
|
215
|
+
- ✅ Built-in logging with row state changes
|
|
216
|
+
|
|
217
|
+
**Procedural:**
|
|
218
|
+
- ❌ Hard to trace through event handlers
|
|
219
|
+
- ❌ Must manually add logging
|
|
220
|
+
- ❌ Difficult to understand execution flow
|
|
221
|
+
- ❌ Error messages don't relate to business rules
|
|
222
|
+
|
|
223
|
+
### 6. **Testing**
|
|
224
|
+
|
|
225
|
+
**LogicBank:**
|
|
226
|
+
- ✅ Test individual rules independently
|
|
227
|
+
- ✅ Clear rule execution reports
|
|
228
|
+
- ✅ Behave testing integration
|
|
229
|
+
- ✅ Rules map directly to test scenarios
|
|
230
|
+
|
|
231
|
+
**Procedural:**
|
|
232
|
+
- ❌ Must test entire event chain
|
|
233
|
+
- ❌ Hard to isolate specific logic
|
|
234
|
+
- ❌ Complex test setup required
|
|
235
|
+
- ❌ Brittle tests that break with changes
|
|
236
|
+
|
|
237
|
+
### 7. **Business Alignment**
|
|
238
|
+
|
|
239
|
+
**LogicBank:**
|
|
240
|
+
- ✅ Rules read like business requirements
|
|
241
|
+
- ✅ Business users can understand the logic
|
|
242
|
+
- ✅ Direct mapping from requirements to code
|
|
243
|
+
- ✅ Self-documenting business policies
|
|
244
|
+
|
|
245
|
+
**Procedural:**
|
|
246
|
+
- ❌ Implementation details obscure business logic
|
|
247
|
+
- ❌ Business users cannot read the code
|
|
248
|
+
- ❌ No clear mapping from requirements
|
|
249
|
+
- ❌ Business logic scattered across handlers
|
|
250
|
+
|
|
251
|
+
## Real-World Impact
|
|
252
|
+
|
|
253
|
+
### Development Time
|
|
254
|
+
- **LogicBank**: Write rules once, they work everywhere
|
|
255
|
+
- **Procedural**: Must consider every possible scenario upfront
|
|
256
|
+
|
|
257
|
+
### Risk Management
|
|
258
|
+
- **LogicBank**: Automatic handling reduces risk of bugs
|
|
259
|
+
- **Procedural**: High risk of missing edge cases
|
|
260
|
+
|
|
261
|
+
### Team Productivity
|
|
262
|
+
- **LogicBank**: New team members can quickly understand rules
|
|
263
|
+
- **Procedural**: Requires deep understanding of event system
|
|
264
|
+
|
|
265
|
+
### Business Agility
|
|
266
|
+
- **LogicBank**: Easy to modify rules as business changes
|
|
267
|
+
- **Procedural**: Changes require extensive testing and validation
|
|
268
|
+
|
|
269
|
+
## Conclusion
|
|
270
|
+
|
|
271
|
+
The comparison demonstrates that **LogicBank provides a 44X reduction in code complexity** while delivering:
|
|
272
|
+
|
|
273
|
+
- **Better Maintainability**: Rules are self-documenting and easy to modify
|
|
274
|
+
- **Higher Quality**: Automatic handling eliminates common bugs
|
|
275
|
+
- **Better Performance**: Built-in optimizations and pruning
|
|
276
|
+
- **Business Alignment**: Rules directly express business requirements
|
|
277
|
+
- **Faster Development**: Write less code, get more functionality
|
|
278
|
+
|
|
279
|
+
### The LogicBank Advantage
|
|
280
|
+
|
|
281
|
+
> **"Logic is declarative, not procedural"**
|
|
282
|
+
|
|
283
|
+
LogicBank represents a fundamental shift from asking **"How do I implement this?"** to **"What do I want to happen?"**
|
|
284
|
+
|
|
285
|
+
This declarative approach:
|
|
286
|
+
1. **Eliminates the complexity** of manual event handling
|
|
287
|
+
2. **Reduces maintenance burden** through automatic rule management
|
|
288
|
+
3. **Improves business alignment** with readable, requirements-based rules
|
|
289
|
+
4. **Accelerates development** with dramatically less code
|
|
290
|
+
|
|
291
|
+
The evidence is clear: **Declarative business logic is not just more concise—it's fundamentally superior for enterprise application development.**
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
*This comparison is based on actual implementations in the API Logic Server project, demonstrating real-world benefits of declarative business logic.*
|
|
@@ -14,8 +14,8 @@ if [ $# -eq 0 ]
|
|
|
14
14
|
# echo "shell: $SHELL"
|
|
15
15
|
echo " eg:"
|
|
16
16
|
echo " "
|
|
17
|
-
echo " > cd
|
|
18
|
-
echo " > sh
|
|
17
|
+
echo " > cd ApiLogicServer # ONLY if already running under docker"
|
|
18
|
+
echo " > sh samples/docker_samples/run_sample_docker.sh nw_sample_nocust"
|
|
19
19
|
echo " "
|
|
20
20
|
exit 0
|
|
21
21
|
fi
|
|
@@ -26,5 +26,5 @@ if [ "$1" = "$" ]
|
|
|
26
26
|
sample="nw_sample"
|
|
27
27
|
fi
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
docker run -it --rm --name
|
|
29
|
+
pushd samples/$sample
|
|
30
|
+
docker run -it --rm --name api_logic_project_${sample}_$(date +%s) -p 5656:5656 --env-file ./devops/docker-standard-image/env.list -v ./:/app apilogicserver/web_genai python3 /app/api_logic_server_run.py
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Create a table SysEmail in `database/db.sqlite` as a child of customer,
|
|
2
|
+
with columns id, message, subject, customer_id and CreatedOn.
|
|
3
|
+
|
|
4
|
+
Add an after_flush event on SysEmail to produce a log message "email sent",
|
|
5
|
+
unless the customer has opted out.
|
|
6
|
+
|
|
7
|
+
List the orders date_shipped is null and CreatedOn before 2023-07-14,
|
|
8
|
+
and send a discount email (subject: 'Discount Offer') to the customer for each one.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Create a system with customers, orders, items and products.
|
|
2
|
+
|
|
3
|
+
Include a notes field for orders.
|
|
4
|
+
|
|
5
|
+
Use case: Check Credit
|
|
6
|
+
1. The Customer's balance is less than the credit limit
|
|
7
|
+
2. The Customer's balance is the sum of the Order amount_total where date_shipped is null
|
|
8
|
+
3. The Order's amount_total is the sum of the Item amount
|
|
9
|
+
4. The Item amount is the quantity * unit_price
|
|
10
|
+
5. The Item unit_price is copied from the Product unit_price
|
|
11
|
+
|
|
12
|
+
Use case: App Integration
|
|
13
|
+
1. Send the Order to Kafka topic 'order_shipping' if the date_shipped is not None.
|