The Thought
A venture time-tracking system ought to enable entry of:
- Purchasers have a number of tasks consisting of a number of duties.
- Duties have timesheet entries, accomplished by individuals getting into hours working for a consumer.
- Invoices are created by including bill gadgets linked to billable timesheet traces.
- As soon as the bill is marked as prepared, ship the knowledge to Kafka for bill processing.
The Immediate
GenAI Logic is an online web page, like many chatbots, that permits the consumer to enter a immediate. The extra particulars offered, the higher the consequence (though you possibly can iterate so as to add or change the end result utilizing the “Iterate” button).
You need to describe the mannequin and attribute, the logic, and the use circumstances as totally as potential. Then, merely click on “Create Tasks” and wait about 90 seconds.
One notice: Beneath “Advance Settings,” change the information mannequin dimension to eight (the variety of tables to create). This prevents GenAI from including extra tables which are wanted.
Use these names for tables and attributes:
* Shopper (id, identify, electronic mail, telephone, total_hours, total_amount, budget_amount, is_over_budget)
* Venture ( id, client_id, identify, total_project_hours, total_project_amount, project_budget_amount, is_over_budget, is_active)
* Bill: (id, invoice_date, project_id, invoice_amount, payment_total, invoice_balance, is_paid, is_ready,task_count,completed_task_count)
* InvoiceItem(id, invoice_id, task_id, task_amount, is_completed)
* Activity (id, project_id, identify, description, total_task_hours_worked, total_task_amount_billed, task_budget_hours, is_over_budget,is_completed)
* Individual (id, client_id, identify, electronic mail, telephone, billing_rate, total_hours_entered, total_amount_billed)
* Timesheet (id,task_id, person_id, date_worked, hours_worked, billing_rate, total_amount_billed, is_billable)
* Fee (id, invoice_id, quantity, payment_date, notes)
Enterprise Logic
Break down the logic into use circumstances, beginning with timesheets, to explain the enterprise logic. For instance: “Copy the individual’s billing_rate
multiplied by the hours_worked
to get the total_amount_billed
.”
Then, modify the use case rule to solely carry out the calculation if the is_billable
flag is ready to True
(some duties are non-billable). The sums and counts are rolled up from Activity to Venture to Shopper. The is_over_budget
flag is decided based mostly on the budget_amount
of the Shopper and Venture.
The bill has an is_ready
flag that, when set to true
, sends the bill row to Kafka. This enables a Kafka client to provoke the workflow integration in a separate container. Different workflows and integrations might be simply added to the use circumstances.
Enterprise Guidelines (Logic)
Use LogicBank to implement enterprise logic.
Use case: Individual
Whole Hours entered is sum of timesheet hours labored
Whole quantity billed is complete hours entered occasions billing fee
Billing fee have to be larger than 0 and fewer than 200
Use case: Timesheet
Copy billing fee from Individual billing fee
If is_billable then the overall quantity billed is the billing fee occasions hours labored
Hours labored have to be larger than 0 and fewer than 15
Use Case: Activity
Whole process hours labored is the sum of the Timesheet hours labored
Whole process quantity billed is the sum of the Timesheet complete quantity billed
Method: is Over Price range when complete process hours labored exceeds process funds hours
Use Case: Venture
Whole venture hours is the sum of Activity complete process hours labored
Whole venture quantity is the sum of Activity complete quantity billed
Method: is Over Price range when complete venture quantity exceeds venture funds quantity
Use Case: Shopper
Whole hours is the sum of Venture complete venture hours
Whole quantity is the sum of Venture complete venture quantity
Method: is Over Price range equals true when complete quantity exceeds funds quantity
Use Case: Bill
Bill Quantity is the sum of InvoiceItem process quantity
Fee complete is the sum of Fee quantity
Bill stability is bill quantity much less cost complete
Method: is_paid when bill stability is than or equal to zero
Activity Rely is rely of InvoiceItem
Activity accomplished rely is rely of InvoiceItem the place is_completed is True
Method: is prepared when Activity Rely is the same as Activity Accomplished Rely
Ship bill to Kafka when is_ready is True
Use Case: InvoiceItem
InvoiceItem process quantity is copied from Activity complete process quantity billed
InvoiceItem is_completed is sum of Activity is_completed when True
The Venture
When accomplished, GenAI Logic creates an SQL Database (SQLite), a SQLAlchemy ORM mannequin, an API (JSON API), a react-admin consumer, full enterprise logic (25+ guidelines), and pattern information for testing. This is able to simply be over 1,000 traces of code to deal with all of the use circumstances of including, updating, deleting, and reparenting entries. The whole venture might be downloaded from GitHub or a zipper file for the developer to overview.
Only for enjoyable, the system additionally created a single-page software touchdown web page to exhibit your venture immediate.
The Information Mannequin
The “Backend Admin” button results in the working web page that features the logic, the mannequin, a pattern react-admin software (for testing the foundations), and instruments for the developer. This was the mannequin created from the immediate.
Discover the Venture
The API entities at the moment are prepared to check on the left (a react software) to see take a look at information. Enter a Shopper, Venture, Activity, and Timesheet for a Individual and watch the sums, counts, and constraint guidelines change worth.
You too can run the generated software domestically utilizing Docker or click on on the GitHub hyperlink to see the code and run the applying utilizing GitHub CodeSpaces.
Lastly, discover the API endpoints utilizing OpenAPI (Swagger). If the “> Logic Guidelines” have any points, they are often individually reviewed, edited, rejected, or accepted. GenAI may even recommend logic based mostly in your mannequin (see the “Logic” button).
Word: You too can run the Docker model domestically.
The Logic Logs: Auditable and Clear
Enterprise logic shouldn’t be a black field. As API endpoints are accessed (POST, PATCH, and DELETE), the foundations hearth on state adjustments of dependent entities and attributes. An entire log of guidelines that fired and the order they fired, together with the row values impacted, provides a full, clear view of the processing. This isn’t a black field however a real companion to companies that require auditable and clear logic transactions.
Word that the before_flush
exhibits the state change of every row impacted so as, and the after_flush
exhibits the ultimate assortment of guidelines that fired (it is a lot of element, however it’s essential if that you must move an audit).
Additionally, notice that the order begins with the timesheet change and cascades as much as the mother or father Shopper. Guidelines are unordered within the declaration (see logic folder) and might simply be added/modified with out impacting different guidelines.
Logic Section: ROW LOGIC (session=0xffffac2f0bf0) (sqlalchemy before_flush)
..Timesheet[3] {Replace - consumer} id: 3, task_id: 12, person_id: 6, date_worked: [2025-02-20-->] 2025-02-20 00:00:00, hours_worked: [12.00-->] 10, billing_rate: 100, total_amount_billed: 1200, is_billable: True row: 0xffffac2443b0 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
..Timesheet[3] {Method total_amount_billed} id: 3, task_id: 12, person_id: 6, date_worked: [2025-02-20-->] 2025-02-20 00:00:00, hours_worked: [12.00-->] 10, billing_rate: 100, total_amount_billed: [1200-->] 1000, is_billable: True row: 0xffffac2443b0 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
....Individual[6] {Replace - Adjusting individual: total_hours_entered} id: 6, client_id: 8, identify: Individual (New Shopper), electronic mail: individual@consumer.com, telephone: 8885551212, billing_rate: 100.00, total_hours_entered: [12.00-->] 10.00, total_amount_billed: 1200.00 row: 0xffffac244380 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
....Individual[6] {Method total_amount_billed} id: 6, client_id: 8, identify: Individual (New Shopper), electronic mail: individual@consumer.com, telephone: 8885551212, billing_rate: 100.00, total_hours_entered: [12.00-->] 10.00, total_amount_billed: [1200.00-->] 1000.0000 row: 0xffffac244380 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
....Activity[12] {Replace - Adjusting process: total_task_hours_worked, total_task_amount_billed} id: 12, project_id: 6, identify: New Activity, description: , total_task_hours_worked: [12.00-->] 10.00, total_task_amount_billed: [1200.00-->] 1000.00, task_budget_hours: 1000.00, is_over_budget: False, is_completed: False row: 0xffffac2450a0 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
......Venture[6] {Replace - Adjusting venture: total_project_hours, total_project_amount} id: 6, client_id: 8, identify: New Venture, total_project_hours: [12.00-->] 10.00, total_project_amount: [1200.00-->] 1000.00, project_budget_amount: 1000.00, is_over_budget: True, is_active: False row: 0xffffac247860 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
......Venture[6] {Method is_over_budget} id: 6, client_id: 8, identify: New Venture, total_project_hours: [12.00-->] 10.00, total_project_amount: [1200.00-->] 1000.00, project_budget_amount: 1000.00, is_over_budget: [True-->] False, is_active: False row: 0xffffac247860 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
........Shopper[8] {Replace - Adjusting consumer: total_hours, total_amount} id: 8, identify: New Shopper, electronic mail: , telephone: , total_hours: [12.00-->] 10.00, total_amount: [1200.00-->] 1000.00, budget_amount: 0.00, is_over_budget: True row: 0xffffac2321e0 session: 0xffffac2f0bf0 ins_upd_dlt: upd, preliminary: upd
Logic Section: COMMIT LOGIC (session=0xffffac2f0bf0)
Logic Section: AFTER_FLUSH LOGIC (session=0xffffac2f0bf0)
These Guidelines Fired (see Logic Phases, above, for precise order): ##
Shopper ##
1. Derive .total_hours as Sum(Venture.total_project_hours The place - None) ##
2. Derive .total_amount as Sum(Venture.total_project_amount The place - None) ##
3. Derive .is_over_budget as Method (1): Rule.method(derive=Shopper.is_over_budget, as_exp [...] ##
Individual ##
4. Derive .total_amount_billed as Method (1): Rule.method(derive=Individual.total_amount_billed, a [...] ##
5. Derive .total_hours_entered as Sum(Timesheet.hours_worked The place - None)
Venture ##
6. Derive .total_project_amount as Sum(Activity.total_task_amount_billed The place - None)
7. Derive .is_over_budget as Method (1): Rule.method(derive=Venture.is_over_budget,
as_ex [...] ##
8. Derive .total_project_hours as Sum(Activity.total_task_hours_worked The place - None) Activity ##
9. Derive .total_task_amount_billed as Sum(Timesheet.total_amount_billed The place - None)
10. Derive .is_over_budget as Method (1): Rule.method(derive=Activity.is_over_budget,
as_expre [...] ##
11. Derive .total_task_hours_worked as Sum(Timesheet.hours_worked The place - None)
Timesheet ##
12. Derive .total_amount_billed as Method (1): Rule.method(derive=Timesheet.total_amount_billed [...] ##
Logic Section: COMPLETE(session=0xffffac2f0bf0))
ApiLogicServer: The Developer Journey
The whole generative method is constructed on high of the open-source ApiLogicServer (ALS). As soon as the venture is downloaded, it may be edited utilizing VSCode (or your favourite IDE). The platform is constructed on Python 3.12, SQLAlchemy ORM, and Flask.
The super-power is the declarative guidelines engine LogicBank.
- Are expressive – 40X the expressive energy of procedural code
- Promote high quality – Robotically invoked
- Are maintainable – Robotically ordered
- Rule execution logs – Auditable, traceable, and clear
The venture is organized into folders: API, config, logic, database, integration, safety, DevOps, and take a look at. Every folder is completely documented and offers the developer with the flexibility so as to add/modify options and companies (e.g., customized API endpoints, integrations, behave take a look at circumstances, or declarative role-based entry management) in an IDE. (Carry your individual favourite AI instrument 0.— CoPilot, Sourcery, Cursor, and so forth.)
Listed here are the steps taken to edit/modify the native venture. Whereas it’s potential to make use of SQLIte in manufacturing (8 billion smartphones can’t be improper), I selected the PostgreSQL route.
- Convert SQLite to PostgreSQL (sqlite3 database/db.sqlite .dump > timetrack_pg.sql).
- Modify the SQL file for PostgreSQL particular (e.g., change sequence to SERIAL8).
- Create the PostgreSQL database and rebuild the mannequin ($als rebuild-from-database).
- Add KeyCloak safety ($als add-auth –provider-type=keycloak or SQL).
- Modify the config.py to level to Keycloak or SQL occasion.
- Add role-based entry management for various roles (e.g,. supervisor, advisor, accounting). See safety/declare_security.py.
- Initialize the GitHub repository and push adjustments.
- Use devops/docker-image ($sh build-image.sh) to create and push the container to the Docker hub.
Word: You could want to alter the linux/amd64 to linux/arm64 on your deployed atmosphere.
Amazon EC2 and RDS Work
- Create an RDS PostgreSQL occasion and deploy timetrack_pg.sql (create database timetracker).
- Create an EC2 occasion and pull the docker picture into the container.
- Add a docker-compose file to start out the picture and connect with RDS.
- Check the authorization http://ec2……compute-1.amazonaws.com:5656.
Check Pushed Improvement
One fast phrase about testing logic. Utilizing the Behave situation characteristic proven under, we rapidly added the implementation to insert varied API entities and take a look at the derivations, aggregations, and occasions with full log traceability.
Situation: New Timesheet
Given Enter Timesheet Information
When Timesheet Put up
Then Timesheet entered and balances
@given('Enter Timesheet Information')
def step_impl(context):
context.information = {"task_id": task_id, "person_id": person_id, "hours_worked": 10, "date_worked": "2025-01-01","is_billable": True}
assert True shouldn't be False
@when('Timesheet Put up')
def step_impl(context):
print(context.information)
r = test_utils.publish("Timesheet", context.information)
context.response = r
assert True shouldn't be False
@then('Timesheet entered and balances')
def step_impl(context):
situation = "New Timesheet"
test_utils.prt(f'Guidelines Report', situation)
international timesheet_id
timesheet_id = int(context.response["data"]["id"])
r = test_utils.get("Shopper", client_id)
total_hrs = r["data"]["attributes"]["total_hours"] ## 10
assert total_hrs == 10, f"Whole Hours: {total_hrs} anticipated: 10"
The Log
Mapped Class[Timesheet] guidelines: ## - 2025-02-25 13:49:22,057 - logic_logger - INFO
Derive .billing_rate as Copy(individual.billing_rate) ## - 2025-02-25 13:49:22,057 - logic_logger - INFO
Derive .total_amount_billed as Method (1): Rule.method(derive=Timesheet.total_amount_billed [...] ## - 2025-02-25 13:49:22,057 - logic_logger - INFO
Angular Entrance-Finish Utilizing OntimizeWeb
ApiLogicServer also can generate an Angular front-end utilizing OntimizeWeb from Imatia. Every API endpoint is used to create pages that may be modified utilizing commonplace instruments or regenerated by modifying the templates (jinja fashion) used to construct web page types (tables, grids, grasp/element, treeview, and so forth.).
From the command line:
$als app-create --app=timetracker
$als app-build --app=timetracker
$cd ui/timetracker
$npm set up && npm begin
Docker and NGINX
As soon as the Angular front-end has been authorised by the UX staff, it is able to be dockerized and pushed.
- cd ui/timetracker
- Evaluate nginx/nginx.conf for manufacturing routing
- Evaluate src/environments/timetracker.prod.ts routing
- $docker construct -f Dockerfile -t ${dockerhub}/timetracker –rm
- Test in adjustments to GitHub
Modify EC2 Compose File
Add the brand new front-end to the docker-compose.yml file and restart. The brand new Ontimize software must be working on port 80. Use Keycloak to log in (or add SQL authentication and use a reputation/password). As soon as logged in, create a consumer, a venture, process, or individual and enter a timesheet (under). Then, see the logs to look at how guidelines hearth.
TreeView Listing of Purchasers and Duties
Abstract: Immediate to Manufacturing in 2 Hours, Human within the Loop
The immediate to manufacturing course of required roughly 2 hours to finish. Though “Immediate to Manufacturing” is the headline, human involvement was nonetheless mandatory for duties corresponding to safety configuration (authentication and authorization), docker compose file configuration, and UX/UI fine-tuning.
Moreover, Kafka and Workflow integrations and configurations required the experience of a separate staff member. The UX staff might need to improve the feel and appear, however that is 100% useful and examined.
See the Venture Time Tracker on GitHub repository right here.