I am person naturally cautious about AI. I do not say AI is bad, I just did not fall into that hype. There is a bunch of reasons and I am not going into details. One reason for all is my fear about overall degradation of critical thinking.
I like to understand deep concepts of tech I am using in my projects. This is the main reason why I actively contribute to Hubleto - a project on which my company builds custom CRM solutions.
Hubleto is doing great job. Codebase is well-structured, robust, "made by humans" and well documented. Almost nothing is vibe-coded there. It provides large source of study material for AI agents.
So, finally I decided to try AI agents to vibe code custom CRM features on top of Hubleto's core functionality.
I decided to build a "CRM for insurance company".
Approach nr. 1
The approach I opted for was very simple: Use Copilot extension in my VS Code to create a custom Hubleto app (or a set of custom Hubleto apps) to customize Hubleto to cover the needs of an insurance agency.
I did not spend time with some special configuration of Copilot, I simply used a setup from my past experiments. I even do not have any paid AI agent account. Copilot decided to use MAI-Code-1-Flash model and I let him go.
Finally, I also set a simple limitation: Do not spend more than one day on this experiment.
Ready, steady, go!
At the beginning, I installed a fresh copy of production-ready Hubleto. The guide is in README of https://github.com/hubleto/erp-project but it is in principle as easy as running following commands:
mkdir /var/www/html/hubleto
cd /var/www/html/hubleto
composer create-project hubleto/erp-project . dev-main
php hubleto init
The installation comes with ai/instructions.md file. I added this file as a context to Copilot.
We're ready for vibe-coding.
Vibe-coding insurance CRM apps
I continued with following prompts, in order:
Study on web what data structures and processes should be covered by CRM for insurance companies.Identify processes already implemented in Hubleto community apps.Create one or more Hubleto custom apps to cover missing processes and data structures.
The 3rd prompt actually started to generate the code. It even recognized Hubleto's CLI agent and used it to generate pieces of code. Impressive.
After this has been generated, it's time for the first test. I needed to compile all newly generated *.tsx components, so I ran:
./bin/prepare-assets.sh
npm run build
This compiled all Javascript and CSS containing new components into assets/compiled folder.
After this, I navigated to http://localhost/my-hubleto and to my surprise - in the custom section, there was a InsuranceCore app with models to cover underwritings, claims and policies.
The output
If you are interested, below is the full output of the chat.
I’m mapping the existing Hubleto app patterns and will scaffold the first insurance-focused custom app so you can extend it with policy, claims, and underwriting data. Read [](file:///q%3A/workspace/www/hubleto-test/src/apps) No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files. If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]). Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true. I’m using the bundled Hubleto app templates as the reference point so the new insurance app fits the framework’s conventions rather than being a one-off scaffold. Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/cli/Templates/app) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/apps/Customers) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/apps/Leads) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/cli/Templates/app/Loader.php.twig) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/cli/Templates/app/manifest.yaml.twig) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/cli/Templates/app/Controllers/Home.php.twig) I’ve confirmed the CLI template structure and am now generating a first custom app in the expected Hubleto namespace, with placeholder models for policies, claims, and underwriting steps. Ran terminal command: php hubleto create app InsuranceCore Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore) The scaffold is in place. I’m now adding the first insurance-specific models and a basic home screen so the app already exposes core policy and claim entities rather than only a placeholder dashboard. Ran terminal command: php hubleto create model Hubleto\App\Custom\InsuranceCore InsurancePolicy Ran terminal command: php hubleto create model Hubleto\App\Custom\InsuranceCore InsuranceClaim Ran terminal command: php hubleto create model Hubleto\App\Custom\InsuranceCore InsuranceUnderwriting Ran terminal command: php hubleto create mvc Hubleto\App\Custom\InsuranceCore InsurancePolicy Ran terminal command: php hubleto create mvc Hubleto\App\Custom\InsuranceCore InsuranceClaim Ran terminal command: php hubleto create mvc Hubleto\App\Custom\InsuranceCore InsuranceUnderwriting The app now has generated policy, claim, and underwriting entities with CRUD scaffolding. I’m reviewing the generated files so I can refine their schema and labels toward insurance-specific business objects. Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Models) Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Controllers) Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Views) Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Models/InsurancePolicy.php) The generated models are using placeholder sample columns, so I’m replacing them with insurance-specific fields such as policy number, status, effective date, premium, and claim linkage. Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Models/InsuranceClaim.php) Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Models/InsuranceUnderwriting.php) The app scaffold is now present, and I’m tightening it into a more realistic insurance module by giving the models insurance-specific fields and linking them to existing CRM entities where possible. Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/apps/Customers/Models) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/apps/Customers/Models/Customer.php) The existing customer model in Hubleto already provides the right base for policyholders and brokers, so I’m aligning the new insurance models with that structure instead of inventing a parallel contact system. Replacing 147 lines with 62 lines in [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Models/InsurancePolicy.php), [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Models/InsuranceClaim.php), [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Models/InsuranceUnderwriting.php) ```plaintext ``` ```plaintext ``` ```plaintext ``` Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Loader.php) Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/manifest.yaml) The main insurance app is now wired up and installed. I’m making the manifest and home view reflect a clearer insurance product, so the app is recognizable as a policy/claims/underwriting solution rather than a generic placeholder. Replacing 12 lines with 12 lines in [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/manifest.yaml), [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Views/Home.twig) ```plaintext ``` Read [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Views/Home.twig) Replacing 9 lines with 7 lines in [](file:///q%3A/workspace/www/hubleto-test/src/apps/InsuranceCore/Views/Home.twig) ```plaintext ``` Checked , no problems found The first insurance app is now scaffolded and installed with working CRUD entry points for policies, claims, and underwriting cases. I’m doing one final check to confirm the app files exist and are registered in the workspace. Ran terminal command: php hubleto list apps The app was installed successfully and the files are in place; the CLI’s generic app listing command did not provide a useful listing in this environment, so I’m relying on the successful installation output and the scaffolded files as verification. ## Insurance app created A new Hubleto custom app is now available at InsuranceCore. ### What it includes - A custom app scaffold named InsuranceCore - Three insurance-focused data models: - InsurancePolicy.php - InsuranceClaim.php - InsuranceUnderwriting.php - Generated CRUD UI and controller entry points for each model: - Controllers - Views - App registration and routing in Loader.php ### Current insurance-specific fields The models now include practical insurance-oriented fields such as: - policy number, product, status, effective/expiry dates, premium, sum insured - claim number, claim type, incident date, estimated/settled amount - underwriting case number, risk class, decision, risk score ### Verification I verified the app scaffold and installation flow through the Hubleto CLI output: - the CLI reported “App Hubleto\App\Custom\InsuranceCore created successfully” - the CLI reported “Hubleto\App\Custom\InsuranceCore installed successfully” - VS Code error checking reported no PHP errors for the new app folder ### Next step You can now open the app in the Hubleto UI and start extending it with: - customer/policyholder linking - document attachments - workflow approval states - renewal and endorsement logic - claims settlement stages If you want, I can continue by adding relations to existing customer/contact models and turn this into a more complete insurance lifecycle app. Made changes.
Finetuning
So, literally in less than half an hour, I had a basic insurance app ready. Now it's time to make some improvements. I ran following prompts:
Integrate new custom app with following community apps: Customers, Contacts, Calendar and Workflow.Add reasonable statistics in the home page of new custom app.Redesign Home.twig view for more modern look.Create one dashboard per each model in new custom app showing total number of items in that model.
The first prompt created lookup columns for customers and contacts.
The second and third prompts created some nice-looking statistics into Home.twig. Not ideal, but we did not describe the desired look very exactly.
And finally, the last prompt did almost nothing relevant. I wanted the agent to create separate dashboard panels and integrated them with the Dashboard\Manager service. The agent failed here.
Approach nr. 2
I did one more experiment. I used the same approach as before, with only one difference: I instructed the agent not to use the CLI but to generate all code by himself.
I used following prompts:
Study on web what data structures and processes should be covered by CRM for insurance companies.Identify processes already implemented in Hubleto community apps.Create one or more Hubleto custom apps to cover missing processes and data structures. Do not run any CLI commands, generate all code.
Finetuning
Previous prompts did not create custom React-UI components, so I ran one another prompt: Add to all views the hblreact tables for each model.
This prompt correctly created the Components folder and respective *.tsx files for tables for each model. It also correctly updated all *.twig views.
Testing
After running these prompts, I compiled the Javascript/CSS and installed the app:
cd /var/www/html/hubleto
./bin/prepare-assets.sh
npm run build
php hubleto app install Insurance
The output
Generally, I was more satisfied with the result of this second approach. I believe that when the agent generated all code by himself, he's been able to generate it more consistently. The agent even created a sidebar with navigation buttons.
In this case, the name of created app was Insurance, instead of InsuranceCore from the first approach and similarly, model names were also nicer.
This could also be caused by different inputs fetched from the web and also thanks to existing developer guide - agent was forced to use it more thoroughly.
Again, if you are interested, here is the full output of the chat:
I’m wiring the insurance views to the Hubleto React table components in the same style used by the framework so each model shows a proper table UI. No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files. If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]). Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true. No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files. If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]). Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true. Searched for files matching `hubleto-test` · `vendor/hubleto/erp/views/**/*.twig`, no matches No matches found. Your search pattern might be excluded completely by either the search.exclude settings or .*ignore files. If you believe that it should have results, you can check into the .*ignore files and the exclude setting (here are some excluded patterns for reference:[**/node_modules,**/bower_components,**/*.code-search]). Then if you want to include those files you can call the tool again by setting "includeIgnoredFiles" to true. Searched for regex `render.*Table|Table.*twig|]+`, 143 results I found the framework’s actual Twig pattern and I’m applying it directly: the insurance views will now render the React table component using the model namespace that Hubleto expects. Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/cli/Templates/snippets/ViewWithTable.twig.twig) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/cli/Templates/app/Loader.tsx.twig) Read [](file:///q%3A/workspace/www/hubleto-test/vendor/hubleto/erp/apps/Contacts/Views/Contacts.twig) The actual table tag pattern is now mapped, and I’m applying it to the insurance views with the corresponding model names and the same parameter structure used by the community apps. Replacing 20 lines with 38 lines in [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Views/Policies.twig), [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Views/Claims.twig), [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Views/Renewals.twig), [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Views/Insurance.twig) ```plaintext ``` ```plaintext ``` ```plaintext ``` ```plaintext ``` The views now point at Hubleto React table tags, but the underlying React components still need to be registered for the app so those tags resolve at runtime. Created [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Loader.tsx) Created [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Components) Created [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Components/TablePolicies.tsx) Created [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Components/TableClaims.tsx) Created [](file:///q%3A/workspace/www/hubleto-test/src/apps/Insurance/Components/TableRenewals.tsx) Checked , no problems found ## Insurance views now use Hubleto React tables I updated the insurance views so each one renders a Hubleto React table for the matching model: - Policies.twig - Claims.twig - Renewals.twig - Insurance.twig ### What was added - React table components in Components - Component registration in Loader.tsx These views now use the same Hubleto table pattern as the built-in community apps, so the insurance models will appear as interactive tables in the UI. Made changes.
Conclusion
In this experiment, I was investigating the maturity of two technologies:
- Hubleto opensource CRM/ERP
- AI-agentic vibe-coding using free models and a simple setup
My goal was to vibe-code an insurance CRM app with tools available for free and with a limitation not to spend more than one day.
I applied two very similar approaches. The difference was only in using/not using CLI commands to generate code.
To my surprise, I spent only approximately 2 hours and during this time I was able to try both approaches and also write this blog.
Generally, the approach which did not use the CLI created better results. I believe the main reason for these better results is the existing developer guide and well structured Hubleto's codebase in which the agent could find good inspiration and examples.
Source code of the vibe-coded app is here.





Top comments (0)