2523 lines
73 KiB
Markdown
2523 lines
73 KiB
Markdown
<file_map>
|
|
/Users/despiegk/code/github/incubaid/herolib
|
|
└── aiprompts
|
|
└── herolib_core
|
|
├── core_curdir_example.md
|
|
├── core_globals.md
|
|
├── core_heroscript_basics.md
|
|
├── core_heroscript_playbook.md
|
|
├── core_http_client.md
|
|
├── core_osal.md
|
|
├── core_ourtime.md
|
|
├── core_params.md
|
|
├── core_paths.md
|
|
├── core_text.md
|
|
├── core_ui_console.md
|
|
└── core_vshell.md
|
|
|
|
/Users/despiegk/code/git.threefold.info/herocode/db
|
|
├── _archive
|
|
│ ├── acldb
|
|
│ │ ├── src
|
|
│ │ │ ├── acl.rs
|
|
│ │ │ ├── error.rs
|
|
│ │ │ ├── lib.rs
|
|
│ │ │ ├── main.rs
|
|
│ │ │ ├── rpc.rs
|
|
│ │ │ ├── server.rs
|
|
│ │ │ ├── topic.rs
|
|
│ │ │ └── utils.rs
|
|
│ │ ├── static
|
|
│ │ │ ├── openapi.json
|
|
│ │ │ └── swagger-ui.html
|
|
│ │ ├── Cargo.lock
|
|
│ │ ├── Cargo.toml
|
|
│ │ └── README.md
|
|
│ ├── adapter_macros
|
|
│ │ ├── src
|
|
│ │ │ └── lib.rs
|
|
│ │ ├── Cargo.lock
|
|
│ │ ├── Cargo.toml
|
|
│ │ └── README.md
|
|
│ ├── herodb_old
|
|
│ │ ├── aiprompts
|
|
│ │ │ ├── builderparadigm.md
|
|
│ │ │ ├── moduledocu.md
|
|
│ │ │ ├── rhaiwrapping_advanced.md
|
|
│ │ │ ├── rhaiwrapping_best_practices.md
|
|
│ │ │ └── rhaiwrapping.md
|
|
│ │ ├── examples
|
|
│ │ │ ├── business_models_demo.rs
|
|
│ │ │ ├── circle_basic_demo.rs
|
|
│ │ │ ├── circle_models_demo.rs
|
|
│ │ │ ├── circle_standalone.rs
|
|
│ │ │ ├── ourdb_example.rs
|
|
│ │ │ └── tst_index_example.rs
|
|
│ │ ├── src
|
|
│ │ │ ├── cmd
|
|
│ │ │ │ ├── dbexample_biz
|
|
│ │ │ │ │ ├── main.rs
|
|
│ │ │ │ │ ├── mod.rs
|
|
│ │ │ │ │ └── README.md
|
|
│ │ │ │ ├── dbexample_gov
|
|
│ │ │ │ │ └── main.rs
|
|
│ │ │ │ ├── dbexample_mcc
|
|
│ │ │ │ │ └── main.rs
|
|
│ │ │ │ ├── dbexample_prod
|
|
│ │ │ │ │ └── main.rs
|
|
│ │ │ │ └── mod.rs
|
|
│ │ │ ├── db
|
|
│ │ │ │ ├── db.rs
|
|
│ │ │ │ ├── error.rs
|
|
│ │ │ │ ├── generic_store.rs
|
|
│ │ │ │ ├── macros.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── model_methods.rs
|
|
│ │ │ │ ├── model.rs
|
|
│ │ │ │ ├── store.rs
|
|
│ │ │ │ ├── tests.rs
|
|
│ │ │ │ └── tst_index.rs
|
|
│ │ │ ├── models
|
|
│ │ │ │ ├── biz
|
|
│ │ │ │ │ ├── rhai
|
|
│ │ │ │ │ │ ├── examples
|
|
│ │ │ │ │ │ │ ├── example.rhai
|
|
│ │ │ │ │ │ │ └── example.rs
|
|
│ │ │ │ │ │ ├── src
|
|
│ │ │ │ │ │ │ ├── engine.rs
|
|
│ │ │ │ │ │ │ ├── generic_wrapper.rs
|
|
│ │ │ │ │ │ │ ├── lib.rs
|
|
│ │ │ │ │ │ │ └── wrapper.rs
|
|
│ │ │ │ │ │ ├── Cargo.lock
|
|
│ │ │ │ │ │ └── Cargo.toml
|
|
│ │ │ │ │ ├── contract.rs
|
|
│ │ │ │ │ ├── currency.rs
|
|
│ │ │ │ │ ├── customer.rs
|
|
│ │ │ │ │ ├── exchange_rate.rs
|
|
│ │ │ │ │ ├── invoice.rs
|
|
│ │ │ │ │ ├── lib.rs
|
|
│ │ │ │ │ ├── mod.rs
|
|
│ │ │ │ │ ├── product.rs
|
|
│ │ │ │ │ ├── README.md
|
|
│ │ │ │ │ ├── sale.rs
|
|
│ │ │ │ │ └── service.rs
|
|
│ │ │ │ ├── circle
|
|
│ │ │ │ │ ├── circle.rs
|
|
│ │ │ │ │ ├── lib.rs
|
|
│ │ │ │ │ ├── member.rs
|
|
│ │ │ │ │ ├── mod.rs
|
|
│ │ │ │ │ ├── name.rs
|
|
│ │ │ │ │ ├── README.md
|
|
│ │ │ │ │ └── wallet.rs
|
|
│ │ │ │ ├── gov
|
|
│ │ │ │ │ ├── committee.rs
|
|
│ │ │ │ │ ├── company.rs
|
|
│ │ │ │ │ ├── meeting.rs
|
|
│ │ │ │ │ ├── mod.rs
|
|
│ │ │ │ │ ├── README.md
|
|
│ │ │ │ │ ├── resolution.rs
|
|
│ │ │ │ │ ├── shareholder.rs
|
|
│ │ │ │ │ ├── user.rs
|
|
│ │ │ │ │ └── vote.rs
|
|
│ │ │ │ ├── mcc
|
|
│ │ │ │ │ ├── calendar.rs
|
|
│ │ │ │ │ ├── contacts.rs
|
|
│ │ │ │ │ ├── event.rs
|
|
│ │ │ │ │ ├── lib.rs
|
|
│ │ │ │ │ ├── mail.rs
|
|
│ │ │ │ │ ├── message.rs
|
|
│ │ │ │ │ ├── mod.rs
|
|
│ │ │ │ │ └── README.md
|
|
│ │ │ │ ├── py
|
|
│ │ │ │ │ ├── __init__.py
|
|
│ │ │ │ │ ├── api.py
|
|
│ │ │ │ │ ├── business.db
|
|
│ │ │ │ │ ├── example.py
|
|
│ │ │ │ │ ├── install_and_run.sh
|
|
│ │ │ │ │ ├── models.py
|
|
│ │ │ │ │ ├── README.md
|
|
│ │ │ │ │ └── server.sh
|
|
│ │ │ │ ├── instructions.md
|
|
│ │ │ │ └── mod.rs
|
|
│ │ │ ├── rhaiengine
|
|
│ │ │ │ ├── engine.rs
|
|
│ │ │ │ └── mod.rs
|
|
│ │ │ ├── error.rs
|
|
│ │ │ ├── instructions.md
|
|
│ │ │ ├── lib.rs
|
|
│ │ │ └── mod.rs
|
|
│ │ ├── .gitignore
|
|
│ │ ├── Cargo.lock
|
|
│ │ ├── Cargo.toml
|
|
│ │ └── README.md
|
|
│ ├── websocket
|
|
│ │ └── architecture.md
|
|
│ ├── instructions.md
|
|
│ └── rhai.rs
|
|
├── herodb_old
|
|
│ └── tmp
|
|
│ └── circle_demo
|
|
│ ├── circle
|
|
│ │ └── circle
|
|
│ │ └── lookup
|
|
│ │ ├── .inc
|
|
│ │ └── data
|
|
│ ├── member
|
|
│ │ └── member
|
|
│ │ └── lookup
|
|
│ │ ├── .inc
|
|
│ │ └── data
|
|
│ ├── name
|
|
│ │ └── name
|
|
│ │ └── lookup
|
|
│ │ ├── .inc
|
|
│ │ └── data
|
|
│ └── wallet
|
|
│ └── wallet
|
|
│ └── lookup
|
|
│ ├── .inc
|
|
│ └── data
|
|
├── heromodels
|
|
│ ├── docs
|
|
│ │ ├── prompts
|
|
│ │ │ ├── new_rhai_rs_gen.md
|
|
│ │ │ └── rhai_rs_generation_prompt.md
|
|
│ │ ├── herodb_ourdb_migration_plan.md
|
|
│ │ ├── mcc_models_standalone_plan.md
|
|
│ │ ├── model_trait_unification_plan.md
|
|
│ │ ├── payment_usage.md
|
|
│ │ ├── sigsocket_architecture.md
|
|
│ │ ├── tst_implementation_plan.md
|
|
│ │ └── tst_integration_plan.md
|
|
│ ├── examples
|
|
│ │ ├── biz_rhai
|
|
│ │ │ ├── payment_flow_example.rs
|
|
│ │ │ └── payment_flow.rhai
|
|
│ │ ├── calendar_example
|
|
│ │ │ └── main.rs
|
|
│ │ ├── finance_example
|
|
│ │ │ └── main.rs
|
|
│ │ ├── governance_proposal_example
|
|
│ │ │ └── main.rs
|
|
│ │ ├── basic_user_example.rs
|
|
│ │ ├── custom_model_example.rs
|
|
│ │ ├── flow_example.rs
|
|
│ │ ├── governance_activity_example.rs
|
|
│ │ ├── legal_contract_example.rs
|
|
│ │ ├── marketplace_example.rs
|
|
│ │ ├── model_macro_example.rs
|
|
│ │ ├── payment_flow_example.rs
|
|
│ │ ├── simple_model_example.rs
|
|
│ │ ├── test_reminder_functionality.rs
|
|
│ │ └── test_signature_functionality.rs
|
|
│ ├── src
|
|
│ │ ├── db
|
|
│ │ │ ├── fjall.rs
|
|
│ │ │ └── hero.rs
|
|
│ │ ├── herodb
|
|
│ │ │ ├── db.rs
|
|
│ │ │ ├── error.rs
|
|
│ │ │ ├── generic_store.rs
|
|
│ │ │ ├── macros.rs
|
|
│ │ │ ├── mod.rs
|
|
│ │ │ ├── model_methods.rs
|
|
│ │ │ ├── model.rs
|
|
│ │ │ ├── store.rs
|
|
│ │ │ ├── tests.rs
|
|
│ │ │ └── tst_index.rs
|
|
│ │ ├── models
|
|
│ │ │ ├── access
|
|
│ │ │ │ ├── access.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── biz
|
|
│ │ │ │ ├── company.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── payment.rs
|
|
│ │ │ │ ├── product.rs
|
|
│ │ │ │ ├── README.md
|
|
│ │ │ │ ├── sale.rs
|
|
│ │ │ │ └── shareholder.rs
|
|
│ │ │ ├── calendar
|
|
│ │ │ │ ├── calendar.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── circle
|
|
│ │ │ │ ├── circle.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── README.md
|
|
│ │ │ │ └── rhai.rs
|
|
│ │ │ ├── contact
|
|
│ │ │ │ ├── contact.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── core
|
|
│ │ │ │ ├── comment.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── model.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── finance
|
|
│ │ │ │ ├── account.rs
|
|
│ │ │ │ ├── asset.rs
|
|
│ │ │ │ ├── marketplace.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── flow
|
|
│ │ │ │ ├── flow_step.rs
|
|
│ │ │ │ ├── flow.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── README.md
|
|
│ │ │ │ └── signature_requirement.rs
|
|
│ │ │ ├── gov
|
|
│ │ │ │ ├── committee.rs
|
|
│ │ │ │ ├── company.rs
|
|
│ │ │ │ ├── meeting.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── README.md
|
|
│ │ │ │ ├── resolution.rs
|
|
│ │ │ │ ├── shareholder.rs
|
|
│ │ │ │ ├── user.rs
|
|
│ │ │ │ └── vote.rs
|
|
│ │ │ ├── governance
|
|
│ │ │ │ ├── activity.rs
|
|
│ │ │ │ ├── attached_file.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── proposal.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── legal
|
|
│ │ │ │ ├── contract.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── library
|
|
│ │ │ │ ├── collection.rs
|
|
│ │ │ │ ├── items.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── log
|
|
│ │ │ │ ├── log.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── object
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── object.rs
|
|
│ │ │ │ └── README.md
|
|
│ │ │ ├── projects
|
|
│ │ │ │ ├── base.rs
|
|
│ │ │ │ ├── epic.rs
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── README.md
|
|
│ │ │ │ ├── sprint_enums.rs
|
|
│ │ │ │ ├── sprint.rs
|
|
│ │ │ │ ├── task_enums.rs
|
|
│ │ │ │ └── task.rs
|
|
│ │ │ ├── userexample
|
|
│ │ │ │ ├── mod.rs
|
|
│ │ │ │ ├── README.md
|
|
│ │ │ │ └── user.rs
|
|
│ │ │ ├── lib.rs
|
|
│ │ │ └── mod.rs
|
|
│ │ ├── db.rs
|
|
│ │ └── lib.rs
|
|
│ ├── tests
|
|
│ │ └── payment.rs
|
|
│ ├── .gitignore
|
|
│ ├── Cargo.lock
|
|
│ ├── Cargo.toml
|
|
│ ├── README.md
|
|
│ └── run_all_examples.sh
|
|
├── heromodels_core
|
|
│ ├── src
|
|
│ │ ├── base_data_builder.rs
|
|
│ │ └── lib.rs
|
|
│ ├── Cargo.lock
|
|
│ └── Cargo.toml
|
|
├── heromodels-derive
|
|
│ ├── src
|
|
│ │ └── lib.rs
|
|
│ ├── tests
|
|
│ │ └── test_model_macro.rs
|
|
│ ├── Cargo.lock
|
|
│ └── Cargo.toml
|
|
├── ourdb
|
|
│ ├── examples
|
|
│ │ ├── advanced_usage.rs
|
|
│ │ ├── basic_usage.rs
|
|
│ │ ├── benchmark.rs
|
|
│ │ ├── main.rs
|
|
│ │ └── standalone_ourdb_example.rs
|
|
│ ├── src
|
|
│ │ ├── backend.rs
|
|
│ │ ├── error.rs
|
|
│ │ ├── lib.rs
|
|
│ │ ├── location.rs
|
|
│ │ └── lookup.rs
|
|
│ ├── tests
|
|
│ │ └── integration_tests.rs
|
|
│ ├── API.md
|
|
│ ├── architecture.md
|
|
│ ├── Cargo.lock
|
|
│ ├── Cargo.toml
|
|
│ └── README.md
|
|
├── radixtree
|
|
│ ├── benches
|
|
│ │ └── radixtree_benchmarks.rs
|
|
│ ├── examples
|
|
│ │ ├── basic_usage.rs
|
|
│ │ ├── large_scale_test.rs
|
|
│ │ ├── performance_test.rs
|
|
│ │ └── prefix_operations.rs
|
|
│ ├── src
|
|
│ │ ├── error.rs
|
|
│ │ ├── lib.rs
|
|
│ │ ├── node.rs
|
|
│ │ ├── operations.rs
|
|
│ │ └── serialize.rs
|
|
│ ├── tests
|
|
│ │ ├── basic_test.rs
|
|
│ │ ├── getall_test.rs
|
|
│ │ ├── prefix_test.rs
|
|
│ │ └── serialize_test.rs
|
|
│ ├── ARCHITECTURE.md
|
|
│ ├── Cargo.lock
|
|
│ ├── Cargo.toml
|
|
│ ├── MIGRATION.md
|
|
│ └── README.md
|
|
├── rhai_client_example
|
|
│ ├── src
|
|
│ │ └── main.rs
|
|
│ ├── Cargo.lock
|
|
│ └── Cargo.toml
|
|
├── rhai_client_macros
|
|
│ ├── src
|
|
│ │ └── lib.rs
|
|
│ ├── Cargo.lock
|
|
│ └── Cargo.toml
|
|
├── specs
|
|
│ └── models
|
|
│ ├── base
|
|
│ │ └── base.v
|
|
│ ├── biz
|
|
│ │ ├── company.v
|
|
│ │ ├── product.v
|
|
│ │ ├── sale.v
|
|
│ │ ├── shareholder.v
|
|
│ │ └── user.v
|
|
│ ├── circle
|
|
│ │ ├── attachment.v
|
|
│ │ ├── config.v
|
|
│ │ ├── domainnames.v
|
|
│ │ ├── group.v
|
|
│ │ └── user.v
|
|
│ ├── crm
|
|
│ │ ├── account.v
|
|
│ │ ├── call.v
|
|
│ │ ├── campaign.v
|
|
│ │ ├── case.v
|
|
│ │ ├── contact.v
|
|
│ │ ├── lead.v
|
|
│ │ ├── opportunity.v
|
|
│ │ └── task.v
|
|
│ ├── finance
|
|
│ │ ├── account.v
|
|
│ │ ├── asset.v
|
|
│ │ └── marketplace.v
|
|
│ ├── flow
|
|
│ │ └── flow.v
|
|
│ ├── governance
|
|
│ │ └── proposal.v
|
|
│ ├── legal
|
|
│ │ └── contract.v
|
|
│ ├── mcc
|
|
│ │ ├── calendar.v
|
|
│ │ ├── contacts.v
|
|
│ │ ├── message.v
|
|
│ │ └── README.md
|
|
│ ├── projects
|
|
│ │ ├── base.v
|
|
│ │ ├── epic.v
|
|
│ │ ├── issue.v
|
|
│ │ ├── kanban.v
|
|
│ │ ├── sprint.v
|
|
│ │ └── story.v
|
|
│ ├── ticket
|
|
│ │ ├── ticket_comment.v
|
|
│ │ ├── ticket_enums.v
|
|
│ │ └── ticket.v
|
|
│ └── user.v
|
|
├── tst
|
|
│ ├── examples
|
|
│ │ ├── basic_usage.rs
|
|
│ │ ├── performance.rs
|
|
│ │ └── prefix_ops.rs
|
|
│ ├── src
|
|
│ │ ├── error.rs
|
|
│ │ ├── lib.rs
|
|
│ │ ├── node.rs
|
|
│ │ ├── operations.rs
|
|
│ │ └── serialize.rs
|
|
│ ├── tests
|
|
│ │ ├── basic_test.rs
|
|
│ │ └── prefix_test.rs
|
|
│ ├── Cargo.lock
|
|
│ ├── Cargo.toml
|
|
│ └── README.md
|
|
├── .gitignore
|
|
└── rust-toolchain.toml
|
|
|
|
</file_map>
|
|
|
|
<file_contents>
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_curdir_example.md
|
|
|
|
```md
|
|
# Getting the Current Script's Path in Herolib/V Shell
|
|
|
|
can be used in any .v or .vsh script, easy to find content close to the script itself.
|
|
|
|
```v
|
|
#!/usr/bin/env vsh
|
|
|
|
const script_path = os.dir(@FILE) + '/scripts'
|
|
echo "Current scripts directory: ${script_directory}"
|
|
|
|
```
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_globals.md
|
|
```md
|
|
## how to remember clients, installers as a global
|
|
|
|
the following is a good pragmatic way to remember clients, installers as a global, use it as best practice.
|
|
|
|
```vmodule docsite
|
|
|
|
module docsite
|
|
|
|
import incubaid.herolib.core.texttools
|
|
|
|
__global (
|
|
siteconfigs map[string]&SiteConfig
|
|
)
|
|
|
|
@[params]
|
|
pub struct FactoryArgs {
|
|
pub mut:
|
|
name string = "default"
|
|
}
|
|
|
|
pub fn new(args FactoryArgs) !&SiteConfig {
|
|
name := texttools.name_fix(args.name)
|
|
siteconfigs[name] = &SiteConfig{
|
|
name: name
|
|
}
|
|
return get(name:name)!
|
|
}
|
|
|
|
pub fn get(args FactoryArgs) !&SiteConfig {
|
|
name := texttools.name_fix(args.name)
|
|
mut sc := siteconfigs[name] or {
|
|
return error('siteconfig with name "${name}" does not exist')
|
|
}
|
|
return sc
|
|
}
|
|
|
|
pub fn default() !&SiteConfig {
|
|
if siteconfigs.len == 0 {
|
|
return new(name:'default')!
|
|
}
|
|
return get()!
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_heroscript_basics.md
|
|
```md
|
|
# HeroScript: Vlang Integration
|
|
|
|
## HeroScript Structure
|
|
|
|
HeroScript is a concise scripting language with the following structure:
|
|
|
|
```heroscript
|
|
!!actor.action_name
|
|
param1: 'value1'
|
|
param2: 'value with spaces'
|
|
multiline_description: '
|
|
This is a multiline description.
|
|
It can span multiple lines.
|
|
'
|
|
arg1 arg2 // Arguments without keys
|
|
```
|
|
|
|
Key characteristics:
|
|
|
|
- __Actions__: Start with `!!`, followed by `actor.action_name` (e.g., `!!mailclient.configure`).
|
|
- __Parameters__: Defined as `key:value`. Values can be quoted for spaces.
|
|
- __Multiline Support__: Parameters like `description` can span multiple lines.
|
|
- __Arguments__: Values without keys (e.g., `arg1`).
|
|
|
|
## Processing HeroScript in Vlang
|
|
|
|
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters, this is used in most of the herolib modules, it allows configuration or actions in a structured way.
|
|
|
|
```v
|
|
import incubaid.herolib.core.playbook { PlayBook }
|
|
import incubaid.herolib.ui.console
|
|
|
|
pub fn play(mut plbook PlayBook) ! {
|
|
|
|
if plbook.exists_once(filter: 'docusaurus.define') {
|
|
mut action := plbook.get(filter: 'docusaurus.define')!
|
|
mut p := action.params
|
|
//example how we get parameters from the action see core_params.md for more details
|
|
ds = new(
|
|
path: p.get_default('path_publish', '')!
|
|
production: p.get_default_false('production')
|
|
)!
|
|
}
|
|
|
|
// Process 'docusaurus.add' actions to configure individual Docusaurus sites
|
|
actions := plbook.find(filter: 'docusaurus.add')!
|
|
for action in actions {
|
|
mut p := action.params
|
|
//do more processing here
|
|
}
|
|
}
|
|
```
|
|
|
|
For detailed information on parameter retrieval methods (e.g., `p.get()`, `p.get_int()`, `p.get_default_true()`), refer to `aiprompts/ai_core/core_params.md`.
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_heroscript_playbook.md
|
|
```md
|
|
# PlayBook
|
|
|
|
## get & execute a playbook
|
|
|
|
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters.
|
|
|
|
```v
|
|
import incubaid.herolib.core.playbook
|
|
import incubaid.herolib.core.playcmds
|
|
|
|
// path string
|
|
// text string
|
|
// git_url string
|
|
// git_pull bool
|
|
// git_branch string
|
|
// git_reset bool
|
|
// session ?&base.Session is optional
|
|
mut plbook := playbook.new(path: "....")!
|
|
|
|
//now we run all the commands as they are pre-defined in herolib, this will execute the playbook and do all actions.
|
|
playcmds.run(mut plbook)!
|
|
|
|
```
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_http_client.md
|
|
```md
|
|
# HTTPConnection Module
|
|
|
|
The `HTTPConnection` module provides a robust HTTP client for Vlang, supporting JSON, custom headers, retries, and caching.
|
|
|
|
## Key Features
|
|
- Type-safe JSON methods
|
|
- Custom headers
|
|
- Retry mechanism
|
|
- Caching
|
|
- URL encoding
|
|
|
|
## Basic Usage
|
|
|
|
```v
|
|
import incubaid.herolib.core.httpconnection
|
|
|
|
// Create a new HTTP connection
|
|
mut conn := httpconnection.new(
|
|
name: 'my_api_client'
|
|
url: 'https://api.example.com'
|
|
retry: 3 // Number of retries for failed requests
|
|
cache: true // Enable caching
|
|
)!
|
|
```
|
|
|
|
## Integration with Management Classes
|
|
|
|
To integrate `HTTPConnection` into a management class (e.g., `HetznerManager`), use a method to lazily initialize and return the connection:
|
|
|
|
```v
|
|
// Example: HetznerManager
|
|
pub fn (mut h HetznerManager) connection() !&httpconnection.HTTPConnection {
|
|
mut c := h.conn or {
|
|
mut c2 := httpconnection.new(
|
|
name: 'hetzner_${h.name}'
|
|
url: h.baseurl
|
|
cache: true
|
|
retry: 3
|
|
)!
|
|
c2.basic_auth(h.user, h.password)
|
|
c2
|
|
}
|
|
return c
|
|
}
|
|
```
|
|
|
|
## Examples
|
|
|
|
### GET Request with JSON Response
|
|
|
|
```v
|
|
struct User {
|
|
id int
|
|
name string
|
|
email string
|
|
}
|
|
|
|
user := conn.get_json_generic[User](
|
|
prefix: 'users/1'
|
|
)!
|
|
```
|
|
|
|
### POST Request with JSON Data
|
|
|
|
```v
|
|
struct NewUserResponse {
|
|
id int
|
|
status string
|
|
}
|
|
|
|
new_user_resp := conn.post_json_generic[NewUserResponse](
|
|
prefix: 'users'
|
|
params: {
|
|
'name': 'Jane Doe'
|
|
'email': 'jane@example.com'
|
|
}
|
|
)!
|
|
```
|
|
|
|
### Custom Headers
|
|
|
|
Set default headers or add them per request:
|
|
|
|
```v
|
|
import net.http { Header }
|
|
|
|
// Set default header
|
|
conn.default_header = http.new_header(key: .authorization, value: 'Bearer your-token')
|
|
|
|
// Add custom header for a specific request
|
|
response := conn.get_json(
|
|
prefix: 'protected/resource'
|
|
header: http.new_header(key: .content_type, value: 'application/json')
|
|
)!
|
|
```
|
|
|
|
### Error Handling
|
|
|
|
Methods return a `Result` type for error handling:
|
|
|
|
```v
|
|
user := conn.get_json_generic[User](
|
|
prefix: 'users/1'
|
|
) or {
|
|
println('Error fetching user: ${err}')
|
|
return
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_osal.md
|
|
|
|
```md
|
|
# OSAL Core Module - Key Capabilities (incubaid.herolib.osal.core)
|
|
|
|
|
|
```v
|
|
//example how to get started
|
|
|
|
import incubaid.herolib.osal.core as osal
|
|
|
|
osal.exec(cmd:"ls /")!
|
|
|
|
```
|
|
|
|
this document has info about the most core functions, more detailed info can be found in `aiprompts/herolib_advanced/osal.md` if needed.
|
|
|
|
## Key Functions
|
|
|
|
### 1. Process Execution
|
|
|
|
- __`osal.exec(cmd: Command) !Job`__: Execute a shell command.
|
|
- __Key Parameters__: `cmd` (string), `timeout` (int), `retry` (int), `work_folder` (string), `environment` (map[string]string), `stdout` (bool), `raise_error` (bool).
|
|
- __Returns__: `Job` (status, output, error, exit code).
|
|
- __`osal.execute_silent(cmd string) !string`__: Execute silently, return output.
|
|
- __`osal.cmd_exists(cmd string) bool`__: Check if a command exists.
|
|
- __`osal.process_kill_recursive(args: ProcessKillArgs) !`__: Kill a process and its children.
|
|
|
|
### 2. Network Utilities
|
|
|
|
- __`osal.ping(args: PingArgs) !bool`__: Check host reachability.
|
|
- __`osal.tcp_port_test(args: TcpPortTestArgs) bool`__: Test if a TCP port is open.
|
|
- __Key Parameters__: `address` (string), `port` (int).
|
|
- __`osal.ipaddr_pub_get() !string`__: Get public IP address.
|
|
|
|
### 3. File System Operations
|
|
|
|
- __`osal.file_write(path string, text string) !`__: Write text to a file.
|
|
- __`osal.file_read(path string) !string`__: Read content from a file.
|
|
- __`osal.dir_ensure(path string) !`__: Ensure a directory exists.
|
|
- __`osal.rm(todelete string) !`__: Remove files/directories.
|
|
|
|
### 4. Environment Variables
|
|
|
|
- __`osal.env_set(args: EnvSet)`__: Set an environment variable.
|
|
- __Key Parameters__: `key` (string), `value` (string).
|
|
- __`osal.env_get(key string) !string`__: Get an environment variable's value.
|
|
- __`osal.load_env_file(file_path string) !`__: Load variables from a file.
|
|
|
|
### 5. Command & Profile Management
|
|
|
|
- __`osal.cmd_add(args: CmdAddArgs) !`__: Add a binary to system paths and update profiles.
|
|
- __Key Parameters__: `source` (string, required), `cmdname` (string).
|
|
- __`osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`__: Add/remove paths from profiles.
|
|
- __Key Parameters__: `paths2add` (string), `paths2delete` (string).
|
|
|
|
### 6. System Information
|
|
|
|
- __`osal.platform() !PlatformType`__: Identify the operating system.
|
|
- __`osal.cputype() !CPUType`__: Identify the CPU architecture.
|
|
- __`osal.hostname() !string`__: Get system hostname.
|
|
|
|
---
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_ourtime.md
|
|
```md
|
|
# OurTime Module
|
|
|
|
The `OurTime` module in V provides flexible time handling, supporting relative and absolute time formats, Unix timestamps, and formatting utilities.
|
|
|
|
## Key Features
|
|
- Create time objects from strings or current time
|
|
- Relative time expressions (e.g., `+1h`, `-2d`)
|
|
- Absolute time formats (e.g., `YYYY-MM-DD HH:mm:ss`)
|
|
- Unix timestamp conversion
|
|
- Time formatting and warping
|
|
|
|
## Basic Usage
|
|
|
|
```v
|
|
import incubaid.herolib.data.ourtime
|
|
|
|
// Current time
|
|
mut t := ourtime.now()
|
|
|
|
// From string
|
|
t2 := ourtime.new('2022-12-05 20:14:35')!
|
|
|
|
// Get formatted string
|
|
println(t2.str()) // e.g., 2022-12-05 20:14
|
|
|
|
// Get Unix timestamp
|
|
println(t2.unix()) // e.g., 1670271275
|
|
```
|
|
|
|
## Time Formats
|
|
|
|
### Relative Time
|
|
|
|
Use `s` (seconds), `h` (hours), `d` (days), `w` (weeks), `M` (months), `Q` (quarters), `Y` (years).
|
|
|
|
```v
|
|
// Create with relative time
|
|
mut t := ourtime.new('+1w +2d -4h')!
|
|
|
|
// Warp existing time
|
|
mut t2 := ourtime.now()
|
|
t2.warp('+1h')!
|
|
```
|
|
|
|
### Absolute Time
|
|
|
|
Supports `YYYY-MM-DD HH:mm:ss`, `YYYY-MM-DD HH:mm`, `YYYY-MM-DD HH`, `YYYY-MM-DD`, `DD-MM-YYYY`.
|
|
|
|
```v
|
|
t1 := ourtime.new('2022-12-05 20:14:35')!
|
|
t2 := ourtime.new('2022-12-05')! // Time defaults to 00:00:00
|
|
```
|
|
|
|
## Methods Overview
|
|
|
|
### Creation
|
|
|
|
```v
|
|
now_time := ourtime.now()
|
|
from_string := ourtime.new('2023-01-15')!
|
|
from_epoch := ourtime.new_from_epoch(1673788800)
|
|
```
|
|
|
|
### Formatting
|
|
|
|
```v
|
|
mut t := ourtime.now()
|
|
println(t.str()) // YYYY-MM-DD HH:mm
|
|
println(t.day()) // YYYY-MM-DD
|
|
println(t.key()) // YYYY_MM_DD_HH_mm_ss
|
|
println(t.md()) // Markdown format
|
|
```
|
|
|
|
### Operations
|
|
|
|
```v
|
|
mut t := ourtime.now()
|
|
t.warp('+1h')! // Move 1 hour forward
|
|
unix_ts := t.unix()
|
|
is_empty := t.empty()
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
Time parsing methods return a `Result` type and should be handled with `!` or `or` blocks.
|
|
|
|
```v
|
|
t_valid := ourtime.new('2023-01-01')!
|
|
t_invalid := ourtime.new('bad-date') or {
|
|
println('Error: ${err}')
|
|
ourtime.now() // Fallback
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_params.md
|
|
|
|
```md
|
|
# Parameter Parsing in Vlang
|
|
|
|
This document details the `paramsparser` module, essential for handling parameters in HeroScript and other contexts.
|
|
|
|
## Obtaining a `paramsparser` Instance
|
|
|
|
```v
|
|
import incubaid.herolib.data.paramsparser
|
|
|
|
// Create new params from a string
|
|
params := paramsparser.new("color:red size:'large' priority:1 enable:true")!
|
|
|
|
// Or create an empty instance and add parameters programmatically
|
|
mut params := paramsparser.new_params()
|
|
params.set("color", "red")
|
|
```
|
|
|
|
## Parameter Formats
|
|
|
|
The parser supports various input formats:
|
|
|
|
1. __Key-value pairs__: `key:value`
|
|
2. __Quoted values__: `key:'value with spaces'` (single or double quotes)
|
|
3. __Arguments without keys__: `arg1 arg2` (accessed by index)
|
|
4. __Comments__: `// this is a comment` (ignored during parsing)
|
|
|
|
Example:
|
|
|
|
```v
|
|
text := "name:'John Doe' age:30 active:true // user details"
|
|
params := paramsparser.new(text)!
|
|
```
|
|
|
|
## Parameter Retrieval Methods
|
|
|
|
The `paramsparser` module provides a comprehensive set of methods for retrieving and converting parameter values.
|
|
|
|
### Basic Retrieval
|
|
|
|
- `get(key string) !string`: Retrieves a string value by key. Returns an error if the key does not exist.
|
|
- `get_default(key string, defval string) !string`: Retrieves a string value by key, or returns `defval` if the key is not found.
|
|
- `exists(key string) bool`: Checks if a keyword argument (`key:value`) exists.
|
|
- `exists_arg(key string) bool`: Checks if an argument (value without a key) exists.
|
|
|
|
### Argument Retrieval (Positional)
|
|
|
|
- `get_arg(nr int) !string`: Retrieves an argument by its 0-based index. Returns an error if the index is out of bounds.
|
|
- `get_arg_default(nr int, defval string) !string`: Retrieves an argument by index, or returns `defval` if the index is out of bounds.
|
|
|
|
### Type-Specific Retrieval
|
|
|
|
- `get_int(key string) !int`: Converts and retrieves an integer (int32).
|
|
- `get_int_default(key string, defval int) !int`: Retrieves an integer with a default.
|
|
- `get_u32(key string) !u32`: Converts and retrieves an unsigned 32-bit integer.
|
|
- `get_u32_default(key string, defval u32) !u32`: Retrieves a u32 with a default.
|
|
- `get_u64(key string) !u64`: Converts and retrieves an unsigned 64-bit integer.
|
|
- `get_u64_default(key string, defval u64) !u64`: Retrieves a u64 with a default.
|
|
- `get_u8(key string) !u8`: Converts and retrieves an unsigned 8-bit integer.
|
|
- `get_u8_default(key string, defval u8) !u8`: Retrieves a u8 with a default.
|
|
- `get_float(key string) !f64`: Converts and retrieves a 64-bit float.
|
|
- `get_float_default(key string, defval f64) !f64`: Retrieves a float with a default.
|
|
- `get_percentage(key string) !f64`: Converts a percentage string (e.g., "80%") to a float (0.8).
|
|
- `get_percentage_default(key string, defval string) !f64`: Retrieves a percentage with a default.
|
|
|
|
### Boolean Retrieval
|
|
|
|
- `get_default_true(key string) bool`: Returns `true` if the value is empty, "1", "true", "y", or "yes". Otherwise `false`.
|
|
- `get_default_false(key string) bool`: Returns `false` if the value is empty, "0", "false", "n", or "no". Otherwise `true`.
|
|
|
|
### List Retrieval
|
|
|
|
Lists are typically comma-separated strings (e.g., `users: "john,jane,bob"`).
|
|
|
|
- `get_list(key string) ![]string`: Retrieves a list of strings.
|
|
- `get_list_default(key string, def []string) ![]string`: Retrieves a list of strings with a default.
|
|
- `get_list_int(key string) ![]int`: Retrieves a list of integers.
|
|
- `get_list_int_default(key string, def []int) []int`: Retrieves a list of integers with a default.
|
|
- `get_list_f32(key string) ![]f32`: Retrieves a list of 32-bit floats.
|
|
- `get_list_f32_default(key string, def []f32) []f32`: Retrieves a list of f32 with a default.
|
|
- `get_list_f64(key string) ![]f64`: Retrieves a list of 64-bit floats.
|
|
- `get_list_f64_default(key string, def []f64) []f64`: Retrieves a list of f64 with a default.
|
|
- `get_list_i8(key string) ![]i8`: Retrieves a list of 8-bit signed integers.
|
|
- `get_list_i8_default(key string, def []i8) []i8`: Retrieves a list of i8 with a default.
|
|
- `get_list_i16(key string) ![]i16`: Retrieves a list of 16-bit signed integers.
|
|
- `get_list_i16_default(key string, def []i16) []i16`: Retrieves a list of i16 with a default.
|
|
- `get_list_i64(key string) ![]i64`: Retrieves a list of 64-bit signed integers.
|
|
- `get_list_i64_default(key string, def []i64) []i64`: Retrieves a list of i64 with a default.
|
|
- `get_list_u16(key string) ![]u16`: Retrieves a list of 16-bit unsigned integers.
|
|
- `get_list_u16_default(key string, def []u16) []u16`: Retrieves a list of u16 with a default.
|
|
- `get_list_u32(key string) ![]u32`: Retrieves a list of 32-bit unsigned integers.
|
|
- `get_list_u32_default(key string, def []u32) []u32`: Retrieves a list of u32 with a default.
|
|
- `get_list_u64(key string) ![]u64`: Retrieves a list of 64-bit unsigned integers.
|
|
- `get_list_u64_default(key string, def []u64) []u64`: Retrieves a list of u64 with a default.
|
|
- `get_list_namefix(key string) ![]string`: Retrieves a list of strings, normalizing each item (e.g., "My Name" -> "my_name").
|
|
- `get_list_namefix_default(key string, def []string) ![]string`: Retrieves a list of name-fixed strings with a default.
|
|
|
|
### Specialized Retrieval
|
|
|
|
- `get_map() map[string]string`: Returns all parameters as a map.
|
|
- `get_path(key string) !string`: Retrieves a path string.
|
|
- `get_path_create(key string) !string`: Retrieves a path string, creating the directory if it doesn't exist.
|
|
- `get_from_hashmap(key string, defval string, hashmap map[string]string) !string`: Retrieves a value from a provided hashmap based on the parameter's value.
|
|
- `get_storagecapacity_in_bytes(key string) !u64`: Converts storage capacity strings (e.g., "10 GB", "500 MB") to bytes (u64).
|
|
- `get_storagecapacity_in_bytes_default(key string, defval u64) !u64`: Retrieves storage capacity in bytes with a default.
|
|
- `get_storagecapacity_in_gigabytes(key string) !u64`: Converts storage capacity strings to gigabytes (u64).
|
|
- `get_time(key string) !ourtime.OurTime`: Parses a time string (relative or absolute) into an `ourtime.OurTime` object.
|
|
- `get_time_default(key string, defval ourtime.OurTime) !ourtime.OurTime`: Retrieves time with a default.
|
|
- `get_time_interval(key string) !Duration`: Parses a time interval string into a `Duration` object.
|
|
- `get_timestamp(key string) !Duration`: Parses a timestamp string into a `Duration` object.
|
|
- `get_timestamp_default(key string, defval Duration) !Duration`: Retrieves a timestamp with a default.
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_paths.md
|
|
```md
|
|
# Pathlib Usage Guide
|
|
|
|
## Overview
|
|
|
|
The pathlib module provides a comprehensive interface for handling file system operations. Key features include:
|
|
|
|
- Robust path handling for files, directories, and symlinks
|
|
- Support for both absolute and relative paths
|
|
- Automatic home directory expansion (~)
|
|
- Recursive directory operations
|
|
- Path filtering and listing
|
|
- File and directory metadata access
|
|
|
|
## Basic Usage
|
|
|
|
### Importing pathlib
|
|
```v
|
|
import incubaid.herolib.core.pathlib
|
|
```
|
|
|
|
### Creating Path Objects
|
|
|
|
```v
|
|
// Create a Path object for a file
|
|
mut file_path := pathlib.get("path/to/file.txt")
|
|
|
|
// Create a Path object for a directory
|
|
mut dir_path := pathlib.get("path/to/directory")
|
|
```
|
|
|
|
### Basic Path Operations
|
|
|
|
```v
|
|
// Get absolute path
|
|
abs_path := file_path.absolute()
|
|
|
|
// Get real path (resolves symlinks)
|
|
real_path := file_path.realpath()
|
|
|
|
// Check if path exists
|
|
if file_path.exists() {
|
|
// Path exists
|
|
}
|
|
```
|
|
|
|
## Path Properties and Methods
|
|
|
|
### Path Types
|
|
|
|
```v
|
|
// Check if path is a file
|
|
if file_path.is_file() {
|
|
// Handle as file
|
|
}
|
|
|
|
// Check if path is a directory
|
|
if dir_path.is_dir() {
|
|
// Handle as directory
|
|
}
|
|
|
|
// Check if path is a symlink
|
|
if file_path.is_link() {
|
|
// Handle as symlink
|
|
}
|
|
```
|
|
|
|
### Path Normalization
|
|
|
|
```v
|
|
// Normalize path (remove extra slashes, resolve . and ..)
|
|
normalized_path := file_path.path_normalize()
|
|
|
|
// Get path directory
|
|
dir_path := file_path.path_dir()
|
|
|
|
// Get path name without extension
|
|
name_no_ext := file_path.name_no_ext()
|
|
```
|
|
|
|
## File and Directory Operations
|
|
|
|
### File Operations
|
|
|
|
```v
|
|
// Write to file
|
|
file_path.write("Content to write")!
|
|
|
|
// Read from file
|
|
content := file_path.read()!
|
|
|
|
// Delete file
|
|
file_path.delete()!
|
|
```
|
|
|
|
### Directory Operations
|
|
|
|
```v
|
|
// Create directory
|
|
mut dir := pathlib.get_dir(
|
|
path: "path/to/new/dir"
|
|
create: true
|
|
)!
|
|
|
|
// List directory contents
|
|
mut dir_list := dir.list()!
|
|
|
|
// Delete directory
|
|
dir.delete()!
|
|
```
|
|
|
|
### Symlink Operations
|
|
|
|
```v
|
|
// Create symlink
|
|
file_path.link("path/to/symlink", delete_exists: true)!
|
|
|
|
// Resolve symlink
|
|
real_path := file_path.realpath()
|
|
```
|
|
|
|
## Advanced Operations
|
|
|
|
### Path Copying
|
|
|
|
```v
|
|
// Copy file to destination
|
|
file_path.copy(dest: "path/to/destination")!
|
|
```
|
|
|
|
### Recursive Operations
|
|
|
|
```v
|
|
// List directory recursively
|
|
mut recursive_list := dir.list(recursive: true)!
|
|
|
|
// Delete directory recursively
|
|
dir.delete()!
|
|
```
|
|
|
|
### Path Filtering
|
|
|
|
```v
|
|
// List files matching pattern
|
|
mut filtered_list := dir.list(
|
|
regex: [r".*\.txt$"],
|
|
recursive: true
|
|
)!
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### Error Handling
|
|
|
|
```v
|
|
if file_path.exists() {
|
|
// Safe to operate
|
|
} else {
|
|
// Handle missing file
|
|
}
|
|
```
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_text.md
|
|
```md
|
|
# TextTools Module
|
|
|
|
The `texttools` module provides a comprehensive set of utilities for text manipulation and processing.
|
|
|
|
## Functions and Examples:
|
|
|
|
```v
|
|
import incubaid.herolib.core.texttools
|
|
|
|
assert hello_world == texttools.name_fix("Hello World!")
|
|
|
|
```
|
|
|
|
### Name/Path Processing
|
|
|
|
* `name_fix(name string) string`: Normalizes filenames and paths.
|
|
- `name_fix_keepspace(name string) !string`: Like name_fix but preserves spaces.
|
|
- `name_fix_no_ext(name_ string) string`: Removes file extension.
|
|
- `name_fix_snake_to_pascal(name string) string`: Converts snake_case to PascalCase.
|
|
|
|
```v
|
|
name := texttools.name_fix_snake_to_pascal("hello_world") // Result: "HelloWorld"
|
|
```
|
|
|
|
* `snake_case(name string) string`: Converts PascalCase to snake_case.
|
|
|
|
```v
|
|
name := texttools.snake_case("HelloWorld") // Result: "hello_world"
|
|
```
|
|
|
|
* `name_split(name string) !(string, string)`: Splits name into site and page components.
|
|
|
|
### Text Cleaning
|
|
|
|
* `name_clean(r string) string`: Normalizes names by removing special characters.
|
|
|
|
```v
|
|
name := texttools.name_clean("Hello@World!") // Result: "HelloWorld"
|
|
```
|
|
|
|
* `ascii_clean(r string) string`: Removes all non-ASCII characters.
|
|
- `remove_empty_lines(text string) string`: Removes empty lines from text.
|
|
|
|
```v
|
|
text := texttools.remove_empty_lines("line1\n\nline2\n\n\nline3") // Result: "line1\nline2\nline3"
|
|
```
|
|
|
|
* `remove_double_lines(text string) string`: Removes consecutive empty lines.
|
|
- `remove_empty_js_blocks(text string) string`: Removes empty code blocks (```...```).
|
|
|
|
### Command Line Parsing
|
|
|
|
* `cmd_line_args_parser(text string) ![]string`: Parses command line arguments with support for quotes and escaping.
|
|
|
|
```v
|
|
args := texttools.cmd_line_args_parser("'arg with spaces' --flag=value") // Result: ['arg with spaces', '--flag=value']
|
|
```
|
|
|
|
* `text_remove_quotes(text string) string`: Removes quoted sections from text.
|
|
- `check_exists_outside_quotes(text string, items []string) bool`: Checks if items exist in text outside of quotes.
|
|
|
|
### Text Expansion
|
|
|
|
* `expand(txt_ string, l int, expand_with string) string`: Expands text to a specified length with a given character.
|
|
|
|
### Indentation
|
|
|
|
* `indent(text string, prefix string) string`: Adds indentation prefix to each line.
|
|
|
|
```v
|
|
text := texttools.indent("line1\nline2", " ") // Result: " line1\n line2\n"
|
|
```
|
|
|
|
* `dedent(text string) string`: Removes common leading whitespace from every line.
|
|
|
|
```v
|
|
text := texttools.dedent(" line1\n line2") // Result: "line1\nline2"
|
|
```
|
|
|
|
### String Validation
|
|
|
|
* `is_int(text string) bool`: Checks if text contains only digits.
|
|
- `is_upper_text(text string) bool`: Checks if text contains only uppercase letters.
|
|
|
|
### Multiline Processing
|
|
|
|
* `multiline_to_single(text string) !string`: Converts multiline text to a single line with proper escaping.
|
|
|
|
### Text Splitting
|
|
|
|
* `split_smart(t string, delimiter_ string) []string`: Intelligent string splitting that respects quotes.
|
|
|
|
### Tokenization
|
|
|
|
* `tokenize(text_ string) TokenizerResult`: Tokenizes text into meaningful parts.
|
|
- `text_token_replace(text string, tofind string, replacewith string) !string`: Replaces tokens in text.
|
|
|
|
### Version Parsing
|
|
|
|
* `version(text_ string) int`: Converts version strings to comparable integers.
|
|
|
|
```v
|
|
ver := texttools.version("v0.4.36") // Result: 4036
|
|
ver = texttools.version("v1.4.36") // Result: 1004036
|
|
```
|
|
|
|
### Formatting
|
|
|
|
* `format_rfc1123(t time.Time) string`: Formats a time.Time object into RFC 1123 format.
|
|
|
|
### Array Operations
|
|
|
|
* `to_array(r string) []string`: Converts a comma or newline separated list to an array of strings.
|
|
|
|
```v
|
|
text := "item1,item2,item3"
|
|
array := texttools.to_array(text) // Result: ['item1', 'item2', 'item3']
|
|
```
|
|
|
|
* `to_array_int(r string) []int`: Converts a text list to an array of integers.
|
|
- `to_map(mapstring string, line string, delimiter_ string) map[string]string`: Intelligent mapping of a line to a map based on a template.
|
|
|
|
```v
|
|
r := texttools.to_map("name,-,-,-,-,pid,-,-,-,-,path",
|
|
"root 304 0.0 0.0 408185328 1360 ?? S 16Dec23 0:34.06 /usr/sbin/distnoted")
|
|
// Result: {'name': 'root', 'pid': '1360', 'path': '/usr/sbin/distnoted'}
|
|
```
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_ui_console.md
|
|
```md
|
|
# module ui.console
|
|
|
|
has mechanisms to print better to console, see the methods below
|
|
|
|
import as
|
|
|
|
```v
|
|
import incubaid.herolib.ui.console
|
|
|
|
```
|
|
|
|
## Methods
|
|
|
|
````v
|
|
|
|
fn clear()
|
|
//reset the console screen
|
|
|
|
fn color_bg(c BackgroundColor) string
|
|
// will give ansi codes to change background color . dont forget to call reset to change back to normal
|
|
|
|
fn color_fg(c ForegroundColor) string
|
|
// will give ansi codes to change foreground color . don't forget to call reset to change back to normal
|
|
|
|
struct PrintArgs {
|
|
pub mut:
|
|
foreground ForegroundColor
|
|
background BackgroundColor
|
|
text string
|
|
style Style
|
|
reset_before bool = true
|
|
reset_after bool = true
|
|
}
|
|
|
|
fn cprint(args PrintArgs)
|
|
// print with colors, reset...
|
|
// ```
|
|
// foreground ForegroundColor
|
|
// background BackgroundColor
|
|
// text string
|
|
// style Style
|
|
// reset_before bool = true
|
|
// reset_after bool = true
|
|
// ```
|
|
|
|
fn cprintln(args_ PrintArgs)
|
|
|
|
fn expand(txt_ string, l int, with string) string
|
|
// expand text till length l, with string which is normally ' '
|
|
|
|
fn lf()
|
|
line feed
|
|
|
|
fn new() UIConsole
|
|
|
|
fn print_array(arr [][]string, delimiter string, sort bool)
|
|
// print 2 dimensional array, delimeter is between columns
|
|
|
|
fn print_debug(i IPrintable)
|
|
|
|
fn print_debug_title(title string, txt string)
|
|
|
|
fn print_green(txt string)
|
|
|
|
fn print_header(txt string)
|
|
|
|
fn print_item(txt string)
|
|
|
|
fn print_lf(nr int)
|
|
|
|
fn print_stderr(txt string)
|
|
|
|
fn print_stdout(txt string)
|
|
|
|
fn reset() string
|
|
|
|
fn silent_get() bool
|
|
|
|
fn silent_set()
|
|
|
|
fn silent_unset()
|
|
|
|
fn style(c Style) string
|
|
// will give ansi codes to change style . don't forget to call reset to change back to normal
|
|
|
|
fn trim(c_ string) string
|
|
|
|
````
|
|
|
|
## Console Object
|
|
|
|
Is used to ask feedback to users
|
|
|
|
```v
|
|
|
|
struct UIConsole {
|
|
pub mut:
|
|
x_max int = 80
|
|
y_max int = 60
|
|
prev_lf bool
|
|
prev_title bool
|
|
prev_item bool
|
|
}
|
|
|
|
//DropDownArgs:
|
|
// - description string
|
|
// - items []string
|
|
// - warning string
|
|
// - clear bool = true
|
|
|
|
|
|
fn (mut c UIConsole) ask_dropdown_int(args_ DropDownArgs) !int
|
|
// return the dropdown as an int
|
|
|
|
fn (mut c UIConsole) ask_dropdown_multiple(args_ DropDownArgs) ![]string
|
|
// result can be multiple, aloso can select all description string items []string warning string clear bool = true
|
|
|
|
fn (mut c UIConsole) ask_dropdown(args DropDownArgs) !string
|
|
// will return the string as given as response description
|
|
|
|
// QuestionArgs:
|
|
// - description string
|
|
// - question string
|
|
// - warning: string (if it goes wrong, which message to use)
|
|
// - reset bool = true
|
|
// - regex: to check what result need to be part of
|
|
// - minlen: min nr of chars
|
|
|
|
fn (mut c UIConsole) ask_question(args QuestionArgs) !string
|
|
|
|
fn (mut c UIConsole) ask_time(args QuestionArgs) !string
|
|
|
|
fn (mut c UIConsole) ask_date(args QuestionArgs) !string
|
|
|
|
fn (mut c UIConsole) ask_yesno(args YesNoArgs) !bool
|
|
// yes is true, no is false
|
|
// args:
|
|
// - description string
|
|
// - question string
|
|
// - warning string
|
|
// - clear bool = true
|
|
|
|
fn (mut c UIConsole) reset()
|
|
|
|
fn (mut c UIConsole) status() string
|
|
|
|
```
|
|
|
|
## enums
|
|
|
|
```v
|
|
enum BackgroundColor {
|
|
default_color = 49 // 'default' is a reserved keyword in V
|
|
black = 40
|
|
red = 41
|
|
green = 42
|
|
yellow = 43
|
|
blue = 44
|
|
magenta = 45
|
|
cyan = 46
|
|
light_gray = 47
|
|
dark_gray = 100
|
|
light_red = 101
|
|
light_green = 102
|
|
light_yellow = 103
|
|
light_blue = 104
|
|
light_magenta = 105
|
|
light_cyan = 106
|
|
white = 107
|
|
}
|
|
enum ForegroundColor {
|
|
default_color = 39 // 'default' is a reserved keyword in V
|
|
white = 97
|
|
black = 30
|
|
red = 31
|
|
green = 32
|
|
yellow = 33
|
|
blue = 34
|
|
magenta = 35
|
|
cyan = 36
|
|
light_gray = 37
|
|
dark_gray = 90
|
|
light_red = 91
|
|
light_green = 92
|
|
light_yellow = 93
|
|
light_blue = 94
|
|
light_magenta = 95
|
|
light_cyan = 96
|
|
}
|
|
enum Style {
|
|
normal = 99
|
|
bold = 1
|
|
dim = 2
|
|
underline = 4
|
|
blink = 5
|
|
reverse = 7
|
|
hidden = 8
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_vshell.md
|
|
```md
|
|
# how to run the vshell example scripts
|
|
|
|
this is how we want example scripts to be, see the first line
|
|
|
|
```v
|
|
#!/usr/bin/env -S v -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
|
|
|
import incubaid.herolib...
|
|
|
|
```
|
|
|
|
the files are in ~/code/github/incubaid/herolib/examples for herolib
|
|
|
|
## important instructions
|
|
|
|
- never use fn main() in a .vsh script
|
|
- always use the top line as in example above
|
|
- these scripts can be executed as is but can also use vrun $pathOfFile
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/git.threefold.info/herocode/db/heromodels/src/models/biz/company.rs
|
|
```rs
|
|
use heromodels_core::BaseModelDataOps;
|
|
use heromodels_core::{BaseModelData, Index};
|
|
use heromodels_derive::model;
|
|
use rhai::{CustomType, EvalAltResult, Position, TypeBuilder}; // For #[derive(CustomType)]
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
// --- Enums ---
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum CompanyStatus {
|
|
PendingPayment, // Company created but payment not completed
|
|
Active, // Payment completed, company is active
|
|
Suspended, // Company suspended (e.g., payment issues)
|
|
Inactive, // Company deactivated
|
|
}
|
|
|
|
impl Default for CompanyStatus {
|
|
fn default() -> Self {
|
|
CompanyStatus::PendingPayment
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum BusinessType {
|
|
Coop,
|
|
Single,
|
|
Twin,
|
|
Starter,
|
|
Global,
|
|
}
|
|
|
|
impl Default for BusinessType {
|
|
fn default() -> Self {
|
|
BusinessType::Single
|
|
}
|
|
}
|
|
|
|
impl BusinessType {
|
|
pub fn to_string(&self) -> String {
|
|
format!("{:?}", self)
|
|
}
|
|
|
|
pub fn from_string(s: &str) -> Result<Self, Box<EvalAltResult>> {
|
|
match s.to_lowercase().as_str() {
|
|
"coop" => Ok(BusinessType::Coop),
|
|
"single" => Ok(BusinessType::Single),
|
|
"twin" => Ok(BusinessType::Twin),
|
|
"starter" => Ok(BusinessType::Starter),
|
|
"global" => Ok(BusinessType::Global),
|
|
_ => Err(Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Invalid business type: {}", s).into(),
|
|
Position::NONE,
|
|
))),
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- Company Struct ---
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, CustomType, Default)] // Added CustomType
|
|
#[model]
|
|
pub struct Company {
|
|
pub base_data: BaseModelData,
|
|
pub name: String,
|
|
pub registration_number: String,
|
|
pub incorporation_date: i64, // Changed to i64 // Timestamp
|
|
pub fiscal_year_end: String, // e.g., "MM-DD"
|
|
pub email: String,
|
|
pub phone: String,
|
|
pub website: String,
|
|
pub address: String,
|
|
pub business_type: BusinessType,
|
|
pub industry: String,
|
|
pub description: String,
|
|
pub status: CompanyStatus,
|
|
}
|
|
|
|
// --- Index Implementations (Example) ---
|
|
|
|
pub struct CompanyNameIndex;
|
|
impl Index for CompanyNameIndex {
|
|
type Model = Company;
|
|
type Key = str;
|
|
fn key() -> &'static str {
|
|
"name"
|
|
}
|
|
}
|
|
|
|
pub struct CompanyRegistrationNumberIndex;
|
|
impl Index for CompanyRegistrationNumberIndex {
|
|
type Model = Company;
|
|
type Key = str;
|
|
fn key() -> &'static str {
|
|
"registration_number"
|
|
}
|
|
}
|
|
|
|
// --- Builder Pattern ---
|
|
|
|
impl BaseModelDataOps for Company {
|
|
fn get_base_data_mut(&mut self) -> &mut BaseModelData {
|
|
&mut self.base_data
|
|
}
|
|
}
|
|
|
|
impl Company {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
base_data: BaseModelData::new(),
|
|
name: String::new(),
|
|
registration_number: String::new(),
|
|
incorporation_date: 0,
|
|
fiscal_year_end: String::new(),
|
|
email: String::new(),
|
|
phone: String::new(),
|
|
website: String::new(),
|
|
address: String::new(),
|
|
business_type: BusinessType::default(),
|
|
industry: String::new(),
|
|
description: String::new(),
|
|
status: CompanyStatus::default(),
|
|
}
|
|
}
|
|
|
|
pub fn name(mut self, name: impl ToString) -> Self {
|
|
self.name = name.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn registration_number(mut self, registration_number: impl ToString) -> Self {
|
|
self.registration_number = registration_number.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn incorporation_date(mut self, incorporation_date: i64) -> Self {
|
|
self.incorporation_date = incorporation_date;
|
|
self
|
|
}
|
|
|
|
pub fn fiscal_year_end(mut self, fiscal_year_end: impl ToString) -> Self {
|
|
self.fiscal_year_end = fiscal_year_end.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn email(mut self, email: impl ToString) -> Self {
|
|
self.email = email.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn phone(mut self, phone: impl ToString) -> Self {
|
|
self.phone = phone.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn website(mut self, website: impl ToString) -> Self {
|
|
self.website = website.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn address(mut self, address: impl ToString) -> Self {
|
|
self.address = address.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn business_type(mut self, business_type: BusinessType) -> Self {
|
|
self.business_type = business_type;
|
|
self
|
|
}
|
|
|
|
pub fn industry(mut self, industry: impl ToString) -> Self {
|
|
self.industry = industry.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn description(mut self, description: impl ToString) -> Self {
|
|
self.description = description.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn status(mut self, status: CompanyStatus) -> Self {
|
|
self.status = status;
|
|
self
|
|
}
|
|
|
|
// Base data operations are now handled by BaseModelDataOps trait
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/git.threefold.info/herocode/db/heromodels/src/models/biz/mod.rs
|
|
|
|
```rs
|
|
// Business models module
|
|
// Sub-modules will be declared here
|
|
|
|
pub mod company;
|
|
pub mod payment;
|
|
pub mod product;
|
|
// pub mod sale;
|
|
// pub mod shareholder;
|
|
// pub mod user;
|
|
|
|
// Re-export main types from sub-modules
|
|
pub use company::{BusinessType, Company, CompanyStatus};
|
|
pub use payment::{Payment, PaymentStatus};
|
|
pub mod shareholder;
|
|
pub use product::{Product, ProductComponent, ProductStatus, ProductType};
|
|
pub use shareholder::{Shareholder, ShareholderType};
|
|
|
|
pub mod sale;
|
|
pub use sale::{Sale, SaleItem, SaleStatus};
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/git.threefold.info/herocode/db/heromodels/src/models/biz/payment.rs
|
|
|
|
```rs
|
|
use heromodels_core::BaseModelData;
|
|
use heromodels_derive::model;
|
|
use rhai::{CustomType, TypeBuilder};
|
|
use serde::{Deserialize, Serialize}; // For #[derive(CustomType)]
|
|
|
|
// --- Enums ---
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum PaymentStatus {
|
|
Pending,
|
|
Processing,
|
|
Completed,
|
|
Failed,
|
|
Refunded,
|
|
}
|
|
|
|
impl std::fmt::Display for PaymentStatus {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
PaymentStatus::Pending => write!(f, "Pending"),
|
|
PaymentStatus::Processing => write!(f, "Processing"),
|
|
PaymentStatus::Completed => write!(f, "Completed"),
|
|
PaymentStatus::Failed => write!(f, "Failed"),
|
|
PaymentStatus::Refunded => write!(f, "Refunded"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for PaymentStatus {
|
|
fn default() -> Self {
|
|
PaymentStatus::Pending
|
|
}
|
|
}
|
|
|
|
// --- Payment Struct ---
|
|
#[model]
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
|
pub struct Payment {
|
|
pub base_data: BaseModelData,
|
|
|
|
// Stripe payment intent ID for tracking
|
|
#[index]
|
|
pub payment_intent_id: String,
|
|
|
|
// Reference to the company this payment is for
|
|
#[index]
|
|
pub company_id: u32,
|
|
|
|
// Payment plan details
|
|
pub payment_plan: String, // "monthly", "yearly", "two_year"
|
|
pub setup_fee: f64,
|
|
pub monthly_fee: f64,
|
|
pub total_amount: f64,
|
|
pub currency: String, // "usd"
|
|
|
|
pub status: PaymentStatus,
|
|
pub stripe_customer_id: Option<String>,
|
|
pub created_at: i64, // Timestamp
|
|
pub completed_at: Option<i64>, // Completion timestamp
|
|
}
|
|
|
|
// Model trait implementation is automatically generated by #[model] attribute
|
|
|
|
// --- Builder Pattern ---
|
|
|
|
impl Payment {
|
|
pub fn new(
|
|
payment_intent_id: String,
|
|
company_id: u32,
|
|
payment_plan: String,
|
|
setup_fee: f64,
|
|
monthly_fee: f64,
|
|
total_amount: f64,
|
|
) -> Self {
|
|
let now = chrono::Utc::now().timestamp();
|
|
Self {
|
|
base_data: BaseModelData::new(),
|
|
payment_intent_id,
|
|
company_id,
|
|
payment_plan,
|
|
setup_fee,
|
|
monthly_fee,
|
|
total_amount,
|
|
currency: "usd".to_string(), // Default to USD
|
|
status: PaymentStatus::default(),
|
|
stripe_customer_id: None,
|
|
created_at: now,
|
|
completed_at: None,
|
|
}
|
|
}
|
|
|
|
pub fn payment_intent_id(mut self, payment_intent_id: String) -> Self {
|
|
self.payment_intent_id = payment_intent_id;
|
|
self
|
|
}
|
|
|
|
pub fn company_id(mut self, company_id: u32) -> Self {
|
|
self.company_id = company_id;
|
|
self
|
|
}
|
|
|
|
pub fn payment_plan(mut self, payment_plan: String) -> Self {
|
|
self.payment_plan = payment_plan;
|
|
self
|
|
}
|
|
|
|
pub fn setup_fee(mut self, setup_fee: f64) -> Self {
|
|
self.setup_fee = setup_fee;
|
|
self
|
|
}
|
|
|
|
pub fn monthly_fee(mut self, monthly_fee: f64) -> Self {
|
|
self.monthly_fee = monthly_fee;
|
|
self
|
|
}
|
|
|
|
pub fn total_amount(mut self, total_amount: f64) -> Self {
|
|
self.total_amount = total_amount;
|
|
self
|
|
}
|
|
|
|
pub fn status(mut self, status: PaymentStatus) -> Self {
|
|
self.status = status;
|
|
self
|
|
}
|
|
|
|
pub fn stripe_customer_id(mut self, stripe_customer_id: Option<String>) -> Self {
|
|
self.stripe_customer_id = stripe_customer_id;
|
|
self
|
|
}
|
|
|
|
pub fn currency(mut self, currency: String) -> Self {
|
|
self.currency = currency;
|
|
self
|
|
}
|
|
|
|
pub fn created_at(mut self, created_at: i64) -> Self {
|
|
self.created_at = created_at;
|
|
self
|
|
}
|
|
|
|
pub fn completed_at(mut self, completed_at: Option<i64>) -> Self {
|
|
self.completed_at = completed_at;
|
|
self
|
|
}
|
|
|
|
// --- Business Logic Methods ---
|
|
|
|
/// Complete the payment with optional Stripe customer ID
|
|
pub fn complete_payment(mut self, stripe_customer_id: Option<String>) -> Self {
|
|
self.status = PaymentStatus::Completed;
|
|
self.stripe_customer_id = stripe_customer_id;
|
|
self.completed_at = Some(chrono::Utc::now().timestamp());
|
|
self.base_data.update_modified();
|
|
self
|
|
}
|
|
|
|
/// Mark payment as processing
|
|
pub fn process_payment(mut self) -> Self {
|
|
self.status = PaymentStatus::Processing;
|
|
self.base_data.update_modified();
|
|
self
|
|
}
|
|
|
|
/// Mark payment as failed
|
|
pub fn fail_payment(mut self) -> Self {
|
|
self.status = PaymentStatus::Failed;
|
|
self.base_data.update_modified();
|
|
self
|
|
}
|
|
|
|
/// Refund the payment
|
|
pub fn refund_payment(mut self) -> Self {
|
|
self.status = PaymentStatus::Refunded;
|
|
self.base_data.update_modified();
|
|
self
|
|
}
|
|
|
|
/// Check if payment is completed
|
|
pub fn is_completed(&self) -> bool {
|
|
self.status == PaymentStatus::Completed
|
|
}
|
|
|
|
/// Check if payment is pending
|
|
pub fn is_pending(&self) -> bool {
|
|
self.status == PaymentStatus::Pending
|
|
}
|
|
|
|
/// Check if payment is processing
|
|
pub fn is_processing(&self) -> bool {
|
|
self.status == PaymentStatus::Processing
|
|
}
|
|
|
|
/// Check if payment has failed
|
|
pub fn has_failed(&self) -> bool {
|
|
self.status == PaymentStatus::Failed
|
|
}
|
|
|
|
/// Check if payment is refunded
|
|
pub fn is_refunded(&self) -> bool {
|
|
self.status == PaymentStatus::Refunded
|
|
}
|
|
|
|
// Setter for base_data fields if needed directly
|
|
pub fn set_base_created_at(mut self, created_at: i64) -> Self {
|
|
self.base_data.created_at = created_at;
|
|
self
|
|
}
|
|
|
|
pub fn set_base_modified_at(mut self, modified_at: i64) -> Self {
|
|
self.base_data.modified_at = modified_at;
|
|
self
|
|
}
|
|
}
|
|
|
|
// Tests for Payment model are located in tests/payment.rs
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/git.threefold.info/herocode/db/heromodels/src/models/biz/product.rs
|
|
|
|
```rs
|
|
use heromodels_core::BaseModelData;
|
|
use heromodels_derive::model;
|
|
use rhai::{CustomType, TypeBuilder};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
// ProductType represents the type of a product
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
|
|
pub enum ProductType {
|
|
#[default]
|
|
Product,
|
|
Service,
|
|
}
|
|
|
|
// ProductStatus represents the status of a product
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
|
|
pub enum ProductStatus {
|
|
#[default]
|
|
Available,
|
|
Unavailable,
|
|
}
|
|
|
|
// ProductComponent represents a component or sub-part of a product.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, CustomType)]
|
|
pub struct ProductComponent {
|
|
pub name: String,
|
|
pub description: String,
|
|
pub quantity: u32,
|
|
}
|
|
|
|
impl ProductComponent {
|
|
// Minimal constructor with no parameters
|
|
pub fn new() -> Self {
|
|
Self {
|
|
name: String::new(),
|
|
description: String::new(),
|
|
quantity: 1, // Default quantity to 1
|
|
}
|
|
}
|
|
|
|
// Builder methods
|
|
pub fn description(mut self, description: impl ToString) -> Self {
|
|
self.description = description.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn quantity(mut self, quantity: u32) -> Self {
|
|
self.quantity = quantity;
|
|
self
|
|
}
|
|
|
|
pub fn name(mut self, name: impl ToString) -> Self {
|
|
self.name = name.to_string();
|
|
self
|
|
}
|
|
}
|
|
|
|
// Product represents a product or service offered
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
|
|
#[model]
|
|
pub struct Product {
|
|
pub base_data: BaseModelData,
|
|
pub name: String,
|
|
pub description: String,
|
|
pub price: f64, // Representing currency.Currency for now
|
|
pub type_: ProductType,
|
|
pub category: String,
|
|
pub status: ProductStatus,
|
|
pub max_amount: u16,
|
|
pub purchase_till: i64, // Representing ourtime.OurTime
|
|
pub active_till: i64, // Representing ourtime.OurTime
|
|
pub components: Vec<ProductComponent>,
|
|
}
|
|
|
|
impl Product {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
base_data: BaseModelData::new(),
|
|
name: String::new(),
|
|
description: String::new(),
|
|
price: 0.0,
|
|
type_: ProductType::default(),
|
|
category: String::new(),
|
|
status: ProductStatus::default(),
|
|
max_amount: 0,
|
|
purchase_till: 0,
|
|
active_till: 0,
|
|
components: Vec::new(),
|
|
}
|
|
}
|
|
|
|
// Builder methods
|
|
pub fn name(mut self, name: impl ToString) -> Self {
|
|
self.name = name.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn description(mut self, description: impl ToString) -> Self {
|
|
self.description = description.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn price(mut self, price: f64) -> Self {
|
|
self.price = price;
|
|
self
|
|
}
|
|
|
|
pub fn type_(mut self, type_: ProductType) -> Self {
|
|
self.type_ = type_;
|
|
self
|
|
}
|
|
|
|
pub fn category(mut self, category: impl ToString) -> Self {
|
|
self.category = category.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn status(mut self, status: ProductStatus) -> Self {
|
|
self.status = status;
|
|
self
|
|
}
|
|
|
|
pub fn max_amount(mut self, max_amount: u16) -> Self {
|
|
self.max_amount = max_amount;
|
|
self
|
|
}
|
|
|
|
pub fn purchase_till(mut self, purchase_till: i64) -> Self {
|
|
self.purchase_till = purchase_till;
|
|
self
|
|
}
|
|
|
|
pub fn active_till(mut self, active_till: i64) -> Self {
|
|
self.active_till = active_till;
|
|
self
|
|
}
|
|
|
|
pub fn add_component(mut self, component: ProductComponent) -> Self {
|
|
self.components.push(component);
|
|
self
|
|
}
|
|
|
|
pub fn components(mut self, components: Vec<ProductComponent>) -> Self {
|
|
self.components = components;
|
|
self
|
|
}
|
|
|
|
// BaseModelData field operations are now handled by BaseModelDataOps trait
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/git.threefold.info/herocode/db/heromodels/src/models/biz/README.md
|
|
|
|
```md
|
|
# Business Models (`biz`)
|
|
|
|
The `biz` module provides a suite of models for handling core business operations, including company management, product catalogs, sales, payments, and shareholder records.
|
|
|
|
## Core Models
|
|
|
|
### `Company`
|
|
|
|
The `Company` struct is the central model, representing a business entity.
|
|
|
|
- **Key Fields**: `name`, `registration_number`, `incorporation_date`, `address`, `business_type`, and `status`.
|
|
- **Enums**:
|
|
- `CompanyStatus`: Tracks the company's state (`PendingPayment`, `Active`, `Suspended`, `Inactive`).
|
|
- `BusinessType`: Categorizes the company (e.g., `Coop`, `Single`, `Global`).
|
|
- **Functionality**: Provides a foundation for linking other business models like products, sales, and shareholders.
|
|
|
|
### `Product`
|
|
|
|
The `Product` model defines goods or services offered by a company.
|
|
|
|
- **Key Fields**: `name`, `description`, `price`, `category`, `status`, and `components`.
|
|
- **Nested Struct**: `ProductComponent` allows for defining complex products with sub-parts.
|
|
- **Enums**:
|
|
- `ProductType`: Differentiates between a `Product` and a `Service`.
|
|
- `ProductStatus`: Indicates if a product is `Available` or `Unavailable`.
|
|
|
|
### `Sale`
|
|
|
|
The `Sale` struct records a transaction, linking a buyer to products.
|
|
|
|
- **Key Fields**: `company_id`, `buyer_id`, `total_amount`, `sale_date`, and `status`.
|
|
- **Nested Struct**: `SaleItem` captures a snapshot of each product at the time of sale, including `product_id`, `quantity`, and `unit_price`.
|
|
- **Enum**: `SaleStatus` tracks the state of the sale (`Pending`, `Completed`, `Cancelled`).
|
|
|
|
### `Payment`
|
|
|
|
The `Payment` model handles financial transactions, often linked to sales or subscriptions.
|
|
|
|
- **Key Fields**: `payment_intent_id` (e.g., for Stripe), `company_id`, `total_amount`, `currency`, and `status`.
|
|
- **Functionality**: Includes methods to manage the payment lifecycle (`process_payment`, `complete_payment`, `fail_payment`, `refund_payment`).
|
|
- **Enum**: `PaymentStatus` provides a detailed state of the payment (`Pending`, `Processing`, `Completed`, `Failed`, `Refunded`).
|
|
|
|
### `Shareholder`
|
|
|
|
The `Shareholder` model tracks ownership of a company.
|
|
|
|
- **Key Fields**: `company_id`, `user_id`, `name`, `shares`, and `percentage`.
|
|
- **Enum**: `ShareholderType` distinguishes between `Individual` and `Corporate` shareholders.
|
|
|
|
## Workflow Example
|
|
|
|
1. A `Company` is created.
|
|
2. The company defines several `Product` models representing its offerings.
|
|
3. A customer (buyer) initiates a purchase, which creates a `Sale` record containing multiple `SaleItem`s.
|
|
4. A `Payment` record is generated to process the transaction for the `Sale`'s total amount.
|
|
5. As the company grows, `Shareholder` records are created to track equity distribution.
|
|
|
|
All models use the builder pattern for easy and readable instance creation.
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/git.threefold.info/herocode/db/heromodels/src/models/biz/sale.rs
|
|
|
|
```rs
|
|
use heromodels_core::{BaseModelData, BaseModelDataOps, Model};
|
|
use rhai::{CustomType, TypeBuilder};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// Represents the status of a sale.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub enum SaleStatus {
|
|
Pending,
|
|
Completed,
|
|
Cancelled,
|
|
}
|
|
|
|
impl Default for SaleStatus {
|
|
fn default() -> Self {
|
|
SaleStatus::Pending
|
|
}
|
|
}
|
|
|
|
/// Represents an individual item within a Sale.
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, CustomType)]
|
|
pub struct SaleItem {
|
|
pub product_id: u32,
|
|
pub name: String, // Denormalized product name at time of sale
|
|
pub quantity: i32,
|
|
pub unit_price: f64, // Price per unit at time of sale
|
|
pub subtotal: f64,
|
|
pub service_active_until: Option<i64>, // Optional: For services, date until this specific purchased instance is active
|
|
}
|
|
|
|
impl SaleItem {
|
|
/// Creates a new `SaleItem` with default values.
|
|
pub fn new() -> Self {
|
|
SaleItem {
|
|
product_id: 0,
|
|
name: String::new(),
|
|
quantity: 0,
|
|
unit_price: 0.0,
|
|
subtotal: 0.0,
|
|
service_active_until: None,
|
|
}
|
|
}
|
|
|
|
// Builder methods
|
|
pub fn product_id(mut self, product_id: u32) -> Self {
|
|
self.product_id = product_id;
|
|
self
|
|
}
|
|
|
|
pub fn name(mut self, name: impl ToString) -> Self {
|
|
self.name = name.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn quantity(mut self, quantity: i32) -> Self {
|
|
self.quantity = quantity;
|
|
self
|
|
}
|
|
|
|
pub fn unit_price(mut self, unit_price: f64) -> Self {
|
|
self.unit_price = unit_price;
|
|
self
|
|
}
|
|
|
|
pub fn subtotal(mut self, subtotal: f64) -> Self {
|
|
self.subtotal = subtotal;
|
|
self
|
|
}
|
|
|
|
pub fn service_active_until(mut self, service_active_until: Option<i64>) -> Self {
|
|
self.service_active_until = service_active_until;
|
|
self
|
|
}
|
|
}
|
|
|
|
/// Represents a sale of products or services.
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, CustomType)]
|
|
pub struct Sale {
|
|
pub base_data: BaseModelData,
|
|
pub company_id: u32,
|
|
pub buyer_id: u32,
|
|
pub transaction_id: u32,
|
|
pub total_amount: f64,
|
|
pub status: SaleStatus,
|
|
pub sale_date: i64,
|
|
pub items: Vec<SaleItem>,
|
|
pub notes: String,
|
|
}
|
|
|
|
impl Model for Sale {
|
|
fn db_prefix() -> &'static str {
|
|
"sale"
|
|
}
|
|
|
|
fn get_id(&self) -> u32 {
|
|
self.base_data.id
|
|
}
|
|
|
|
fn base_data_mut(&mut self) -> &mut BaseModelData {
|
|
&mut self.base_data
|
|
}
|
|
}
|
|
|
|
impl BaseModelDataOps for Sale {
|
|
fn get_base_data_mut(&mut self) -> &mut BaseModelData {
|
|
&mut self.base_data
|
|
}
|
|
}
|
|
|
|
impl Sale {
|
|
/// Creates a new `Sale` with default values.
|
|
pub fn new() -> Self {
|
|
Sale {
|
|
base_data: BaseModelData::new(),
|
|
company_id: 0,
|
|
buyer_id: 0,
|
|
transaction_id: 0,
|
|
total_amount: 0.0,
|
|
status: SaleStatus::default(),
|
|
sale_date: 0,
|
|
items: Vec::new(),
|
|
notes: String::new(),
|
|
}
|
|
}
|
|
|
|
// Builder methods for Sale
|
|
pub fn company_id(mut self, company_id: u32) -> Self {
|
|
self.company_id = company_id;
|
|
self
|
|
}
|
|
|
|
pub fn buyer_id(mut self, buyer_id: u32) -> Self {
|
|
self.buyer_id = buyer_id;
|
|
self
|
|
}
|
|
|
|
pub fn transaction_id(mut self, transaction_id: u32) -> Self {
|
|
self.transaction_id = transaction_id;
|
|
self
|
|
}
|
|
|
|
pub fn total_amount(mut self, total_amount: f64) -> Self {
|
|
self.total_amount = total_amount;
|
|
self
|
|
}
|
|
|
|
pub fn status(mut self, status: SaleStatus) -> Self {
|
|
self.status = status;
|
|
self
|
|
}
|
|
|
|
pub fn sale_date(mut self, sale_date: i64) -> Self {
|
|
self.sale_date = sale_date;
|
|
self
|
|
}
|
|
|
|
pub fn items(mut self, items: Vec<SaleItem>) -> Self {
|
|
self.items = items;
|
|
self
|
|
}
|
|
|
|
pub fn add_item(mut self, item: SaleItem) -> Self {
|
|
self.items.push(item);
|
|
self
|
|
}
|
|
|
|
pub fn notes(mut self, notes: impl ToString) -> Self {
|
|
self.notes = notes.to_string();
|
|
self
|
|
}
|
|
|
|
// BaseModelData operations are now handled by BaseModelDataOps trait
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/git.threefold.info/herocode/db/heromodels/src/models/biz/shareholder.rs
|
|
|
|
```rs
|
|
use heromodels_core::BaseModelData;
|
|
use heromodels_derive::model;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum ShareholderType {
|
|
Individual,
|
|
Corporate,
|
|
}
|
|
|
|
impl Default for ShareholderType {
|
|
fn default() -> Self {
|
|
ShareholderType::Individual
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
|
#[model]
|
|
pub struct Shareholder {
|
|
pub base_data: BaseModelData,
|
|
pub company_id: u32,
|
|
pub user_id: u32, // Or other entity ID
|
|
pub name: String,
|
|
pub shares: f64,
|
|
pub percentage: f64,
|
|
pub type_: ShareholderType,
|
|
pub since: i64, // Timestamp
|
|
}
|
|
|
|
impl Shareholder {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
base_data: BaseModelData::new(),
|
|
company_id: 0, // Default, to be set by builder
|
|
user_id: 0, // Default, to be set by builder
|
|
name: String::new(), // Default
|
|
shares: 0.0, // Default
|
|
percentage: 0.0, // Default
|
|
type_: ShareholderType::default(), // Uses ShareholderType's Default impl
|
|
since: 0, // Default timestamp, to be set by builder
|
|
}
|
|
}
|
|
|
|
// Builder methods
|
|
pub fn company_id(mut self, company_id: u32) -> Self {
|
|
self.company_id = company_id;
|
|
self
|
|
}
|
|
|
|
pub fn user_id(mut self, user_id: u32) -> Self {
|
|
self.user_id = user_id;
|
|
self
|
|
}
|
|
|
|
pub fn name(mut self, name: impl ToString) -> Self {
|
|
self.name = name.to_string();
|
|
self
|
|
}
|
|
|
|
pub fn shares(mut self, shares: f64) -> Self {
|
|
self.shares = shares;
|
|
self
|
|
}
|
|
|
|
pub fn percentage(mut self, percentage: f64) -> Self {
|
|
self.percentage = percentage;
|
|
self
|
|
}
|
|
|
|
pub fn type_(mut self, type_: ShareholderType) -> Self {
|
|
self.type_ = type_;
|
|
self
|
|
}
|
|
|
|
pub fn since(mut self, since: i64) -> Self {
|
|
self.since = since;
|
|
self
|
|
}
|
|
|
|
// Base data operations are now handled by BaseModelDataOps trait
|
|
}
|
|
|
|
```
|
|
|
|
</file_contents>
|
|
<meta prompt 1 = "[Architect]">
|
|
You are a senior software architect specializing in code design and implementation planning. Your role is to:
|
|
|
|
1. Analyze the requested changes and break them down into clear, actionable steps
|
|
2. Create a detailed implementation plan that includes:
|
|
- Files that need to be modified
|
|
- Specific code sections requiring changes
|
|
- New functions, methods, or classes to be added
|
|
- Dependencies or imports to be updated
|
|
- Data structure modifications
|
|
- Interface changes
|
|
- Configuration updates
|
|
|
|
For each change:
|
|
|
|
- Describe the exact location in the code where changes are needed
|
|
- Explain the logic and reasoning behind each modification
|
|
- Provide example signatures, parameters, and return types
|
|
- Note any potential side effects or impacts on other parts of the codebase
|
|
- Highlight critical architectural decisions that need to be made
|
|
|
|
You may include short code snippets to illustrate specific patterns, signatures, or structures, but do not implement the full solution.
|
|
|
|
Focus solely on the technical implementation plan - exclude testing, validation, and deployment considerations unless they directly impact the architecture.
|
|
|
|
Please proceed with your analysis based on the following <user instructions>
|
|
</meta prompt 1>
|
|
<meta prompt 2 = "models in V for rust import">
|
|
|
|
pub struct StructName{
|
|
pub mut:
|
|
name string = “aname” //comment
|
|
…
|
|
|
|
forget what rust does, there is no special module things needed, no re-exports of any of that complicates stuff
|
|
|
|
there is no defaults for empty strings or 0 ints, … defaults are only for non empty stuff
|
|
|
|
</meta prompt 2>
|
|
<user_instructions>
|
|
$NAME = finance
|
|
|
|
walk over all models from biz: db/heromodels/src/models/$NAME in the rust repo
|
|
create nice structured public models in Vlang (V) see instructions in herlolib
|
|
|
|
put the results in /Users/despiegk/code/github/incubaid/herolib/lib/hero/models/$NAME
|
|
|
|
put decorator on fields which need to be indexed: use @[index] for that at end of line of the property of the struct
|
|
|
|
copy the documentation as well and put on the vstruct and on its fields
|
|
|
|
make instructions so a coding agent can execute it, put the models in files, ...
|
|
|
|
keep it all simple
|
|
|
|
don't do anything additional for modules, don't do import
|
|
|
|
at top of each file we have ```module $NAME```
|
|
|
|
don't create management classes, only output the structs
|
|
|
|
</user_instructions>
|