1455 lines
40 KiB
Markdown
1455 lines
40 KiB
Markdown
<file_map>
|
|
/Users/despiegk/code/github/incubaid/herolib
|
|
├── .github
|
|
│ └── workflows
|
|
├── .zed
|
|
├── aiprompts
|
|
│ ├── .openhands
|
|
│ ├── bizmodel
|
|
│ ├── documentor
|
|
│ ├── docusaurus
|
|
│ ├── herolib_advanced
|
|
│ ├── herolib_core
|
|
│ ├── instructions_archive
|
|
│ │ ├── models_from_v
|
|
│ │ └── processing
|
|
│ ├── v_advanced
|
|
│ ├── v_core
|
|
│ │ ├── array
|
|
│ │ ├── benchmark
|
|
│ │ ├── builtin
|
|
│ │ ├── crypto
|
|
│ │ ├── encoding
|
|
│ │ ├── io
|
|
│ │ ├── json
|
|
│ │ ├── json2
|
|
│ │ ├── maps
|
|
│ │ ├── net
|
|
│ │ ├── orm
|
|
│ │ ├── regex
|
|
│ │ ├── string
|
|
│ │ ├── time
|
|
│ │ ├── toml
|
|
│ │ └── veb
|
|
│ └── v_veb_webserver
|
|
├── cli
|
|
├── docker
|
|
│ ├── herolib
|
|
│ │ └── scripts
|
|
│ └── postgresql
|
|
├── examples
|
|
│ ├── aiexamples
|
|
│ ├── biztools
|
|
│ │ ├── _archive
|
|
│ │ ├── bizmodel_docusaurus
|
|
│ │ │ └── archive
|
|
│ │ │ └── img
|
|
│ │ └── examples
|
|
│ │ └── full
|
|
│ ├── builder
|
|
│ │ └── remote_executor
|
|
│ ├── clients
|
|
│ ├── core
|
|
│ │ ├── base
|
|
│ │ ├── db
|
|
│ │ ├── logger
|
|
│ │ ├── openapi
|
|
│ │ │ └── gitea
|
|
│ │ ├── openrpc
|
|
│ │ │ └── examples
|
|
│ │ │ ├── openrpc_client
|
|
│ │ │ ├── openrpc_docs
|
|
│ │ │ └── petstore_client
|
|
│ │ └── pathlib
|
|
│ │ └── examples
|
|
│ │ ├── list
|
|
│ │ ├── md5
|
|
│ │ ├── scanner
|
|
│ │ └── sha256
|
|
│ ├── data
|
|
│ │ ├── location
|
|
│ │ ├── ourdb_syncer
|
|
│ │ ├── params
|
|
│ │ │ ├── args
|
|
│ │ │ │ └── data
|
|
│ │ │ └── paramsfilter
|
|
│ │ └── resp
|
|
│ ├── develop
|
|
│ │ ├── codewalker
|
|
│ │ ├── gittools
|
|
│ │ ├── heroprompt
|
|
│ │ ├── ipapi
|
|
│ │ ├── juggler
|
|
│ │ │ └── hero
|
|
│ │ │ └── playbook
|
|
│ │ ├── luadns
|
|
│ │ ├── openai
|
|
│ │ ├── runpod
|
|
│ │ ├── vastai
|
|
│ │ └── wireguard
|
|
│ ├── hero
|
|
│ │ ├── db
|
|
│ │ ├── generation
|
|
│ │ │ ├── blank_generation
|
|
│ │ │ └── openapi_generation
|
|
│ │ │ └── example_actor
|
|
│ │ │ └── specs
|
|
│ │ ├── herofs
|
|
│ │ ├── heromodels
|
|
│ │ └── openapi
|
|
│ │ └── data
|
|
│ ├── installers
|
|
│ │ ├── db
|
|
│ │ ├── infra
|
|
│ │ ├── lang
|
|
│ │ ├── net
|
|
│ │ ├── sysadmintools
|
|
│ │ ├── threefold
|
|
│ │ └── virt
|
|
│ ├── installers_remote
|
|
│ ├── jobs
|
|
│ ├── lang
|
|
│ │ └── python
|
|
│ ├── mcp
|
|
│ │ ├── http_demo
|
|
│ │ ├── http_server
|
|
│ │ ├── inspector
|
|
│ │ └── simple_http
|
|
│ ├── osal
|
|
│ │ ├── coredns
|
|
│ │ ├── download
|
|
│ │ ├── ping
|
|
│ │ ├── process
|
|
│ │ │ ├── process_bash
|
|
│ │ │ └── process_python
|
|
│ │ ├── rsync
|
|
│ │ ├── sandbox
|
|
│ │ │ └── examples
|
|
│ │ ├── sshagent
|
|
│ │ ├── tmux
|
|
│ │ │ └── heroscripts
|
|
│ │ ├── ubuntu
|
|
│ │ └── zinit
|
|
│ │ ├── rpc
|
|
│ │ └── simple
|
|
│ ├── schemas
|
|
│ │ ├── example
|
|
│ │ │ └── testdata
|
|
│ │ ├── openapi
|
|
│ │ │ └── codegen
|
|
│ │ └── openrpc
|
|
│ ├── sshagent
|
|
│ ├── threefold
|
|
│ │ ├── grid
|
|
│ │ │ ├── deploy
|
|
│ │ │ └── utils
|
|
│ │ ├── gridproxy
|
|
│ │ ├── holochain
|
|
│ │ ├── incatokens
|
|
│ │ │ └── data
|
|
│ │ ├── solana
|
|
│ │ └── tfgrid3deployer
|
|
│ │ ├── gw_over_wireguard
|
|
│ │ ├── heroscript
|
|
│ │ ├── hetzner
|
|
│ │ ├── open_webui_gw
|
|
│ │ └── vm_gw_caddy
|
|
│ ├── tools
|
|
│ │ └── imagemagick
|
|
│ │ └── .backup
|
|
│ ├── ui
|
|
│ │ ├── console
|
|
│ │ │ ├── console2
|
|
│ │ │ └── flow1
|
|
│ │ └── telegram
|
|
│ ├── vfs
|
|
│ │ └── vfs_db
|
|
│ ├── virt
|
|
│ │ ├── daguserver
|
|
│ │ ├── docker
|
|
│ │ │ └── ai_web_ui
|
|
│ │ ├── heropods
|
|
│ │ ├── hetzner
|
|
│ │ ├── lima
|
|
│ │ ├── podman
|
|
│ │ └── windows
|
|
│ ├── web
|
|
│ │ ├── doctree
|
|
│ │ │ └── content
|
|
│ │ └── markdown_renderer
|
|
│ └── webdav
|
|
├── lib
|
|
│ ├── ai
|
|
│ │ ├── escalayer
|
|
│ │ ├── mcp
|
|
│ │ │ ├── baobab
|
|
│ │ │ ├── cmd
|
|
│ │ │ ├── mcpgen
|
|
│ │ │ │ ├── schemas
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── pugconvert
|
|
│ │ │ │ ├── cmd
|
|
│ │ │ │ ├── logic
|
|
│ │ │ │ │ └── templates
|
|
│ │ │ │ └── mcp
|
|
│ │ │ ├── rhai
|
|
│ │ │ │ ├── cmd
|
|
│ │ │ │ ├── example
|
|
│ │ │ │ ├── logic
|
|
│ │ │ │ │ ├── prompts
|
|
│ │ │ │ │ └── templates
|
|
│ │ │ │ └── mcp
|
|
│ │ │ ├── rust
|
|
│ │ │ └── vcode
|
|
│ │ │ ├── cmd
|
|
│ │ │ ├── logic
|
|
│ │ │ └── mcp
|
|
│ │ └── utils
|
|
│ ├── biz
|
|
│ │ ├── bizmodel
|
|
│ │ │ ├── docu
|
|
│ │ │ ├── exampledata
|
|
│ │ │ └── templates
|
|
│ │ ├── investortool
|
|
│ │ │ └── simulator
|
|
│ │ │ └── templates
|
|
│ │ ├── planner
|
|
│ │ │ ├── examples
|
|
│ │ │ └── models
|
|
│ │ └── spreadsheet
|
|
│ │ └── docu
|
|
│ ├── builder
|
|
│ ├── clients
|
|
│ │ ├── giteaclient
|
|
│ │ ├── ipapi
|
|
│ │ ├── jina
|
|
│ │ │ └── py_specs
|
|
│ │ ├── livekit
|
|
│ │ ├── mailclient
|
|
│ │ ├── meilisearch
|
|
│ │ ├── mycelium
|
|
│ │ ├── mycelium_rpc
|
|
│ │ ├── openai
|
|
│ │ │ ├── audio
|
|
│ │ │ ├── embeddings
|
|
│ │ │ ├── files
|
|
│ │ │ ├── finetune
|
|
│ │ │ ├── images
|
|
│ │ │ └── moderation
|
|
│ │ ├── postgresql_client
|
|
│ │ ├── qdrant
|
|
│ │ ├── rclone
|
|
│ │ ├── runpod
|
|
│ │ ├── sendgrid
|
|
│ │ ├── traefik
|
|
│ │ ├── vastai
|
|
│ │ ├── wireguard
|
|
│ │ ├── zerodb_client
|
|
│ │ └── zinit
|
|
│ ├── conversiontools
|
|
│ │ ├── docsorter
|
|
│ │ │ └── pythonscripts
|
|
│ │ ├── imagemagick
|
|
│ │ ├── pdftotext
|
|
│ │ └── text_extractor
|
|
│ ├── core
|
|
│ │ ├── base
|
|
│ │ ├── code
|
|
│ │ │ └── templates
|
|
│ │ │ ├── comment
|
|
│ │ │ ├── function
|
|
│ │ │ ├── interface
|
|
│ │ │ └── struct
|
|
│ │ ├── generator
|
|
│ │ │ └── generic
|
|
│ │ │ └── templates
|
|
│ │ ├── herocmds
|
|
│ │ ├── httpconnection
|
|
│ │ ├── logger
|
|
│ │ ├── openrpc_remove
|
|
│ │ │ ├── examples
|
|
│ │ │ └── specs
|
|
│ │ ├── pathlib
|
|
│ │ ├── playbook
|
|
│ │ ├── playcmds
|
|
│ │ ├── playmacros
|
|
│ │ ├── redisclient
|
|
│ │ ├── rootpath
|
|
│ │ ├── smartid
|
|
│ │ ├── texttools
|
|
│ │ │ └── regext
|
|
│ │ │ └── testdata
|
|
│ │ └── vexecutor
|
|
│ ├── crypt
|
|
│ │ ├── aes_symmetric
|
|
│ │ ├── crpgp
|
|
│ │ ├── ed25519
|
|
│ │ ├── keychain
|
|
│ │ ├── keysafe
|
|
│ │ ├── openssl
|
|
│ │ ├── pgp
|
|
│ │ └── secrets
|
|
│ ├── data
|
|
│ │ ├── cache
|
|
│ │ ├── countries
|
|
│ │ │ └── data
|
|
│ │ ├── currency
|
|
│ │ ├── dbfs
|
|
│ │ ├── dedupestor
|
|
│ │ │ └── dedupe_ourdb
|
|
│ │ ├── doctree
|
|
│ │ │ ├── collection
|
|
│ │ │ │ ├── data
|
|
│ │ │ │ ├── template
|
|
│ │ │ │ └── testdata
|
|
│ │ │ │ └── export_test
|
|
│ │ │ │ ├── export_expected
|
|
│ │ │ │ │ └── src
|
|
│ │ │ │ │ └── col1
|
|
│ │ │ │ │ └── img
|
|
│ │ │ │ └── mytree
|
|
│ │ │ │ └── dir1
|
|
│ │ │ │ └── dir2
|
|
│ │ │ ├── pointer
|
|
│ │ │ └── testdata
|
|
│ │ │ ├── actions
|
|
│ │ │ │ └── functionality
|
|
│ │ │ ├── export_test
|
|
│ │ │ │ ├── export_expected
|
|
│ │ │ │ │ ├── col1
|
|
│ │ │ │ │ │ └── img
|
|
│ │ │ │ │ └── col2
|
|
│ │ │ │ └── mytree
|
|
│ │ │ │ ├── dir1
|
|
│ │ │ │ │ └── dir2
|
|
│ │ │ │ └── dir3
|
|
│ │ │ ├── process_defs_test
|
|
│ │ │ │ ├── col1
|
|
│ │ │ │ └── col2
|
|
│ │ │ ├── process_includes_test
|
|
│ │ │ │ ├── col1
|
|
│ │ │ │ └── col2
|
|
│ │ │ ├── rpc
|
|
│ │ │ └── tree_test
|
|
│ │ │ ├── fruits
|
|
│ │ │ │ └── berries
|
|
│ │ │ │ └── img
|
|
│ │ │ └── vegetables
|
|
│ │ │ └── cruciferous
|
|
│ │ ├── encoder
|
|
│ │ ├── encoderhero
|
|
│ │ ├── flist
|
|
│ │ ├── gid
|
|
│ │ ├── graphdb
|
|
│ │ ├── ipaddress
|
|
│ │ ├── location
|
|
│ │ ├── markdown
|
|
│ │ │ ├── elements
|
|
│ │ │ ├── parsers
|
|
│ │ │ ├── testdata
|
|
│ │ │ └── tools
|
|
│ │ ├── markdownparser2
|
|
│ │ ├── markdownrenderer
|
|
│ │ ├── mnemonic
|
|
│ │ ├── models
|
|
│ │ │ └── hr
|
|
│ │ ├── ourdb
|
|
│ │ ├── ourdb_syncer
|
|
│ │ │ ├── http
|
|
│ │ │ └── streamer
|
|
│ │ ├── ourjson
|
|
│ │ ├── ourtime
|
|
│ │ ├── paramsparser
|
|
│ │ ├── radixtree
|
|
│ │ ├── resp
|
|
│ │ ├── serializers
|
|
│ │ ├── tst
|
|
│ │ ├── verasure
|
|
│ │ └── vstor
|
|
│ ├── dav
|
|
│ │ └── webdav
|
|
│ │ ├── bin
|
|
│ │ ├── specs
|
|
│ │ └── templates
|
|
│ ├── develop
|
|
│ │ ├── codewalker
|
|
│ │ ├── gittools
|
|
│ │ │ └── tests
|
|
│ │ ├── heroprompt
|
|
│ │ │ └── templates
|
|
│ │ ├── luadns
|
|
│ │ ├── performance
|
|
│ │ │ └── cmd
|
|
│ │ ├── sourcetree
|
|
│ │ ├── vscode
|
|
│ │ └── vscode_extensions
|
|
│ │ └── ourdb
|
|
│ │ └── templates
|
|
│ ├── hero
|
|
│ │ ├── db
|
|
│ │ ├── herocluster
|
|
│ │ │ └── example
|
|
│ │ ├── herofs
|
|
│ │ ├── herohandlers
|
|
│ │ ├── heromodels
|
|
│ │ └── heromodels copy
|
|
│ │ └── examples
|
|
│ ├── installers
|
|
│ │ ├── base
|
|
│ │ │ └── templates
|
|
│ │ ├── db
|
|
│ │ │ ├── cometbft
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── meilisearch_installer
|
|
│ │ │ ├── postgresql
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── qdrant_installer
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── zerodb
|
|
│ │ │ └── zerofs
|
|
│ │ ├── develapps
|
|
│ │ │ ├── chrome
|
|
│ │ │ └── vscode
|
|
│ │ ├── infra
|
|
│ │ │ ├── coredns
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── gitea
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── livekit
|
|
│ │ │ │ └── templates
|
|
│ │ │ └── zinit_installer
|
|
│ │ ├── lang
|
|
│ │ │ ├── golang
|
|
│ │ │ ├── herolib
|
|
│ │ │ ├── nodejs
|
|
│ │ │ ├── python
|
|
│ │ │ ├── rust
|
|
│ │ │ └── vlang
|
|
│ │ ├── net
|
|
│ │ │ ├── mycelium_installer
|
|
│ │ │ ├── wireguard_installer
|
|
│ │ │ └── yggdrasil
|
|
│ │ ├── sysadmintools
|
|
│ │ │ ├── actrunner
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── b2
|
|
│ │ │ ├── fungistor
|
|
│ │ │ ├── garage_s3
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── grafana
|
|
│ │ │ ├── prometheus
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── rclone
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── restic
|
|
│ │ │ └── s3
|
|
│ │ ├── threefold
|
|
│ │ │ ├── griddriver
|
|
│ │ │ └── tfrobot
|
|
│ │ ├── ulist
|
|
│ │ ├── virt
|
|
│ │ │ ├── cloudhypervisor
|
|
│ │ │ ├── docker
|
|
│ │ │ ├── herorunner
|
|
│ │ │ ├── lima
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── pacman
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── podman
|
|
│ │ │ ├── qemu
|
|
│ │ │ └── youki
|
|
│ │ └── web
|
|
│ │ ├── bun
|
|
│ │ ├── imagemagick
|
|
│ │ ├── lighttpd
|
|
│ │ │ └── templates
|
|
│ │ ├── tailwind
|
|
│ │ ├── tailwind4
|
|
│ │ ├── traefik
|
|
│ │ │ └── templates
|
|
│ │ └── zola
|
|
│ ├── lang
|
|
│ │ ├── python
|
|
│ │ │ └── templates
|
|
│ │ └── rust
|
|
│ ├── mcp
|
|
│ │ ├── baobab
|
|
│ │ ├── cmd
|
|
│ │ ├── mcpgen
|
|
│ │ │ ├── schemas
|
|
│ │ │ └── templates
|
|
│ │ ├── pugconvert
|
|
│ │ │ ├── cmd
|
|
│ │ │ ├── logic
|
|
│ │ │ │ └── templates
|
|
│ │ │ └── mcp
|
|
│ │ ├── rhai
|
|
│ │ │ ├── cmd
|
|
│ │ │ ├── example
|
|
│ │ │ ├── logic
|
|
│ │ │ │ ├── prompts
|
|
│ │ │ │ └── templates
|
|
│ │ │ └── mcp
|
|
│ │ ├── transport
|
|
│ │ └── vcode
|
|
│ │ ├── cmd
|
|
│ │ ├── logic
|
|
│ │ └── mcp
|
|
│ ├── osal
|
|
│ │ ├── core
|
|
│ │ ├── coredns
|
|
│ │ ├── hostsfile
|
|
│ │ ├── linux
|
|
│ │ │ └── templates
|
|
│ │ ├── netns
|
|
│ │ ├── notifier
|
|
│ │ ├── osinstaller
|
|
│ │ ├── rsync
|
|
│ │ │ └── templates
|
|
│ │ ├── screen
|
|
│ │ ├── sshagent
|
|
│ │ ├── startupmanager
|
|
│ │ ├── systemd
|
|
│ │ │ └── templates
|
|
│ │ ├── tmux
|
|
│ │ │ └── bin
|
|
│ │ ├── traefik
|
|
│ │ │ └── specs
|
|
│ │ ├── tun
|
|
│ │ ├── ubuntu
|
|
│ │ └── ufw
|
|
│ ├── schemas
|
|
│ │ ├── jsonrpc
|
|
│ │ │ ├── reflection
|
|
│ │ │ └── testdata
|
|
│ │ │ ├── testmodule
|
|
│ │ │ └── testserver
|
|
│ │ ├── jsonschema
|
|
│ │ │ ├── codegen
|
|
│ │ │ │ └── templates
|
|
│ │ │ └── testdata
|
|
│ │ ├── openapi
|
|
│ │ │ ├── codegen
|
|
│ │ │ ├── templates
|
|
│ │ │ └── testdata
|
|
│ │ └── openrpc
|
|
│ │ ├── codegen
|
|
│ │ │ ├── templates
|
|
│ │ │ └── testdata
|
|
│ │ ├── server
|
|
│ │ └── testdata
|
|
│ │ └── petstore_client
|
|
│ ├── security
|
|
│ │ ├── authentication
|
|
│ │ │ └── templates
|
|
│ │ └── jwt
|
|
│ ├── threefold
|
|
│ │ ├── grid3
|
|
│ │ │ ├── deploy_tosort
|
|
│ │ │ ├── deployer
|
|
│ │ │ ├── deployer2_sort
|
|
│ │ │ ├── griddriver
|
|
│ │ │ ├── gridproxy
|
|
│ │ │ │ └── model
|
|
│ │ │ ├── models
|
|
│ │ │ ├── rmb
|
|
│ │ │ ├── tfrobot
|
|
│ │ │ │ └── templates
|
|
│ │ │ ├── tokens
|
|
│ │ │ └── zerohub
|
|
│ │ ├── grid4
|
|
│ │ │ ├── datamodel
|
|
│ │ │ ├── datamodelsimulator
|
|
│ │ │ ├── farmingsimulator
|
|
│ │ │ │ └── templates
|
|
│ │ │ └── gridsimulator
|
|
│ │ │ └── manual
|
|
│ │ ├── incatokens
|
|
│ │ │ └── templates
|
|
│ │ └── models
|
|
│ │ ├── business
|
|
│ │ ├── core
|
|
│ │ ├── finance
|
|
│ │ ├── flow
|
|
│ │ ├── identity
|
|
│ │ ├── legal
|
|
│ │ ├── library
|
|
│ │ ├── location
|
|
│ │ └── payment
|
|
│ ├── ui
|
|
│ │ ├── console
|
|
│ │ ├── generic
|
|
│ │ ├── logger
|
|
│ │ ├── telegram
|
|
│ │ │ └── client
|
|
│ │ ├── template
|
|
│ │ └── uimodel
|
|
│ ├── vfs
|
|
│ │ ├── vfs_calendar
|
|
│ │ ├── vfs_contacts
|
|
│ │ ├── vfs_db
|
|
│ │ ├── vfs_local
|
|
│ │ ├── vfs_mail
|
|
│ │ └── vfs_nested
|
|
│ ├── virt
|
|
│ │ ├── cloudhypervisor
|
|
│ │ ├── crun
|
|
│ │ ├── docker
|
|
│ │ ├── heropods
|
|
│ │ ├── herorun
|
|
│ │ ├── herorun2
|
|
│ │ ├── hetznermanager
|
|
│ │ ├── lima
|
|
│ │ │ ├── raw
|
|
│ │ │ └── templates
|
|
│ │ ├── podman
|
|
│ │ └── qemu
|
|
│ │ └── templates
|
|
│ └── web
|
|
│ ├── doctreeclient
|
|
│ ├── docusaurus
|
|
│ │ └── example
|
|
│ ├── echarts
|
|
│ ├── site
|
|
│ │ └── example
|
|
│ └── ui
|
|
│ ├── static
|
|
│ │ ├── css
|
|
│ │ └── js
|
|
│ └── templates
|
|
│ └── admin
|
|
├── libarchive
|
|
│ ├── baobab
|
|
│ │ ├── actor
|
|
│ │ ├── generator
|
|
│ │ │ ├── _archive
|
|
│ │ │ ├── templates
|
|
│ │ │ └── testdata
|
|
│ │ ├── osis
|
|
│ │ ├── specification
|
|
│ │ └── stage
|
|
│ │ └── interfaces
|
|
│ ├── buildah
|
|
│ ├── daguserver
|
|
│ │ └── templates
|
|
│ ├── dify
|
|
│ │ └── templates
|
|
│ ├── examples
|
|
│ │ └── baobab
|
|
│ │ ├── generator
|
|
│ │ │ ├── basic
|
|
│ │ │ ├── geomind_poc
|
|
│ │ │ └── openapi_e2e
|
|
│ │ └── specification
|
|
│ ├── installers
|
|
│ │ └── web
|
|
│ │ └── caddy2
|
|
│ │ └── templates
|
|
│ ├── rhai
|
|
│ │ ├── prompts
|
|
│ │ ├── templates
|
|
│ │ └── testdata
|
|
│ ├── starlight
|
|
│ │ └── templates
|
|
│ └── zinit
|
|
│ └── zinit
|
|
├── manual
|
|
│ ├── best_practices
|
|
│ │ ├── osal
|
|
│ │ └── scripts
|
|
│ ├── core
|
|
│ │ └── concepts
|
|
│ ├── documentation
|
|
│ └── playcmds
|
|
├── research
|
|
│ ├── globals
|
|
│ └── openrpc
|
|
├── tests
|
|
│ └── data
|
|
└── vscodeplugin
|
|
└── heroscrypt-syntax
|
|
└── syntaxes
|
|
|
|
</file_map>
|
|
|
|
<file_contents>
|
|
File: /Users/despiegk/code/github/incubaid/herolib/lib/hero/db/ai_instructions.md
|
|
|
|
```md
|
|
# HeroDB Model Creation Instructions for AI
|
|
|
|
## Overview
|
|
|
|
This document provides clear instructions for AI agents to create new HeroDB models similar to `comment.v`. These models are used to store structured data in Redis using the HeroDB system.
|
|
|
|
## Key Concepts
|
|
|
|
- Each model represents a data type stored in Redis hash sets
|
|
- Models must implement serialization/deserialization using the `encoder` module
|
|
- Models inherit from the `Base` struct which provides common fields
|
|
- The database uses a factory pattern for model access
|
|
|
|
## File Structure
|
|
|
|
Create a new file in `lib/hero/heromodels/` with the model name (e.g., `calendar.v`).
|
|
|
|
## Required Components
|
|
|
|
### 1. Model Struct Definition
|
|
|
|
Define your model struct with the following pattern:
|
|
|
|
```v
|
|
@[heap]
|
|
pub struct Calendar {
|
|
db.Base // Inherit from Base struct
|
|
pub mut:
|
|
// Add your specific fields here
|
|
title string
|
|
start_time i64
|
|
end_time i64
|
|
location string
|
|
attendees []string
|
|
}
|
|
```
|
|
|
|
### 2. Type Name Method
|
|
|
|
Implement a method to return the model's type name:
|
|
|
|
```v
|
|
pub fn (self Calendar) type_name() string {
|
|
return 'calendar'
|
|
}
|
|
```
|
|
|
|
### 3. Serialization (dump) Method
|
|
|
|
Implement the `dump` method to serialize your struct's fields using the encoder:
|
|
|
|
```v
|
|
pub fn (self Calendar) dump(mut e &encoder.Encoder) ! {
|
|
e.add_string(self.title)
|
|
e.add_i64(self.start_time)
|
|
e.add_i64(self.end_time)
|
|
e.add_string(self.location)
|
|
e.add_list_string(self.attendees)
|
|
}
|
|
```
|
|
|
|
### 4. Deserialization (load) Method
|
|
|
|
Implement the `load` method to deserialize your struct's fields:
|
|
|
|
```v
|
|
fn (mut self DBCalendar) load(mut o Calendar, mut e &encoder.Decoder) ! {
|
|
o.title = e.get_string()!
|
|
o.start_time = e.get_i64()!
|
|
o.end_time = e.get_i64()!
|
|
o.location = e.get_string()!
|
|
o.attendees = e.get_list_string()!
|
|
}
|
|
```
|
|
|
|
### 5. Model Arguments Struct
|
|
|
|
Define a struct for creating new instances of your model:
|
|
|
|
```v
|
|
@[params]
|
|
pub struct CalendarArg {
|
|
pub mut:
|
|
title string @[required]
|
|
start_time i64
|
|
end_time i64
|
|
location string
|
|
attendees []string
|
|
}
|
|
```
|
|
|
|
### 6. Database Wrapper Struct
|
|
|
|
Create a database wrapper struct for your model:
|
|
|
|
```v
|
|
pub struct DBCalendar {
|
|
pub mut:
|
|
db &db.DB @[skip; str: skip]
|
|
}
|
|
```
|
|
|
|
### 7. Factory Integration
|
|
|
|
Add your model to the ModelsFactory struct in `factory.v`:
|
|
|
|
```v
|
|
pub struct ModelsFactory {
|
|
pub mut:
|
|
comments DBCalendar
|
|
// ... other models
|
|
}
|
|
```
|
|
|
|
And initialize it in the `new()` function:
|
|
|
|
```v
|
|
pub fn new() !ModelsFactory {
|
|
mut mydb := db.new()!
|
|
return ModelsFactory{
|
|
comments: DBCalendar{
|
|
db: &mydb
|
|
}
|
|
// ... initialize other models
|
|
}
|
|
}
|
|
```
|
|
|
|
## Encoder Methods Reference
|
|
|
|
Use these methods for serialization/deserialization:
|
|
|
|
### Encoder (Serialization)
|
|
|
|
- `e.add_bool(val bool)`
|
|
- `e.add_u8(val u8)`
|
|
- `e.add_u16(val u16)`
|
|
- `e.add_u32(val u32)`
|
|
- `e.add_u64(val u64)`
|
|
- `e.add_i8(val i8)`
|
|
- `e.add_i16(val i16)`
|
|
- `e.add_i32(val i32)`
|
|
- `e.add_i64(val i64)`
|
|
- `e.add_f32(val f32)`
|
|
- `e.add_f64(val f64)`
|
|
- `e.add_string(val string)`
|
|
- `e.add_list_bool(val []bool)`
|
|
- `e.add_list_u8(val []u8)`
|
|
- `e.add_list_u16(val []u16)`
|
|
- `e.add_list_u32(val []u32)`
|
|
- `e.add_list_u64(val []u64)`
|
|
- `e.add_list_i8(val []i8)`
|
|
- `e.add_list_i16(val []i16)`
|
|
- `e.add_list_i32(val []i32)`
|
|
- `e.add_list_i64(val []i64)`
|
|
- `e.add_list_f32(val []f32)`
|
|
- `e.add_list_f64(val []f64)`
|
|
- `e.add_list_string(val []string)`
|
|
|
|
### Decoder (Deserialization)
|
|
|
|
- `e.get_bool()!`
|
|
- `e.get_u8()!`
|
|
- `e.get_u16()!`
|
|
- `e.get_u32()!`
|
|
- `e.get_u64()!`
|
|
- `e.get_i8()!`
|
|
- `e.get_i16()!`
|
|
- `e.get_i32()!`
|
|
- `e.get_i64()!`
|
|
- `e.get_f32()!`
|
|
- `e.get_f64()!`
|
|
- `e.get_string()!`
|
|
- `e.get_list_bool()!`
|
|
- `e.get_list_u8()!`
|
|
- `e.get_list_u16()!`
|
|
- `e.get_list_u32()!`
|
|
- `e.get_list_u64()!`
|
|
- `e.get_list_i8()!`
|
|
- `e.get_list_i16()!`
|
|
- `e.get_list_i32()!`
|
|
- `e.get_list_i64()!`
|
|
- `e.get_list_f32()!`
|
|
- `e.get_list_f64()!`
|
|
- `e.get_list_string()!`
|
|
|
|
## CRUD Methods Implementation
|
|
|
|
### Create New Instance
|
|
|
|
```v
|
|
pub fn (mut self DBCalendar) new(args CalendarArg) !Calendar {
|
|
mut o := Calendar{
|
|
title: args.title
|
|
start_time: args.start_time
|
|
end_time: args.end_time
|
|
location: args.location
|
|
attendees: args.attendees
|
|
updated_at: ourtime.now().unix()
|
|
}
|
|
return o
|
|
}
|
|
```
|
|
|
|
### Save to Database
|
|
|
|
```v
|
|
pub fn (mut self DBCalendar) set(o Calendar) !u32 {
|
|
return self.db.set[Calendar](o)!
|
|
}
|
|
```
|
|
|
|
### Retrieve from Database
|
|
|
|
```v
|
|
pub fn (mut self DBCalendar) get(id u32) !Calendar {
|
|
mut o, data := self.db.get_data[Calendar](id)!
|
|
mut e_decoder := encoder.decoder_new(data)
|
|
self.load(mut o, mut e_decoder)!
|
|
return o
|
|
}
|
|
```
|
|
|
|
### Delete from Database
|
|
|
|
```v
|
|
pub fn (mut self DBCalendar) delete(id u32) ! {
|
|
self.db.delete[Calendar](id)!
|
|
}
|
|
```
|
|
|
|
### Check Existence
|
|
|
|
```v
|
|
pub fn (mut self DBCalendar) exist(id u32) !bool {
|
|
return self.db.exists[Calendar](id)!
|
|
}
|
|
```
|
|
|
|
### List All Objects
|
|
|
|
```v
|
|
pub fn (mut self DBCalendar) list() ![]Calendar {
|
|
return self.db.list[Calendar]()!.map(self.get(it)!)
|
|
}
|
|
```
|
|
|
|
## Example Usage Script
|
|
|
|
Create a `.vsh` script in `examples/hero/heromodels/` to demonstrate usage:
|
|
|
|
```v
|
|
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
|
|
|
import incubaid.herolib.core.redisclient
|
|
import incubaid.herolib.hero.heromodels
|
|
|
|
mut mydb := heromodels.new()!
|
|
|
|
// Create a new object
|
|
mut o := mydb.calendar.new(
|
|
title: 'Meeting'
|
|
start_time: 1672531200
|
|
end_time: 1672534800
|
|
location: 'Conference Room'
|
|
attendees: ['john@example.com', 'jane@example.com']
|
|
)!
|
|
|
|
// Save to database
|
|
oid := mydb.calendar.set(o)!
|
|
println('Created object with ID: ${oid}')
|
|
|
|
// Retrieve from database
|
|
mut o2 := mydb.calendar.get(oid)!
|
|
println('Retrieved object: ${o2}')
|
|
|
|
// List all objects
|
|
mut objects := mydb.calendar.list()!
|
|
println('All objects: ${objects}')
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. Always inherit from `db.Base` struct
|
|
2. Implement all required methods (`type_name`, `dump`, `load`)
|
|
3. Use the encoder methods for consistent serialization
|
|
4. Handle errors appropriately with `!` or `or` blocks
|
|
5. Keep field ordering consistent between `dump` and `load` methods
|
|
6. Use snake_case for field names
|
|
7. Add `@[required]` attribute to mandatory fields in argument structs
|
|
8. Initialize timestamps using `ourtime.now().unix()`
|
|
|
|
## Implementation Steps Summary
|
|
|
|
1. Create model struct inheriting from `db.Base`
|
|
2. Implement `type_name()` method
|
|
3. Implement `dump()` method using encoder
|
|
4. Implement `load()` method using decoder
|
|
5. Create argument struct with `@[params]` attribute
|
|
6. Create database wrapper struct
|
|
7. Add model to `ModelsFactory` in `factory.v`
|
|
8. Implement CRUD methods
|
|
9. Create example usage script
|
|
10. Test the implementation with the example script
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/lib/hero/db/core_methods.v
|
|
```v
|
|
module db
|
|
|
|
import incubaid.herolib.data.ourtime
|
|
import incubaid.herolib.data.encoder
|
|
|
|
pub fn (mut self DB) set[T](obj_ T) !u32 {
|
|
// Get the next ID
|
|
mut obj := obj_
|
|
if obj.id == 0 {
|
|
obj.id = self.new_id()!
|
|
}
|
|
mut t := ourtime.now().unix()
|
|
if obj.created_at == 0 {
|
|
obj.created_at = t
|
|
}
|
|
obj.updated_at = t
|
|
|
|
// id u32
|
|
// name string
|
|
// description string
|
|
// created_at i64
|
|
// updated_at i64
|
|
// securitypolicy u32
|
|
// tags u32 // when we set/get we always do as []string but this can then be sorted and md5ed this gies the unique id of tags
|
|
// comments []u32
|
|
mut e := encoder.new()
|
|
e.add_u8(1)
|
|
e.add_u32(obj.id)
|
|
e.add_string(obj.name)
|
|
e.add_string(obj.description)
|
|
e.add_i64(obj.created_at)
|
|
e.add_i64(obj.updated_at)
|
|
e.add_u32(obj.securitypolicy)
|
|
e.add_u32(obj.tags)
|
|
e.add_u16(u16(obj.comments.len))
|
|
for comment in obj.comments {
|
|
e.add_u32(comment)
|
|
}
|
|
// println('set: before dump, e.data.len: ${e.data.len}')
|
|
obj.dump(mut e)!
|
|
// println('set: after dump, e.data.len: ${e.data.len}')
|
|
self.redis.hset(self.db_name[T](), obj.id.str(), e.data.bytestr())!
|
|
return obj.id
|
|
}
|
|
|
|
// return the data, cannot return the object as we do not know the type
|
|
pub fn (mut self DB) get_data[T](id u32) !(T, []u8) {
|
|
data := self.redis.hget(self.db_name[T](), id.str())!
|
|
|
|
if data.len == 0 {
|
|
return error('herodb:${self.db_name[T]()} not found for ${id}')
|
|
}
|
|
|
|
// println('get_data: data.len: ${data.len}')
|
|
mut e := encoder.decoder_new(data.bytes())
|
|
version := e.get_u8()!
|
|
if version != 1 {
|
|
panic('wrong version in base load')
|
|
}
|
|
mut base := T{}
|
|
base.id = e.get_u32()!
|
|
base.name = e.get_string()!
|
|
base.description = e.get_string()!
|
|
base.created_at = e.get_i64()!
|
|
base.updated_at = e.get_i64()!
|
|
base.securitypolicy = e.get_u32()!
|
|
base.tags = e.get_u32()!
|
|
for _ in 0 .. e.get_u16()! {
|
|
base.comments << e.get_u32()!
|
|
}
|
|
return base, e.data
|
|
}
|
|
|
|
pub fn (mut self DB) exists[T](id u32) !bool {
|
|
return self.redis.hexists(self.db_name[T](), id.str())!
|
|
}
|
|
|
|
pub fn (mut self DB) delete[T](id u32) ! {
|
|
self.redis.hdel(self.db_name[T](), id.str())!
|
|
}
|
|
|
|
pub fn (mut self DB) list[T]() ![]u32 {
|
|
ids := self.redis.hkeys(self.db_name[T]())!
|
|
return ids.map(it.u32())
|
|
}
|
|
|
|
// make it easy to get a base object
|
|
pub fn (mut self DB) new_from_base[T](args BaseArgs) !Base {
|
|
return T{
|
|
Base: new_base(args)!
|
|
}
|
|
}
|
|
|
|
fn (mut self DB) db_name[T]() string {
|
|
// get the name of the type T
|
|
mut name := T.name.to_lower_ascii().split('.').last()
|
|
// println("db_name rediskey: '${name}'")
|
|
return 'db:${name}'
|
|
}
|
|
|
|
pub fn (mut self DB) new_id() !u32 {
|
|
return u32(self.redis.incr('db:id')!)
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/lib/hero/db/core_models.v
|
|
|
|
```v
|
|
module db
|
|
|
|
import crypto.md5
|
|
import incubaid.herolib.core.redisclient
|
|
import incubaid.herolib.data.ourtime
|
|
|
|
// Group represents a collection of users with roles and permissions
|
|
@[heap]
|
|
pub struct Base {
|
|
pub mut:
|
|
id u32
|
|
name string
|
|
description string
|
|
created_at i64
|
|
updated_at i64
|
|
securitypolicy u32
|
|
tags u32 // when we set/get we always do as []string but this can then be sorted and md5ed this gies the unique id of tags
|
|
comments []u32
|
|
}
|
|
|
|
@[heap]
|
|
pub struct SecurityPolicy {
|
|
pub mut:
|
|
id u32
|
|
read []u32 // links to users & groups
|
|
write []u32 // links to users & groups
|
|
delete []u32 // links to users & groups
|
|
public bool
|
|
md5 string // this sorts read, write and delete u32 + hash, then do md5 hash, this allows to go from a random read/write/delete/public config to a hash
|
|
}
|
|
|
|
@[heap]
|
|
pub struct Tags {
|
|
pub mut:
|
|
id u32
|
|
names []string // unique per id
|
|
md5 string // of sorted names, to make easy to find unique id, each name lowercased and made ascii
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/lib/hero/db/helpers_comments.v
|
|
|
|
```v
|
|
module db
|
|
|
|
import crypto.md5
|
|
|
|
|
|
@[params]
|
|
pub struct CommentArg {
|
|
pub mut:
|
|
comment string
|
|
parent u32
|
|
author u32
|
|
}
|
|
|
|
pub fn (mut self DB) comments_get(args []CommentArg) ![]u32 {
|
|
return args.map(self.comment_get(it.comment)!)
|
|
}
|
|
|
|
pub fn (mut self DB) comment_get(comment string) !u32 {
|
|
comment_fixed := comment.to_lower_ascii().trim_space()
|
|
return if comment_fixed.len > 0 {
|
|
hash := md5.hexhash(comment_fixed)
|
|
comment_found := self.redis.hget('db:comments', hash)!
|
|
if comment_found == '' {
|
|
id := self.new_id()!
|
|
self.redis.hset('db:comments', hash, id.str())!
|
|
self.redis.hset('db:comments', id.str(), comment_fixed)!
|
|
id
|
|
} else {
|
|
comment_found.u32()
|
|
}
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/lib/hero/db/helpers_tags.v
|
|
|
|
```v
|
|
module db
|
|
|
|
import crypto.md5
|
|
|
|
pub fn (mut self DB) tags_get(tags []string) !u32 {
|
|
return if tags.len > 0 {
|
|
mut tags_fixed := tags.map(it.to_lower_ascii().trim_space()).filter(it != '')
|
|
tags_fixed.sort_ignore_case()
|
|
hash := md5.hexhash(tags_fixed.join(','))
|
|
tags_found := self.redis.hget('db:tags', hash)!
|
|
return if tags_found == '' {
|
|
println('tags_get: new tags: ${tags_fixed.join(",")}')
|
|
id := self.new_id()!
|
|
self.redis.hset('db:tags', hash, id.str())!
|
|
self.redis.hset('db:tags', id.str(), tags_fixed.join(','))!
|
|
id
|
|
} else {
|
|
tags_found.u32()
|
|
}
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
|
|
```
|
|
|
|
File: /Users/despiegk/code/github/incubaid/herolib/lib/hero/heromodels/calendar_event.v
|
|
|
|
```v
|
|
|
|
module heromodels
|
|
|
|
import incubaid.herolib.data.encoder
|
|
import incubaid.herolib.data.ourtime
|
|
import incubaid.herolib.hero.db
|
|
|
|
// CalendarEvent represents a single event in a calendar
|
|
@[heap]
|
|
pub struct CalendarEvent {
|
|
db.Base
|
|
pub mut:
|
|
title string
|
|
start_time i64 // Unix timestamp
|
|
end_time i64 // Unix timestamp
|
|
location string
|
|
attendees []u32 // IDs of user groups
|
|
fs_items []u32 // IDs of linked files or dirs
|
|
calendar_id u32 // Associated calendar
|
|
status EventStatus
|
|
is_all_day bool
|
|
is_recurring bool
|
|
recurrence []RecurrenceRule // normally empty
|
|
reminder_mins []int // Minutes before event for reminders
|
|
color string // Hex color code
|
|
timezone string
|
|
}
|
|
|
|
pub struct Attendee {
|
|
pub mut:
|
|
user_id u32
|
|
status AttendanceStatus
|
|
role AttendeeRole
|
|
}
|
|
|
|
pub enum AttendanceStatus {
|
|
no_response
|
|
accepted
|
|
declined
|
|
tentative
|
|
}
|
|
|
|
pub enum AttendeeRole {
|
|
required
|
|
optional
|
|
organizer
|
|
}
|
|
|
|
pub enum EventStatus {
|
|
draft
|
|
published
|
|
cancelled
|
|
completed
|
|
}
|
|
|
|
pub struct RecurrenceRule {
|
|
pub mut:
|
|
frequency RecurrenceFreq
|
|
interval int // Every N frequencies
|
|
until i64 // End date (Unix timestamp)
|
|
count int // Number of occurrences
|
|
by_weekday []int // Days of week (0=Sunday)
|
|
by_monthday []int // Days of month
|
|
}
|
|
|
|
pub enum RecurrenceFreq {
|
|
none
|
|
daily
|
|
weekly
|
|
monthly
|
|
yearly
|
|
}
|
|
|
|
pub struct DBCalendarEvent {
|
|
pub mut:
|
|
db &db.DB @[skip; str: skip]
|
|
}
|
|
|
|
pub fn (self CalendarEvent) type_name() string {
|
|
return 'calendar_event'
|
|
}
|
|
|
|
pub fn (self CalendarEvent) dump(mut e &encoder.Encoder) ! {
|
|
e.add_string(self.title)
|
|
e.add_i64(self.start_time)
|
|
e.add_i64(self.end_time)
|
|
e.add_string(self.location)
|
|
e.add_list_u32(self.attendees)
|
|
e.add_list_u32(self.fs_items)
|
|
e.add_u32(self.calendar_id)
|
|
e.add_u8(u8(self.status))
|
|
e.add_bool(self.is_all_day)
|
|
e.add_bool(self.is_recurring)
|
|
|
|
// Encode recurrence array
|
|
e.add_u16(u16(self.recurrence.len))
|
|
for rule in self.recurrence {
|
|
e.add_u8(u8(rule.frequency))
|
|
e.add_int(rule.interval)
|
|
e.add_i64(rule.until)
|
|
e.add_int(rule.count)
|
|
e.add_list_int(rule.by_weekday)
|
|
e.add_list_int(rule.by_monthday)
|
|
}
|
|
|
|
e.add_list_int(self.reminder_mins)
|
|
e.add_string(self.color)
|
|
e.add_string(self.timezone)
|
|
}
|
|
|
|
fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e &encoder.Decoder) ! {
|
|
o.title = e.get_string()!
|
|
o.start_time = e.get_i64()!
|
|
o.end_time = e.get_i64()!
|
|
o.location = e.get_string()!
|
|
o.attendees = e.get_list_u32()!
|
|
o.fs_items = e.get_list_u32()!
|
|
o.calendar_id = e.get_u32()!
|
|
o.status = unsafe { EventStatus(e.get_u8()!) } //TODO: is there no better way?
|
|
o.is_all_day = e.get_bool()!
|
|
o.is_recurring = e.get_bool()!
|
|
|
|
// Decode recurrence array
|
|
recurrence_len := e.get_u16()!
|
|
mut recurrence := []RecurrenceRule{}
|
|
for _ in 0 .. recurrence_len {
|
|
frequency := unsafe { RecurrenceFreq(e.get_u8()!) }
|
|
interval := e.get_int()!
|
|
until := e.get_i64()!
|
|
count := e.get_int()!
|
|
by_weekday := e.get_list_int()!
|
|
by_monthday := e.get_list_int()!
|
|
|
|
recurrence << RecurrenceRule{
|
|
frequency: frequency
|
|
interval: interval
|
|
until: until
|
|
count: count
|
|
by_weekday: by_weekday
|
|
by_monthday: by_monthday
|
|
}
|
|
}
|
|
o.recurrence = recurrence
|
|
|
|
o.reminder_mins = e.get_list_int()!
|
|
o.color = e.get_string()!
|
|
o.timezone = e.get_string()!
|
|
}
|
|
|
|
@[params]
|
|
pub struct CalendarEventArg {
|
|
pub mut:
|
|
name string
|
|
description string
|
|
title string
|
|
start_time string // use ourtime module to go from string to epoch
|
|
end_time string // use ourtime module to go from string to epoch
|
|
location string
|
|
attendees []u32 // IDs of user groups
|
|
fs_items []u32 // IDs of linked files or dirs
|
|
calendar_id u32 // Associated calendar
|
|
status EventStatus
|
|
is_all_day bool
|
|
is_recurring bool
|
|
recurrence []RecurrenceRule
|
|
reminder_mins []int // Minutes before event for reminders
|
|
color string // Hex color code
|
|
timezone string
|
|
securitypolicy u32
|
|
tags []string
|
|
comments []db.CommentArg
|
|
}
|
|
|
|
// get new calendar event, not from the DB
|
|
pub fn (mut self DBCalendarEvent) new(args CalendarEventArg) !CalendarEvent {
|
|
mut o := CalendarEvent{
|
|
title: args.title
|
|
location: args.location
|
|
attendees: args.attendees
|
|
fs_items: args.fs_items
|
|
calendar_id: args.calendar_id
|
|
status: args.status
|
|
is_all_day: args.is_all_day
|
|
is_recurring: args.is_recurring
|
|
recurrence: args.recurrence
|
|
reminder_mins: args.reminder_mins
|
|
color: args.color
|
|
timezone: args.timezone
|
|
}
|
|
|
|
// Set base fields
|
|
o.name = args.name
|
|
o.description = args.description
|
|
o.securitypolicy = args.securitypolicy
|
|
o.tags = self.db.tags_get(args.tags)!
|
|
o.comments = self.db.comments_get(args.comments)!
|
|
o.updated_at = ourtime.now().unix()
|
|
|
|
// Convert string times to Unix timestamps
|
|
mut start_time_obj := ourtime.new(args.start_time)!
|
|
o.start_time = start_time_obj.unix()
|
|
|
|
mut end_time_obj := ourtime.new(args.end_time)!
|
|
o.end_time = end_time_obj.unix()
|
|
|
|
return o
|
|
}
|
|
|
|
pub fn (mut self DBCalendarEvent) set(o CalendarEvent) !u32 {
|
|
// Use db set function which now returns the ID
|
|
return self.db.set[CalendarEvent](o)!
|
|
}
|
|
|
|
pub fn (mut self DBCalendarEvent) delete(id u32) ! {
|
|
self.db.delete[CalendarEvent](id)!
|
|
}
|
|
|
|
pub fn (mut self DBCalendarEvent) exist(id u32) !bool {
|
|
return self.db.exists[CalendarEvent](id)!
|
|
}
|
|
|
|
pub fn (mut self DBCalendarEvent) get(id u32) !CalendarEvent {
|
|
mut o, data := self.db.get_data[CalendarEvent](id)!
|
|
mut e_decoder := encoder.decoder_new(data)
|
|
self.load(mut o, mut e_decoder)!
|
|
return o
|
|
}
|
|
|
|
pub fn (mut self DBCalendarEvent) list() ![]CalendarEvent {
|
|
return self.db.list[CalendarEvent]()!.map(self.get(it)!)
|
|
}
|
|
|
|
```
|
|
|
|
</file_contents>
|
|
<user_instructions>
|
|
make the crud and example for all files in lib/hero/herofs
|
|
|
|
think about which additional hsets we need to make it efficient
|
|
|
|
check the implementation
|
|
|
|
do the implementation
|
|
|
|
</user_instructions>
|