refactor(store): replace project and skill models with generated models
Some checks failed
CI / build-and-test (push) Failing after -31m25s

* Update project creation and retrieval to use generated models
* Modify skill addition and listing to utilize generated models
* Refactor thought handling to incorporate generated models
* Adjust tool annotations to align with new model structure
* Update API calls in the UI to use new ResolveSpec-based endpoints
* Enhance stats retrieval logic to aggregate thought metadata
This commit is contained in:
2026-04-26 12:56:32 +02:00
parent da7220ad64
commit db7b152852
53 changed files with 3638 additions and 426 deletions

View File

@@ -12,6 +12,7 @@ RELSPEC ?= $(shell command -v relspec 2>/dev/null || echo $(HOME)/go/bin/relspec
SCHEMA_FILES := $(sort $(wildcard schema/*.dbml)) SCHEMA_FILES := $(sort $(wildcard schema/*.dbml))
MERGE_TARGET_TMP := $(CURDIR)/.cache/schema.merge-target.dbml MERGE_TARGET_TMP := $(CURDIR)/.cache/schema.merge-target.dbml
GENERATED_SCHEMA_MIGRATION := migrations/020_generated_schema.sql GENERATED_SCHEMA_MIGRATION := migrations/020_generated_schema.sql
GENERATED_MODELS_DIR := internal/generatedmodels
PNPM ?= pnpm PNPM ?= pnpm
LDFLAGS := -s -w \ LDFLAGS := -s -w \
-X $(BUILDINFO_PKG).Version=$(VERSION_TAG) \ -X $(BUILDINFO_PKG).Version=$(VERSION_TAG) \
@@ -19,7 +20,7 @@ LDFLAGS := -s -w \
-X $(BUILDINFO_PKG).Commit=$(COMMIT_SHA) \ -X $(BUILDINFO_PKG).Commit=$(COMMIT_SHA) \
-X $(BUILDINFO_PKG).BuildDate=$(BUILD_DATE) -X $(BUILDINFO_PKG).BuildDate=$(BUILD_DATE)
.PHONY: all build clean migrate release-version test generate-migrations check-schema-drift build-cli ui-install ui-build ui-dev ui-check .PHONY: all build clean migrate release-version test generate-migrations generate-models check-schema-drift build-cli ui-install ui-build ui-dev ui-check
all: build all: build
@@ -78,6 +79,10 @@ generate-migrations:
@schema_list=$$(printf '%s\n' $(SCHEMA_FILES) | paste -sd, -); \ @schema_list=$$(printf '%s\n' $(SCHEMA_FILES) | paste -sd, -); \
$(RELSPEC) merge --target dbml --target-path $(MERGE_TARGET_TMP) --source dbml --from-list "$$schema_list" --output pgsql --output-path $(GENERATED_SCHEMA_MIGRATION) $(RELSPEC) merge --target dbml --target-path $(MERGE_TARGET_TMP) --source dbml --from-list "$$schema_list" --output pgsql --output-path $(GENERATED_SCHEMA_MIGRATION)
generate-models:
@test -n "$(SCHEMA_FILES)" || (echo "No DBML schema files found in schema/" >&2; exit 1)
@./scripts/generate-models.sh
check-schema-drift: check-schema-drift:
@test -f $(GENERATED_SCHEMA_MIGRATION) || (echo "$(GENERATED_SCHEMA_MIGRATION) is missing; run make generate-migrations" >&2; exit 1) @test -f $(GENERATED_SCHEMA_MIGRATION) || (echo "$(GENERATED_SCHEMA_MIGRATION) is missing; run make generate-migrations" >&2; exit 1)
@command -v $(RELSPEC) >/dev/null 2>&1 || (echo "relspec not found; install git.warky.dev/wdevs/relspecgo/cmd/relspec@latest" >&2; exit 1) @command -v $(RELSPEC) >/dev/null 2>&1 || (echo "relspec not found; install git.warky.dev/wdevs/relspecgo/cmd/relspec@latest" >&2; exit 1)

64
go.mod
View File

@@ -3,29 +3,85 @@ module git.warky.dev/wdevs/amcs
go 1.26.1 go 1.26.1
require ( require (
github.com/bitechdev/ResolveSpec v1.0.86
github.com/google/jsonschema-go v0.4.2 github.com/google/jsonschema-go v0.4.2
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/jackc/pgx/v5 v5.9.1 github.com/jackc/pgx/v5 v5.9.1
github.com/modelcontextprotocol/go-sdk v1.4.1 github.com/modelcontextprotocol/go-sdk v1.4.1
github.com/pgvector/pgvector-go v0.3.0 github.com/pgvector/pgvector-go v0.3.0
github.com/spf13/cobra v1.10.2 github.com/spf13/cobra v1.10.2
golang.org/x/sync v0.17.0 github.com/uptrace/bun v1.2.16
github.com/uptrace/bun/dialect/pgdialect v1.2.16
github.com/uptrace/bun/driver/pgdriver v1.1.12
github.com/uptrace/bunrouter v1.0.23
golang.org/x/sync v0.19.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
require ( require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/getsentry/sentry-go v0.40.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/kr/text v0.2.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-sqlite3 v1.14.33 // indirect
github.com/microsoft/go-mssqldb v1.9.5 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.4 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
github.com/redis/go-redis/v9 v9.17.2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/sagikazarmark/locafero v0.12.0 // indirect
github.com/segmentio/asm v1.1.3 // indirect github.com/segmentio/asm v1.1.3 // indirect
github.com/segmentio/encoding v0.5.4 // indirect github.com/segmentio/encoding v0.5.4 // indirect
github.com/spf13/pflag v1.0.9 // indirect github.com/shopspring/decimal v1.4.0 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/spf13/viper v1.21.0 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/match v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/uptrace/bun/dialect/mssqldialect v1.2.16 // indirect
github.com/uptrace/bun/dialect/sqlitedialect v1.2.16 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.1 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sys v0.40.0 // indirect golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.29.0 // indirect golang.org/x/text v0.32.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gorm.io/driver/postgres v1.6.0 // indirect
gorm.io/driver/sqlite v1.6.0 // indirect
gorm.io/driver/sqlserver v1.6.3 // indirect
gorm.io/gorm v1.31.1 // indirect
mellium.im/sasl v0.3.1 // indirect
) )

415
go.sum
View File

@@ -1,22 +1,127 @@
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
entgo.io/ent v0.14.3 h1:wokAV/kIlH9TeklJWGGS7AYJdVckr0DloWjIcO9iIIQ= entgo.io/ent v0.14.3 h1:wokAV/kIlH9TeklJWGGS7AYJdVckr0DloWjIcO9iIIQ=
entgo.io/ent v0.14.3/go.mod h1:aDPE/OziPEu8+OWbzy4UlvWmD2/kbRuWfK2A40hcxJM= entgo.io/ent v0.14.3/go.mod h1:aDPE/OziPEu8+OWbzy4UlvWmD2/kbRuWfK2A40hcxJM=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1/go.mod h1:uE9zaUfEQT/nbQjVi2IblCG9iaLtZsuYZ8ne+PuQ02M=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1/go.mod h1:GpPjLhVR9dnUoJMyHWSPy71xY9/lcmpzIPZXmF0FCVY=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bitechdev/ResolveSpec v1.0.86 h1:a4yFMMDizrmvDOV61cj/+kD+mEtKL/5EIHY2GcP3uJU=
github.com/bitechdev/ResolveSpec v1.0.86/go.mod h1:YZOY2YCD0Kmb+pjAMhOqPh4q82Hij57F/CLlCMkzT78=
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I=
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/docker v28.5.1+incompatible h1:Bm8DchhSD2J6PsFzxC35TZo4TLGR2PdW/E69rU45NhM=
github.com/docker/docker v28.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/getsentry/sentry-go v0.40.0 h1:VTJMN9zbTvqDqPwheRVLcp0qcUcM+8eFivvGocAaSbo=
github.com/getsentry/sentry-go v0.40.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-pg/pg/v10 v10.11.0 h1:CMKJqLgTrfpE/aOVeLdybezR2om071Vh38OLZjsyMI0= github.com/go-pg/pg/v10 v10.11.0 h1:CMKJqLgTrfpE/aOVeLdybezR2om071Vh38OLZjsyMI0=
github.com/go-pg/pg/v10 v10.11.0/go.mod h1:4BpHRoxE61y4Onpof3x1a2SQvi9c+q1dJnrNdMjsroA= github.com/go-pg/pg/v10 v10.11.0/go.mod h1:4BpHRoxE61y4Onpof3x1a2SQvi9c+q1dJnrNdMjsroA=
github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU=
github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8=
github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
@@ -27,52 +132,181 @@ github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc=
github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0=
github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/microsoft/go-mssqldb v1.8.2/go.mod h1:vp38dT33FGfVotRiTmDo3bFyaHq+p3LektQrjTULowo=
github.com/microsoft/go-mssqldb v1.9.5 h1:orwya0X/5bsL1o+KasupTkk2eNTNFkTQG0BEe/HxCn0=
github.com/microsoft/go-mssqldb v1.9.5/go.mod h1:VCP2a0KEZZtGLRHd1PsLavLFYy/3xX2yJUPycv3Sr2Q=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modelcontextprotocol/go-sdk v1.4.1 h1:M4x9GyIPj+HoIlHNGpK2hq5o3BFhC+78PkEaldQRphc= github.com/modelcontextprotocol/go-sdk v1.4.1 h1:M4x9GyIPj+HoIlHNGpK2hq5o3BFhC+78PkEaldQRphc=
github.com/modelcontextprotocol/go-sdk v1.4.1/go.mod h1:Bo/mS87hPQqHSRkMv4dQq1XCu6zv4INdXnFZabkNU6s= github.com/modelcontextprotocol/go-sdk v1.4.1/go.mod h1:Bo/mS87hPQqHSRkMv4dQq1XCu6zv4INdXnFZabkNU6s=
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pgvector/pgvector-go v0.3.0 h1:Ij+Yt78R//uYqs3Zk35evZFvr+G0blW0OUN+Q2D1RWc= github.com/pgvector/pgvector-go v0.3.0 h1:Ij+Yt78R//uYqs3Zk35evZFvr+G0blW0OUN+Q2D1RWc=
github.com/pgvector/pgvector-go v0.3.0/go.mod h1:duFy+PXWfW7QQd5ibqutBO4GxLsUZ9RVXhFZGIBsWSA= github.com/pgvector/pgvector-go v0.3.0/go.mod h1:duFy+PXWfW7QQd5ibqutBO4GxLsUZ9RVXhFZGIBsWSA=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc=
github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/redis/go-redis/v9 v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4ViluI=
github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc= github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg= github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0= github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0=
github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0= github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs=
github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/testcontainers/testcontainers-go v0.40.0 h1:pSdJYLOVgLE8YdUY2FHQ1Fxu+aMnb6JfVz1mxk7OeMU=
github.com/testcontainers/testcontainers-go v0.40.0/go.mod h1:FSXV5KQtX2HAMlm7U3APNyLkkap35zNLxukw9oBi/MY=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
github.com/uptrace/bun v1.1.12 h1:sOjDVHxNTuM6dNGaba0wUuz7KvDE1BmNu9Gqs2gJSXQ= github.com/uptrace/bun v1.2.16 h1:QlObi6ZIK5Ao7kAALnh91HWYNZUBbVwye52fmlQM9kc=
github.com/uptrace/bun v1.1.12/go.mod h1:NPG6JGULBeQ9IU6yHp7YGELRa5Agmd7ATZdz4tGZ6z0= github.com/uptrace/bun v1.2.16/go.mod h1:jMoNg2n56ckaawi/O/J92BHaECmrz6IRjuMWqlMaMTM=
github.com/uptrace/bun/dialect/pgdialect v1.1.12 h1:m/CM1UfOkoBTglGO5CUTKnIKKOApOYxkcP2qn0F9tJk= github.com/uptrace/bun/dialect/mssqldialect v1.2.16 h1:rKv0cKPNBviXadB/+2Y/UedA/c1JnwGzUWZkdN5FdSQ=
github.com/uptrace/bun/dialect/pgdialect v1.1.12/go.mod h1:Ij6WIxQILxLlL2frUBxUBOZJtLElD2QQNDcu/PWDHTc= github.com/uptrace/bun/dialect/mssqldialect v1.2.16/go.mod h1:J5U7tGKWDsx2Q7MwDZF2417jCdpD6yD/ZMFJcCR80bk=
github.com/uptrace/bun/dialect/pgdialect v1.2.16 h1:KFNZ0LxAyczKNfK/IJWMyaleO6eI9/Z5tUv3DE1NVL4=
github.com/uptrace/bun/dialect/pgdialect v1.2.16/go.mod h1:IJdMeV4sLfh0LDUZl7TIxLI0LipF1vwTK3hBC7p5qLo=
github.com/uptrace/bun/dialect/sqlitedialect v1.2.16 h1:6wVAiYLj1pMibRthGwy4wDLa3D5AQo32Y8rvwPd8CQ0=
github.com/uptrace/bun/dialect/sqlitedialect v1.2.16/go.mod h1:Z7+5qK8CGZkDQiPMu+LSdVuDuR1I5jcwtkB1Pi3F82E=
github.com/uptrace/bun/driver/pgdriver v1.1.12 h1:3rRWB1GK0psTJrHwxzNfEij2MLibggiLdTqjTtfHc1w= github.com/uptrace/bun/driver/pgdriver v1.1.12 h1:3rRWB1GK0psTJrHwxzNfEij2MLibggiLdTqjTtfHc1w=
github.com/uptrace/bun/driver/pgdriver v1.1.12/go.mod h1:ssYUP+qwSEgeDDS1xm2XBip9el1y9Mi5mTAvLoiADLM= github.com/uptrace/bun/driver/pgdriver v1.1.12/go.mod h1:ssYUP+qwSEgeDDS1xm2XBip9el1y9Mi5mTAvLoiADLM=
github.com/uptrace/bun/driver/sqliteshim v1.2.16 h1:M6Dh5kkDWFbUWBrOsIE1g1zdZ5JbSytTD4piFRBOUAI=
github.com/uptrace/bun/driver/sqliteshim v1.2.16/go.mod h1:iKdJ06P3XS+pwKcONjSIK07bbhksH3lWsw3mpfr0+bY=
github.com/uptrace/bunrouter v1.0.23 h1:Bi7NKw3uCQkcA/GUCtDNPq5LE5UdR9pe+UyWbjHB/wU=
github.com/uptrace/bunrouter v1.0.23/go.mod h1:O3jAcl+5qgnF+ejhgkmbceEk0E/mqaK+ADOocdNpY8M=
github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94=
github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ=
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
@@ -81,28 +315,171 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0= gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
gorm.io/driver/sqlserver v1.6.3 h1:UR+nWCuphPnq7UxnL57PSrlYjuvs+sf1N59GgFX7uAI=
gorm.io/driver/sqlserver v1.6.3/go.mod h1:VZeNn7hqX1aXoN5TPAFGWvxWG90xtA8erGn2gQmpc6U=
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo=
mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw=
modernc.org/libc v1.67.4 h1:zZGmCMUVPORtKv95c2ReQN5VDjvkoRm9GWPTEPuvlWg=
modernc.org/libc v1.67.4/go.mod h1:QvvnnJ5P7aitu0ReNpVIEyesuhmDLQ8kaEoyMjIFZJA=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/sqlite v1.42.2 h1:7hkZUNJvJFN2PgfUdjni9Kbvd4ef4mNLOu0B9FGxM74=
modernc.org/sqlite v1.42.2/go.mod h1:+VkC6v3pLOAE0A0uVucQEcbVW0I5nHCeDaBf+DpsQT8=

View File

@@ -1,4 +1,5 @@
package app package app
// Legacy admin handlers retired in favor of ResolveSpec-backed routes.
import ( import (
"encoding/json" "encoding/json"
@@ -265,4 +266,3 @@ func parseUUID(w http.ResponseWriter, s string) (uuid.UUID, bool) {
} }
return id, true return id, true
} }

View File

@@ -227,7 +227,9 @@ func routes(logger *slog.Logger, cfg *config.Config, info buildinfo.Info, db *st
mux.Handle(cfg.MCP.SSEPath, authMiddleware(mcpHandlers.SSE)) mux.Handle(cfg.MCP.SSEPath, authMiddleware(mcpHandlers.SSE))
logger.Info("SSE transport enabled", slog.String("sse_path", cfg.MCP.SSEPath)) logger.Info("SSE transport enabled", slog.String("sse_path", cfg.MCP.SSEPath))
} }
newAdminHandlers(db, logger).register(mux, authMiddleware) if err := registerResolveSpecAdminRoutes(mux, db, authMiddleware, logger); err != nil {
return nil, fmt.Errorf("setup resolvespec admin routes: %w", err)
}
mux.Handle("/files", authMiddleware(fileHandler(filesTool))) mux.Handle("/files", authMiddleware(fileHandler(filesTool)))
mux.Handle("/files/{id}", authMiddleware(fileHandler(filesTool))) mux.Handle("/files/{id}", authMiddleware(fileHandler(filesTool)))
mux.HandleFunc("/.well-known/oauth-authorization-server", oauthMetadataHandler()) mux.HandleFunc("/.well-known/oauth-authorization-server", oauthMetadataHandler())

View File

@@ -0,0 +1,128 @@
package app
import (
"fmt"
"log/slog"
"net/http"
"github.com/bitechdev/ResolveSpec/pkg/resolvespec"
"github.com/uptrace/bunrouter"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
"git.warky.dev/wdevs/amcs/internal/store"
)
func registerResolveSpecAdminRoutes(mux *http.ServeMux, db *store.DB, middleware func(http.Handler) http.Handler, logger *slog.Logger) error {
rs := resolvespec.NewHandlerWithBun(db.Bun())
registerResolveSpecGuards(rs)
for _, model := range resolveSpecModels() {
if err := rs.RegisterModel(model.schema, model.entity, model.model); err != nil {
return fmt.Errorf("register resolvespec model %s.%s: %w", model.schema, model.entity, err)
}
}
rsRouter := bunrouter.New()
resolvespec.SetupBunRouterRoutes(rsRouter, rs, nil)
rsMount := http.StripPrefix("/api/rs", rsRouter)
protectedRSMount := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodOptions {
rsMount.ServeHTTP(w, r)
return
}
middleware(rsMount).ServeHTTP(w, r)
})
mux.Handle("/api/rs/", protectedRSMount)
mux.Handle("/api/rs", http.RedirectHandler("/api/rs/openapi", http.StatusTemporaryRedirect))
if logger != nil {
logger.Info("resolvespec admin api enabled",
slog.String("prefix", "/api/rs"),
slog.Int("models", len(resolveSpecModels())),
)
}
return nil
}
func registerResolveSpecGuards(rs *resolvespec.Handler) {
mutableByEntity := map[string]map[string]struct{}{
"projects": {
"create": {},
},
"thoughts": {
"update": {},
"delete": {},
},
"agent_skills": {
"delete": {},
},
"agent_guardrails": {
"delete": {},
},
}
rs.Hooks().Register(resolvespec.BeforeHandle, func(hookCtx *resolvespec.HookContext) error {
switch hookCtx.Operation {
case "read", "meta":
return nil
case "create", "update", "delete":
allowedOps, ok := mutableByEntity[hookCtx.Entity]
if !ok {
hookCtx.Abort = true
hookCtx.AbortCode = http.StatusForbidden
hookCtx.AbortMessage = fmt.Sprintf("operation %q is not allowed for %s.%s", hookCtx.Operation, hookCtx.Schema, hookCtx.Entity)
return fmt.Errorf("forbidden operation")
}
if _, ok := allowedOps[hookCtx.Operation]; !ok {
hookCtx.Abort = true
hookCtx.AbortCode = http.StatusForbidden
hookCtx.AbortMessage = fmt.Sprintf("operation %q is not allowed for %s.%s", hookCtx.Operation, hookCtx.Schema, hookCtx.Entity)
return fmt.Errorf("forbidden operation")
}
return nil
default:
hookCtx.Abort = true
hookCtx.AbortCode = http.StatusBadRequest
hookCtx.AbortMessage = fmt.Sprintf("unsupported operation %q", hookCtx.Operation)
return fmt.Errorf("unsupported operation")
}
})
}
type resolveSpecModel struct {
schema string
entity string
model any
}
func resolveSpecModels() []resolveSpecModel {
return []resolveSpecModel{
{schema: "public", entity: "activities", model: generatedmodels.ModelPublicActivities{}},
{schema: "public", entity: "agent_guardrails", model: generatedmodels.ModelPublicAgentGuardrails{}},
{schema: "public", entity: "agent_skills", model: generatedmodels.ModelPublicAgentSkills{}},
{schema: "public", entity: "chat_histories", model: generatedmodels.ModelPublicChatHistories{}},
{schema: "public", entity: "contact_interactions", model: generatedmodels.ModelPublicContactInteractions{}},
{schema: "public", entity: "embeddings", model: generatedmodels.ModelPublicEmbeddings{}},
{schema: "public", entity: "family_members", model: generatedmodels.ModelPublicFamilyMembers{}},
{schema: "public", entity: "household_items", model: generatedmodels.ModelPublicHouseholdItems{}},
{schema: "public", entity: "household_vendors", model: generatedmodels.ModelPublicHouseholdVendors{}},
{schema: "public", entity: "important_dates", model: generatedmodels.ModelPublicImportantDates{}},
{schema: "public", entity: "learnings", model: generatedmodels.ModelPublicLearnings{}},
{schema: "public", entity: "maintenance_logs", model: generatedmodels.ModelPublicMaintenanceLogs{}},
{schema: "public", entity: "maintenance_tasks", model: generatedmodels.ModelPublicMaintenanceTasks{}},
{schema: "public", entity: "meal_plans", model: generatedmodels.ModelPublicMealPlans{}},
{schema: "public", entity: "opportunities", model: generatedmodels.ModelPublicOpportunities{}},
{schema: "public", entity: "professional_contacts", model: generatedmodels.ModelPublicProfessionalContacts{}},
{schema: "public", entity: "project_guardrails", model: generatedmodels.ModelPublicProjectGuardrails{}},
{schema: "public", entity: "project_skills", model: generatedmodels.ModelPublicProjectSkills{}},
{schema: "public", entity: "projects", model: generatedmodels.ModelPublicProjects{}},
{schema: "public", entity: "recipes", model: generatedmodels.ModelPublicRecipes{}},
{schema: "public", entity: "shopping_lists", model: generatedmodels.ModelPublicShoppingLists{}},
{schema: "public", entity: "stored_files", model: generatedmodels.ModelPublicStoredFiles{}},
{schema: "public", entity: "thought_links", model: generatedmodels.ModelPublicThoughtLinks{}},
{schema: "public", entity: "thoughts", model: generatedmodels.ModelPublicThoughts{}},
{schema: "public", entity: "tool_annotations", model: generatedmodels.ModelPublicToolAnnotations{}},
}
}

View File

@@ -0,0 +1,154 @@
package app
import (
"io"
"log/slog"
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.warky.dev/wdevs/amcs/internal/auth"
"git.warky.dev/wdevs/amcs/internal/config"
"github.com/bitechdev/ResolveSpec/pkg/resolvespec"
)
func TestResolveSpecAuthRequiresValidCredentials(t *testing.T) {
keyring, err := auth.NewKeyring([]config.APIKey{{ID: "operator", Value: "secret"}})
if err != nil {
t.Fatalf("NewKeyring() error = %v", err)
}
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
protected := auth.Middleware(config.AuthConfig{}, keyring, nil, nil, nil, logger)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/rs/public/projects" {
t.Fatalf("path = %q, want /api/rs/public/projects", r.URL.Path)
}
w.WriteHeader(http.StatusNoContent)
}))
t.Run("missing credentials are rejected", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/api/rs/public/projects", strings.NewReader(`{"operation":"read"}`))
rec := httptest.NewRecorder()
protected.ServeHTTP(rec, req)
if rec.Code != http.StatusUnauthorized {
t.Fatalf("status = %d, want %d", rec.Code, http.StatusUnauthorized)
}
})
t.Run("valid API key is accepted", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/api/rs/public/projects", strings.NewReader(`{"operation":"read"}`))
req.Header.Set("x-brain-key", "secret")
rec := httptest.NewRecorder()
protected.ServeHTTP(rec, req)
if rec.Code != http.StatusNoContent {
t.Fatalf("status = %d, want %d", rec.Code, http.StatusNoContent)
}
})
}
func TestResolveSpecGuardAllowsSupportedMutations(t *testing.T) {
rs := resolvespec.NewHandler(nil, nil)
registerResolveSpecGuards(rs)
cases := []struct {
name string
entity string
operation string
}{
{name: "projects create", entity: "projects", operation: "create"},
{name: "thoughts update", entity: "thoughts", operation: "update"},
{name: "thoughts delete", entity: "thoughts", operation: "delete"},
{name: "agent_skills delete", entity: "agent_skills", operation: "delete"},
{name: "agent_guardrails delete", entity: "agent_guardrails", operation: "delete"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
hookCtx := &resolvespec.HookContext{
Schema: "public",
Entity: tc.entity,
Operation: tc.operation,
}
err := rs.Hooks().Execute(resolvespec.BeforeHandle, hookCtx)
if err != nil {
t.Fatalf("Execute() error = %v, want nil", err)
}
if hookCtx.Abort {
t.Fatalf("Abort = true, want false (code=%d message=%q)", hookCtx.AbortCode, hookCtx.AbortMessage)
}
})
}
}
func TestResolveSpecGuardBlocksUnsupportedMutations(t *testing.T) {
rs := resolvespec.NewHandler(nil, nil)
registerResolveSpecGuards(rs)
cases := []struct {
name string
entity string
operation string
wantCode int
wantMessageIn string
}{
{
name: "create not allowed on thoughts",
entity: "thoughts",
operation: "create",
wantCode: http.StatusForbidden,
wantMessageIn: `operation "create" is not allowed for public.thoughts`,
},
{
name: "delete not allowed on projects",
entity: "projects",
operation: "delete",
wantCode: http.StatusForbidden,
wantMessageIn: `operation "delete" is not allowed for public.projects`,
},
{
name: "mutations blocked for non-allowlisted entity",
entity: "stored_files",
operation: "delete",
wantCode: http.StatusForbidden,
wantMessageIn: `operation "delete" is not allowed for public.stored_files`,
},
{
name: "unknown operation is rejected",
entity: "projects",
operation: "scan",
wantCode: http.StatusBadRequest,
wantMessageIn: `unsupported operation "scan"`,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
hookCtx := &resolvespec.HookContext{
Schema: "public",
Entity: tc.entity,
Operation: tc.operation,
}
err := rs.Hooks().Execute(resolvespec.BeforeHandle, hookCtx)
if err == nil {
t.Fatal("Execute() error = nil, want non-nil")
}
if !hookCtx.Abort {
t.Fatal("Abort = false, want true")
}
if hookCtx.AbortCode != tc.wantCode {
t.Fatalf("AbortCode = %d, want %d", hookCtx.AbortCode, tc.wantCode)
}
if !strings.Contains(hookCtx.AbortMessage, tc.wantMessageIn) {
t.Fatalf("AbortMessage = %q, want substring %q", hookCtx.AbortMessage, tc.wantMessageIn)
}
})
}
}

View File

@@ -0,0 +1,70 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicActivities struct {
bun.BaseModel `bun:"table:public.activities,alias:activities"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
ActivityType resolvespec_common.SqlString `bun:"activity_type,type:text,nullzero," json:"activity_type"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
DayOfWeek resolvespec_common.SqlString `bun:"day_of_week,type:text,nullzero," json:"day_of_week"`
EndDate resolvespec_common.SqlDate `bun:"end_date,type:date,nullzero," json:"end_date"`
EndTime resolvespec_common.SqlTime `bun:"end_time,type:time,nullzero," json:"end_time"`
FamilyMemberID resolvespec_common.SqlUUID `bun:"family_member_id,type:uuid,nullzero," json:"family_member_id"`
Location resolvespec_common.SqlString `bun:"location,type:text,nullzero," json:"location"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
StartDate resolvespec_common.SqlDate `bun:"start_date,type:date,nullzero," json:"start_date"`
StartTime resolvespec_common.SqlTime `bun:"start_time,type:time,nullzero," json:"start_time"`
Title resolvespec_common.SqlString `bun:"title,type:text,notnull," json:"title"`
RelFamilyMemberID *ModelPublicFamilyMembers `bun:"rel:has-one,join:family_member_id=id" json:"relfamilymemberid,omitempty"` // Has one ModelPublicFamilyMembers
}
// TableName returns the table name for ModelPublicActivities
func (m ModelPublicActivities) TableName() string {
return "public.activities"
}
// TableNameOnly returns the table name without schema for ModelPublicActivities
func (m ModelPublicActivities) TableNameOnly() string {
return "activities"
}
// SchemaName returns the schema name for ModelPublicActivities
func (m ModelPublicActivities) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicActivities) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicActivities) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicActivities) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicActivities) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicActivities) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicActivities) GetPrefix() string {
return "ACT"
}

View File

@@ -0,0 +1,66 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicAgentGuardrails struct {
bun.BaseModel `bun:"table:public.agent_guardrails,alias:agent_guardrails"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
Content resolvespec_common.SqlString `bun:"content,type:text,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Severity resolvespec_common.SqlString `bun:"severity,type:text,default:'medium',notnull," json:"severity"`
Tags resolvespec_common.SqlString `bun:"tags,type:text,nullzero," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelGuardrailIDPublicProjectGuardrails []*ModelPublicProjectGuardrails `bun:"rel:has-many,join:id=guardrail_id" json:"relguardrailidpublicprojectguardrails,omitempty"` // Has many ModelPublicProjectGuardrails
}
// TableName returns the table name for ModelPublicAgentGuardrails
func (m ModelPublicAgentGuardrails) TableName() string {
return "public.agent_guardrails"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentGuardrails
func (m ModelPublicAgentGuardrails) TableNameOnly() string {
return "agent_guardrails"
}
// SchemaName returns the schema name for ModelPublicAgentGuardrails
func (m ModelPublicAgentGuardrails) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicAgentGuardrails) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicAgentGuardrails) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicAgentGuardrails) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicAgentGuardrails) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicAgentGuardrails) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentGuardrails) GetPrefix() string {
return "AGG"
}

View File

@@ -0,0 +1,66 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicAgentSkills struct {
bun.BaseModel `bun:"table:public.agent_skills,alias:agent_skills"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
Content resolvespec_common.SqlString `bun:"content,type:text,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,default:'',notnull," json:"description"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Tags resolvespec_common.SqlString `bun:"tags,type:text,nullzero," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelRelatedSkillIDPublicLearnings []*ModelPublicLearnings `bun:"rel:has-many,join:id=related_skill_id" json:"relrelatedskillidpubliclearnings,omitempty"` // Has many ModelPublicLearnings
RelSkillIDPublicProjectSkills []*ModelPublicProjectSkills `bun:"rel:has-many,join:id=skill_id" json:"relskillidpublicprojectskills,omitempty"` // Has many ModelPublicProjectSkills
}
// TableName returns the table name for ModelPublicAgentSkills
func (m ModelPublicAgentSkills) TableName() string {
return "public.agent_skills"
}
// TableNameOnly returns the table name without schema for ModelPublicAgentSkills
func (m ModelPublicAgentSkills) TableNameOnly() string {
return "agent_skills"
}
// SchemaName returns the schema name for ModelPublicAgentSkills
func (m ModelPublicAgentSkills) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicAgentSkills) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicAgentSkills) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicAgentSkills) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicAgentSkills) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicAgentSkills) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicAgentSkills) GetPrefix() string {
return "ASG"
}

View File

@@ -0,0 +1,69 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicChatHistories struct {
bun.BaseModel `bun:"table:public.chat_histories,alias:chat_histories"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
AgentID resolvespec_common.SqlString `bun:"agent_id,type:text,nullzero," json:"agent_id"`
Channel resolvespec_common.SqlString `bun:"channel,type:text,nullzero," json:"channel"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Messages resolvespec_common.SqlJSONB `bun:"messages,type:jsonb,default:'[',notnull," json:"messages"`
Metadata resolvespec_common.SqlJSONB `bun:"metadata,type:jsonb,default:'{}',notnull," json:"metadata"`
ProjectID resolvespec_common.SqlUUID `bun:"project_id,type:uuid,nullzero," json:"project_id"`
SessionID resolvespec_common.SqlString `bun:"session_id,type:text,notnull," json:"session_id"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,nullzero," json:"summary"`
Title resolvespec_common.SqlString `bun:"title,type:text,nullzero," json:"title"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=guid" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
}
// TableName returns the table name for ModelPublicChatHistories
func (m ModelPublicChatHistories) TableName() string {
return "public.chat_histories"
}
// TableNameOnly returns the table name without schema for ModelPublicChatHistories
func (m ModelPublicChatHistories) TableNameOnly() string {
return "chat_histories"
}
// SchemaName returns the schema name for ModelPublicChatHistories
func (m ModelPublicChatHistories) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicChatHistories) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicChatHistories) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicChatHistories) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicChatHistories) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicChatHistories) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicChatHistories) GetPrefix() string {
return "CHH"
}

View File

@@ -0,0 +1,66 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicContactInteractions struct {
bun.BaseModel `bun:"table:public.contact_interactions,alias:contact_interactions"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
ContactID resolvespec_common.SqlUUID `bun:"contact_id,type:uuid,notnull," json:"contact_id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
FollowUpNeeded bool `bun:"follow_up_needed,type:boolean,default:false,notnull," json:"follow_up_needed"`
FollowUpNotes resolvespec_common.SqlString `bun:"follow_up_notes,type:text,nullzero," json:"follow_up_notes"`
InteractionType resolvespec_common.SqlString `bun:"interaction_type,type:text,notnull," json:"interaction_type"`
OccurredAt resolvespec_common.SqlTimeStamp `bun:"occurred_at,type:timestamptz,default:now(),notnull," json:"occurred_at"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,notnull," json:"summary"`
RelContactID *ModelPublicProfessionalContacts `bun:"rel:has-one,join:contact_id=id" json:"relcontactid,omitempty"` // Has one ModelPublicProfessionalContacts
}
// TableName returns the table name for ModelPublicContactInteractions
func (m ModelPublicContactInteractions) TableName() string {
return "public.contact_interactions"
}
// TableNameOnly returns the table name without schema for ModelPublicContactInteractions
func (m ModelPublicContactInteractions) TableNameOnly() string {
return "contact_interactions"
}
// SchemaName returns the schema name for ModelPublicContactInteractions
func (m ModelPublicContactInteractions) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicContactInteractions) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicContactInteractions) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicContactInteractions) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicContactInteractions) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicContactInteractions) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicContactInteractions) GetPrefix() string {
return "CIO"
}

View File

@@ -0,0 +1,66 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicEmbeddings struct {
bun.BaseModel `bun:"table:public.embeddings,alias:embeddings"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
Dim resolvespec_common.SqlInt32 `bun:"dim,type:int,notnull," json:"dim"`
Embedding resolvespec_common.SqlString `bun:"embedding,type:vector,notnull," json:"embedding"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Model resolvespec_common.SqlString `bun:"model,type:text,notnull,unique:uidx_embeddings_thought_id_model," json:"model"`
ThoughtID resolvespec_common.SqlUUID `bun:"thought_id,type:uuid,notnull,unique:uidx_embeddings_thought_id_model," json:"thought_id"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),nullzero," json:"updated_at"`
RelThoughtID *ModelPublicThoughts `bun:"rel:has-one,join:thought_id=guid" json:"relthoughtid,omitempty"` // Has one ModelPublicThoughts
}
// TableName returns the table name for ModelPublicEmbeddings
func (m ModelPublicEmbeddings) TableName() string {
return "public.embeddings"
}
// TableNameOnly returns the table name without schema for ModelPublicEmbeddings
func (m ModelPublicEmbeddings) TableNameOnly() string {
return "embeddings"
}
// SchemaName returns the schema name for ModelPublicEmbeddings
func (m ModelPublicEmbeddings) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicEmbeddings) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicEmbeddings) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicEmbeddings) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicEmbeddings) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicEmbeddings) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicEmbeddings) GetPrefix() string {
return "EMB"
}

View File

@@ -0,0 +1,65 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicFamilyMembers struct {
bun.BaseModel `bun:"table:public.family_members,alias:family_members"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
BirthDate resolvespec_common.SqlDate `bun:"birth_date,type:date,nullzero," json:"birth_date"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
Relationship resolvespec_common.SqlString `bun:"relationship,type:text,nullzero," json:"relationship"`
RelFamilyMemberIDPublicActivities []*ModelPublicActivities `bun:"rel:has-many,join:id=family_member_id" json:"relfamilymemberidpublicactivities,omitempty"` // Has many ModelPublicActivities
RelFamilyMemberIDPublicImportantDates []*ModelPublicImportantDates `bun:"rel:has-many,join:id=family_member_id" json:"relfamilymemberidpublicimportantdates,omitempty"` // Has many ModelPublicImportantDates
}
// TableName returns the table name for ModelPublicFamilyMembers
func (m ModelPublicFamilyMembers) TableName() string {
return "public.family_members"
}
// TableNameOnly returns the table name without schema for ModelPublicFamilyMembers
func (m ModelPublicFamilyMembers) TableNameOnly() string {
return "family_members"
}
// SchemaName returns the schema name for ModelPublicFamilyMembers
func (m ModelPublicFamilyMembers) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicFamilyMembers) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicFamilyMembers) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicFamilyMembers) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicFamilyMembers) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicFamilyMembers) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicFamilyMembers) GetPrefix() string {
return "FMA"
}

View File

@@ -0,0 +1,65 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicHouseholdItems struct {
bun.BaseModel `bun:"table:public.household_items,alias:household_items"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
Category resolvespec_common.SqlString `bun:"category,type:text,nullzero," json:"category"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Details resolvespec_common.SqlJSONB `bun:"details,type:jsonb,default:'{}',notnull," json:"details"`
Location resolvespec_common.SqlString `bun:"location,type:text,nullzero," json:"location"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
}
// TableName returns the table name for ModelPublicHouseholdItems
func (m ModelPublicHouseholdItems) TableName() string {
return "public.household_items"
}
// TableNameOnly returns the table name without schema for ModelPublicHouseholdItems
func (m ModelPublicHouseholdItems) TableNameOnly() string {
return "household_items"
}
// SchemaName returns the schema name for ModelPublicHouseholdItems
func (m ModelPublicHouseholdItems) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicHouseholdItems) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicHouseholdItems) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicHouseholdItems) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicHouseholdItems) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicHouseholdItems) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicHouseholdItems) GetPrefix() string {
return "HIO"
}

View File

@@ -0,0 +1,67 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicHouseholdVendors struct {
bun.BaseModel `bun:"table:public.household_vendors,alias:household_vendors"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Email resolvespec_common.SqlString `bun:"email,type:text,nullzero," json:"email"`
LastUsed resolvespec_common.SqlDate `bun:"last_used,type:date,nullzero," json:"last_used"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
Phone resolvespec_common.SqlString `bun:"phone,type:text,nullzero," json:"phone"`
Rating resolvespec_common.SqlInt32 `bun:"rating,type:int,nullzero," json:"rating"`
ServiceType resolvespec_common.SqlString `bun:"service_type,type:text,nullzero," json:"service_type"`
Website resolvespec_common.SqlString `bun:"website,type:text,nullzero," json:"website"`
}
// TableName returns the table name for ModelPublicHouseholdVendors
func (m ModelPublicHouseholdVendors) TableName() string {
return "public.household_vendors"
}
// TableNameOnly returns the table name without schema for ModelPublicHouseholdVendors
func (m ModelPublicHouseholdVendors) TableNameOnly() string {
return "household_vendors"
}
// SchemaName returns the schema name for ModelPublicHouseholdVendors
func (m ModelPublicHouseholdVendors) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicHouseholdVendors) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicHouseholdVendors) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicHouseholdVendors) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicHouseholdVendors) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicHouseholdVendors) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicHouseholdVendors) GetPrefix() string {
return "HVO"
}

View File

@@ -0,0 +1,66 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicImportantDates struct {
bun.BaseModel `bun:"table:public.important_dates,alias:important_dates"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
DateValue resolvespec_common.SqlDate `bun:"date_value,type:date,notnull," json:"date_value"`
FamilyMemberID resolvespec_common.SqlUUID `bun:"family_member_id,type:uuid,nullzero," json:"family_member_id"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
RecurringYearly bool `bun:"recurring_yearly,type:boolean,default:false,notnull," json:"recurring_yearly"`
ReminderDaysBefore resolvespec_common.SqlInt32 `bun:"reminder_days_before,type:int,default:7,notnull," json:"reminder_days_before"`
Title resolvespec_common.SqlString `bun:"title,type:text,notnull," json:"title"`
RelFamilyMemberID *ModelPublicFamilyMembers `bun:"rel:has-one,join:family_member_id=id" json:"relfamilymemberid,omitempty"` // Has one ModelPublicFamilyMembers
}
// TableName returns the table name for ModelPublicImportantDates
func (m ModelPublicImportantDates) TableName() string {
return "public.important_dates"
}
// TableNameOnly returns the table name without schema for ModelPublicImportantDates
func (m ModelPublicImportantDates) TableNameOnly() string {
return "important_dates"
}
// SchemaName returns the schema name for ModelPublicImportantDates
func (m ModelPublicImportantDates) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicImportantDates) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicImportantDates) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicImportantDates) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicImportantDates) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicImportantDates) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicImportantDates) GetPrefix() string {
return "IDM"
}

View File

@@ -0,0 +1,83 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicLearnings struct {
bun.BaseModel `bun:"table:public.learnings,alias:learnings"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
ActionRequired bool `bun:"action_required,type:boolean,default:false,notnull," json:"action_required"`
Area resolvespec_common.SqlString `bun:"area,type:text,default:'other',notnull," json:"area"`
Category resolvespec_common.SqlString `bun:"category,type:text,default:'insight',notnull," json:"category"`
Confidence resolvespec_common.SqlString `bun:"confidence,type:text,default:'hypothesis',notnull," json:"confidence"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Details resolvespec_common.SqlString `bun:"details,type:text,default:'',notnull," json:"details"`
DuplicateOfLearningID resolvespec_common.SqlUUID `bun:"duplicate_of_learning_id,type:uuid,nullzero," json:"duplicate_of_learning_id"`
Priority resolvespec_common.SqlString `bun:"priority,type:text,default:'medium',notnull," json:"priority"`
ProjectID resolvespec_common.SqlUUID `bun:"project_id,type:uuid,nullzero," json:"project_id"`
RelatedSkillID resolvespec_common.SqlUUID `bun:"related_skill_id,type:uuid,nullzero," json:"related_skill_id"`
RelatedThoughtID resolvespec_common.SqlUUID `bun:"related_thought_id,type:uuid,nullzero," json:"related_thought_id"`
ReviewedAt resolvespec_common.SqlTimeStamp `bun:"reviewed_at,type:timestamptz,nullzero," json:"reviewed_at"`
ReviewedBy resolvespec_common.SqlString `bun:"reviewed_by,type:text,nullzero," json:"reviewed_by"`
SourceRef resolvespec_common.SqlString `bun:"source_ref,type:text,nullzero," json:"source_ref"`
SourceType resolvespec_common.SqlString `bun:"source_type,type:text,nullzero," json:"source_type"`
Status resolvespec_common.SqlString `bun:"status,type:text,default:'pending',notnull," json:"status"`
Summary resolvespec_common.SqlString `bun:"summary,type:text,notnull," json:"summary"`
SupersedesLearningID resolvespec_common.SqlUUID `bun:"supersedes_learning_id,type:uuid,nullzero," json:"supersedes_learning_id"`
Tags resolvespec_common.SqlString `bun:"tags,type:text,nullzero," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelDuplicateOfLearningID *ModelPublicLearnings `bun:"rel:has-one,join:duplicate_of_learning_id=id" json:"relduplicateoflearningid,omitempty"` // Has one ModelPublicLearnings
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=guid" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelRelatedSkillID *ModelPublicAgentSkills `bun:"rel:has-one,join:related_skill_id=id" json:"relrelatedskillid,omitempty"` // Has one ModelPublicAgentSkills
RelRelatedThoughtID *ModelPublicThoughts `bun:"rel:has-one,join:related_thought_id=guid" json:"relrelatedthoughtid,omitempty"` // Has one ModelPublicThoughts
RelSupersedesLearningID *ModelPublicLearnings `bun:"rel:has-one,join:supersedes_learning_id=id" json:"relsupersedeslearningid,omitempty"` // Has one ModelPublicLearnings
}
// TableName returns the table name for ModelPublicLearnings
func (m ModelPublicLearnings) TableName() string {
return "public.learnings"
}
// TableNameOnly returns the table name without schema for ModelPublicLearnings
func (m ModelPublicLearnings) TableNameOnly() string {
return "learnings"
}
// SchemaName returns the schema name for ModelPublicLearnings
func (m ModelPublicLearnings) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicLearnings) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicLearnings) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicLearnings) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicLearnings) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicLearnings) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicLearnings) GetPrefix() string {
return "LEA"
}

View File

@@ -0,0 +1,65 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicMaintenanceLogs struct {
bun.BaseModel `bun:"table:public.maintenance_logs,alias:maintenance_logs"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
CompletedAt resolvespec_common.SqlTimeStamp `bun:"completed_at,type:timestamptz,default:now(),notnull," json:"completed_at"`
Cost resolvespec_common.SqlFloat64 `bun:"cost,type:decimal(10,2),nullzero," json:"cost"`
NextAction resolvespec_common.SqlString `bun:"next_action,type:text,nullzero," json:"next_action"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
PerformedBy resolvespec_common.SqlString `bun:"performed_by,type:text,nullzero," json:"performed_by"`
TaskID resolvespec_common.SqlUUID `bun:"task_id,type:uuid,notnull," json:"task_id"`
RelTaskID *ModelPublicMaintenanceTasks `bun:"rel:has-one,join:task_id=id" json:"reltaskid,omitempty"` // Has one ModelPublicMaintenanceTasks
}
// TableName returns the table name for ModelPublicMaintenanceLogs
func (m ModelPublicMaintenanceLogs) TableName() string {
return "public.maintenance_logs"
}
// TableNameOnly returns the table name without schema for ModelPublicMaintenanceLogs
func (m ModelPublicMaintenanceLogs) TableNameOnly() string {
return "maintenance_logs"
}
// SchemaName returns the schema name for ModelPublicMaintenanceLogs
func (m ModelPublicMaintenanceLogs) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicMaintenanceLogs) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicMaintenanceLogs) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicMaintenanceLogs) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicMaintenanceLogs) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicMaintenanceLogs) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicMaintenanceLogs) GetPrefix() string {
return "MLA"
}

View File

@@ -0,0 +1,68 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicMaintenanceTasks struct {
bun.BaseModel `bun:"table:public.maintenance_tasks,alias:maintenance_tasks"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
Category resolvespec_common.SqlString `bun:"category,type:text,nullzero," json:"category"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
FrequencyDays resolvespec_common.SqlInt32 `bun:"frequency_days,type:int,nullzero," json:"frequency_days"`
LastCompleted resolvespec_common.SqlTimeStamp `bun:"last_completed,type:timestamptz,nullzero," json:"last_completed"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
NextDue resolvespec_common.SqlTimeStamp `bun:"next_due,type:timestamptz,nullzero," json:"next_due"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
Priority resolvespec_common.SqlString `bun:"priority,type:text,default:'medium',notnull," json:"priority"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelTaskIDPublicMaintenanceLogs []*ModelPublicMaintenanceLogs `bun:"rel:has-many,join:id=task_id" json:"reltaskidpublicmaintenancelogs,omitempty"` // Has many ModelPublicMaintenanceLogs
}
// TableName returns the table name for ModelPublicMaintenanceTasks
func (m ModelPublicMaintenanceTasks) TableName() string {
return "public.maintenance_tasks"
}
// TableNameOnly returns the table name without schema for ModelPublicMaintenanceTasks
func (m ModelPublicMaintenanceTasks) TableNameOnly() string {
return "maintenance_tasks"
}
// SchemaName returns the schema name for ModelPublicMaintenanceTasks
func (m ModelPublicMaintenanceTasks) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicMaintenanceTasks) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicMaintenanceTasks) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicMaintenanceTasks) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicMaintenanceTasks) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicMaintenanceTasks) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicMaintenanceTasks) GetPrefix() string {
return "MTA"
}

View File

@@ -0,0 +1,67 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicMealPlans struct {
bun.BaseModel `bun:"table:public.meal_plans,alias:meal_plans"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
CustomMeal resolvespec_common.SqlString `bun:"custom_meal,type:text,nullzero," json:"custom_meal"`
DayOfWeek resolvespec_common.SqlString `bun:"day_of_week,type:text,notnull," json:"day_of_week"`
MealType resolvespec_common.SqlString `bun:"meal_type,type:text,notnull," json:"meal_type"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
RecipeID resolvespec_common.SqlUUID `bun:"recipe_id,type:uuid,nullzero," json:"recipe_id"`
Servings resolvespec_common.SqlInt32 `bun:"servings,type:int,nullzero," json:"servings"`
WeekStart resolvespec_common.SqlDate `bun:"week_start,type:date,notnull," json:"week_start"`
RelRecipeID *ModelPublicRecipes `bun:"rel:has-one,join:recipe_id=id" json:"relrecipeid,omitempty"` // Has one ModelPublicRecipes
}
// TableName returns the table name for ModelPublicMealPlans
func (m ModelPublicMealPlans) TableName() string {
return "public.meal_plans"
}
// TableNameOnly returns the table name without schema for ModelPublicMealPlans
func (m ModelPublicMealPlans) TableNameOnly() string {
return "meal_plans"
}
// SchemaName returns the schema name for ModelPublicMealPlans
func (m ModelPublicMealPlans) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicMealPlans) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicMealPlans) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicMealPlans) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicMealPlans) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicMealPlans) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicMealPlans) GetPrefix() string {
return "MPE"
}

View File

@@ -0,0 +1,68 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicOpportunities struct {
bun.BaseModel `bun:"table:public.opportunities,alias:opportunities"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
ContactID resolvespec_common.SqlUUID `bun:"contact_id,type:uuid,nullzero," json:"contact_id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,nullzero," json:"description"`
ExpectedCloseDate resolvespec_common.SqlDate `bun:"expected_close_date,type:date,nullzero," json:"expected_close_date"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
Stage resolvespec_common.SqlString `bun:"stage,type:text,default:'identified',notnull," json:"stage"`
Title resolvespec_common.SqlString `bun:"title,type:text,notnull," json:"title"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
Value resolvespec_common.SqlFloat64 `bun:"value,type:decimal(12,2),nullzero," json:"value"`
RelContactID *ModelPublicProfessionalContacts `bun:"rel:has-one,join:contact_id=id" json:"relcontactid,omitempty"` // Has one ModelPublicProfessionalContacts
}
// TableName returns the table name for ModelPublicOpportunities
func (m ModelPublicOpportunities) TableName() string {
return "public.opportunities"
}
// TableNameOnly returns the table name without schema for ModelPublicOpportunities
func (m ModelPublicOpportunities) TableNameOnly() string {
return "opportunities"
}
// SchemaName returns the schema name for ModelPublicOpportunities
func (m ModelPublicOpportunities) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicOpportunities) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicOpportunities) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicOpportunities) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicOpportunities) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicOpportunities) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicOpportunities) GetPrefix() string {
return "OPP"
}

View File

@@ -0,0 +1,73 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicProfessionalContacts struct {
bun.BaseModel `bun:"table:public.professional_contacts,alias:professional_contacts"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
Company resolvespec_common.SqlString `bun:"company,type:text,nullzero," json:"company"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Email resolvespec_common.SqlString `bun:"email,type:text,nullzero," json:"email"`
FollowUpDate resolvespec_common.SqlDate `bun:"follow_up_date,type:date,nullzero," json:"follow_up_date"`
HowWeMet resolvespec_common.SqlString `bun:"how_we_met,type:text,nullzero," json:"how_we_met"`
LastContacted resolvespec_common.SqlTimeStamp `bun:"last_contacted,type:timestamptz,nullzero," json:"last_contacted"`
LinkedinURL resolvespec_common.SqlString `bun:"linkedin_url,type:text,nullzero," json:"linkedin_url"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
Phone resolvespec_common.SqlString `bun:"phone,type:text,nullzero," json:"phone"`
Tags resolvespec_common.SqlString `bun:"tags,type:text,nullzero," json:"tags"`
Title resolvespec_common.SqlString `bun:"title,type:text,nullzero," json:"title"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelContactIDPublicContactInteractions []*ModelPublicContactInteractions `bun:"rel:has-many,join:id=contact_id" json:"relcontactidpubliccontactinteractions,omitempty"` // Has many ModelPublicContactInteractions
RelContactIDPublicOpportunities []*ModelPublicOpportunities `bun:"rel:has-many,join:id=contact_id" json:"relcontactidpublicopportunities,omitempty"` // Has many ModelPublicOpportunities
}
// TableName returns the table name for ModelPublicProfessionalContacts
func (m ModelPublicProfessionalContacts) TableName() string {
return "public.professional_contacts"
}
// TableNameOnly returns the table name without schema for ModelPublicProfessionalContacts
func (m ModelPublicProfessionalContacts) TableNameOnly() string {
return "professional_contacts"
}
// SchemaName returns the schema name for ModelPublicProfessionalContacts
func (m ModelPublicProfessionalContacts) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicProfessionalContacts) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicProfessionalContacts) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicProfessionalContacts) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicProfessionalContacts) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicProfessionalContacts) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicProfessionalContacts) GetPrefix() string {
return "PCR"
}

View File

@@ -0,0 +1,63 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicProjectGuardrails struct {
bun.BaseModel `bun:"table:public.project_guardrails,alias:project_guardrails"`
ID resolvespec_common.SqlInt32 `bun:"id,type:serial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
GuardrailID resolvespec_common.SqlUUID `bun:"guardrail_id,type:uuid,notnull," json:"guardrail_id"`
ProjectID resolvespec_common.SqlUUID `bun:"project_id,type:uuid,notnull," json:"project_id"`
RelGuardrailID *ModelPublicAgentGuardrails `bun:"rel:has-one,join:guardrail_id=id" json:"relguardrailid,omitempty"` // Has one ModelPublicAgentGuardrails
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=guid" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
}
// TableName returns the table name for ModelPublicProjectGuardrails
func (m ModelPublicProjectGuardrails) TableName() string {
return "public.project_guardrails"
}
// TableNameOnly returns the table name without schema for ModelPublicProjectGuardrails
func (m ModelPublicProjectGuardrails) TableNameOnly() string {
return "project_guardrails"
}
// SchemaName returns the schema name for ModelPublicProjectGuardrails
func (m ModelPublicProjectGuardrails) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicProjectGuardrails) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicProjectGuardrails) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicProjectGuardrails) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicProjectGuardrails) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicProjectGuardrails) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicProjectGuardrails) GetPrefix() string {
return "PGR"
}

View File

@@ -0,0 +1,63 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicProjectSkills struct {
bun.BaseModel `bun:"table:public.project_skills,alias:project_skills"`
ID resolvespec_common.SqlInt32 `bun:"id,type:serial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
ProjectID resolvespec_common.SqlUUID `bun:"project_id,type:uuid,notnull," json:"project_id"`
SkillID resolvespec_common.SqlUUID `bun:"skill_id,type:uuid,notnull," json:"skill_id"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=guid" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelSkillID *ModelPublicAgentSkills `bun:"rel:has-one,join:skill_id=id" json:"relskillid,omitempty"` // Has one ModelPublicAgentSkills
}
// TableName returns the table name for ModelPublicProjectSkills
func (m ModelPublicProjectSkills) TableName() string {
return "public.project_skills"
}
// TableNameOnly returns the table name without schema for ModelPublicProjectSkills
func (m ModelPublicProjectSkills) TableNameOnly() string {
return "project_skills"
}
// SchemaName returns the schema name for ModelPublicProjectSkills
func (m ModelPublicProjectSkills) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicProjectSkills) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicProjectSkills) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicProjectSkills) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicProjectSkills) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicProjectSkills) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicProjectSkills) GetPrefix() string {
return "PSR"
}

View File

@@ -0,0 +1,69 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicProjects struct {
bun.BaseModel `bun:"table:public.projects,alias:projects"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
Description resolvespec_common.SqlString `bun:"description,type:text,nullzero," json:"description"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
LastActiveAt resolvespec_common.SqlTimeStamp `bun:"last_active_at,type:timestamptz,default:now(),nullzero," json:"last_active_at"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
RelProjectIDPublicThoughts []*ModelPublicThoughts `bun:"rel:has-many,join:guid=project_id" json:"relprojectidpublicthoughts,omitempty"` // Has many ModelPublicThoughts
RelProjectIDPublicStoredFiles []*ModelPublicStoredFiles `bun:"rel:has-many,join:guid=project_id" json:"relprojectidpublicstoredfiles,omitempty"` // Has many ModelPublicStoredFiles
RelProjectIDPublicChatHistories []*ModelPublicChatHistories `bun:"rel:has-many,join:guid=project_id" json:"relprojectidpublicchathistories,omitempty"` // Has many ModelPublicChatHistories
RelProjectIDPublicLearnings []*ModelPublicLearnings `bun:"rel:has-many,join:guid=project_id" json:"relprojectidpubliclearnings,omitempty"` // Has many ModelPublicLearnings
RelProjectIDPublicProjectSkills []*ModelPublicProjectSkills `bun:"rel:has-many,join:guid=project_id" json:"relprojectidpublicprojectskills,omitempty"` // Has many ModelPublicProjectSkills
RelProjectIDPublicProjectGuardrails []*ModelPublicProjectGuardrails `bun:"rel:has-many,join:guid=project_id" json:"relprojectidpublicprojectguardrails,omitempty"` // Has many ModelPublicProjectGuardrails
}
// TableName returns the table name for ModelPublicProjects
func (m ModelPublicProjects) TableName() string {
return "public.projects"
}
// TableNameOnly returns the table name without schema for ModelPublicProjects
func (m ModelPublicProjects) TableNameOnly() string {
return "projects"
}
// SchemaName returns the schema name for ModelPublicProjects
func (m ModelPublicProjects) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicProjects) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicProjects) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicProjects) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicProjects) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicProjects) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicProjects) GetPrefix() string {
return "PRO"
}

View File

@@ -0,0 +1,71 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicRecipes struct {
bun.BaseModel `bun:"table:public.recipes,alias:recipes"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
CookTimeMinutes resolvespec_common.SqlInt32 `bun:"cook_time_minutes,type:int,nullzero," json:"cook_time_minutes"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Cuisine resolvespec_common.SqlString `bun:"cuisine,type:text,nullzero," json:"cuisine"`
Ingredients resolvespec_common.SqlJSONB `bun:"ingredients,type:jsonb,default:'[',notnull," json:"ingredients"`
Instructions resolvespec_common.SqlJSONB `bun:"instructions,type:jsonb,default:'[',notnull," json:"instructions"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
PrepTimeMinutes resolvespec_common.SqlInt32 `bun:"prep_time_minutes,type:int,nullzero," json:"prep_time_minutes"`
Rating resolvespec_common.SqlInt32 `bun:"rating,type:int,nullzero," json:"rating"`
Servings resolvespec_common.SqlInt32 `bun:"servings,type:int,nullzero," json:"servings"`
Tags resolvespec_common.SqlString `bun:"tags,type:text,nullzero," json:"tags"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelRecipeIDPublicMealPlans []*ModelPublicMealPlans `bun:"rel:has-many,join:id=recipe_id" json:"relrecipeidpublicmealplans,omitempty"` // Has many ModelPublicMealPlans
}
// TableName returns the table name for ModelPublicRecipes
func (m ModelPublicRecipes) TableName() string {
return "public.recipes"
}
// TableNameOnly returns the table name without schema for ModelPublicRecipes
func (m ModelPublicRecipes) TableNameOnly() string {
return "recipes"
}
// SchemaName returns the schema name for ModelPublicRecipes
func (m ModelPublicRecipes) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicRecipes) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicRecipes) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicRecipes) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicRecipes) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicRecipes) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicRecipes) GetPrefix() string {
return "REC"
}

View File

@@ -0,0 +1,63 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicShoppingLists struct {
bun.BaseModel `bun:"table:public.shopping_lists,alias:shopping_lists"`
ID resolvespec_common.SqlUUID `bun:"id,type:uuid,pk,default:gen_random_uuid()," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Items resolvespec_common.SqlJSONB `bun:"items,type:jsonb,default:'[',notnull," json:"items"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,nullzero," json:"notes"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
WeekStart resolvespec_common.SqlDate `bun:"week_start,type:date,notnull," json:"week_start"`
}
// TableName returns the table name for ModelPublicShoppingLists
func (m ModelPublicShoppingLists) TableName() string {
return "public.shopping_lists"
}
// TableNameOnly returns the table name without schema for ModelPublicShoppingLists
func (m ModelPublicShoppingLists) TableNameOnly() string {
return "shopping_lists"
}
// SchemaName returns the schema name for ModelPublicShoppingLists
func (m ModelPublicShoppingLists) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicShoppingLists) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicShoppingLists) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicShoppingLists) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicShoppingLists) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicShoppingLists) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicShoppingLists) GetPrefix() string {
return "SLH"
}

View File

@@ -0,0 +1,72 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicStoredFiles struct {
bun.BaseModel `bun:"table:public.stored_files,alias:stored_files"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
Content []byte `bun:"content,type:bytea,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Encoding resolvespec_common.SqlString `bun:"encoding,type:text,default:'base64',notnull," json:"encoding"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Kind resolvespec_common.SqlString `bun:"kind,type:text,default:'file',notnull," json:"kind"`
MediaType resolvespec_common.SqlString `bun:"media_type,type:text,notnull," json:"media_type"`
Name resolvespec_common.SqlString `bun:"name,type:text,notnull," json:"name"`
ProjectID resolvespec_common.SqlUUID `bun:"project_id,type:uuid,nullzero," json:"project_id"`
Sha256 resolvespec_common.SqlString `bun:"sha256,type:text,notnull," json:"sha256"`
SizeBytes int64 `bun:"size_bytes,type:bigint,notnull," json:"size_bytes"`
ThoughtID resolvespec_common.SqlUUID `bun:"thought_id,type:uuid,nullzero," json:"thought_id"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=guid" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelThoughtID *ModelPublicThoughts `bun:"rel:has-one,join:thought_id=guid" json:"relthoughtid,omitempty"` // Has one ModelPublicThoughts
}
// TableName returns the table name for ModelPublicStoredFiles
func (m ModelPublicStoredFiles) TableName() string {
return "public.stored_files"
}
// TableNameOnly returns the table name without schema for ModelPublicStoredFiles
func (m ModelPublicStoredFiles) TableNameOnly() string {
return "stored_files"
}
// SchemaName returns the schema name for ModelPublicStoredFiles
func (m ModelPublicStoredFiles) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicStoredFiles) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicStoredFiles) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicStoredFiles) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicStoredFiles) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicStoredFiles) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicStoredFiles) GetPrefix() string {
return "SFT"
}

View File

@@ -0,0 +1,64 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicThoughtLinks struct {
bun.BaseModel `bun:"table:public.thought_links,alias:thought_links"`
ID resolvespec_common.SqlInt32 `bun:"id,type:serial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
FromID int64 `bun:"from_id,type:bigint,notnull," json:"from_id"`
Relation resolvespec_common.SqlString `bun:"relation,type:text,notnull," json:"relation"`
ToID int64 `bun:"to_id,type:bigint,notnull," json:"to_id"`
RelFromID *ModelPublicThoughts `bun:"rel:has-one,join:from_id=id" json:"relfromid,omitempty"` // Has one ModelPublicThoughts
RelToID *ModelPublicThoughts `bun:"rel:has-one,join:to_id=id" json:"reltoid,omitempty"` // Has one ModelPublicThoughts
}
// TableName returns the table name for ModelPublicThoughtLinks
func (m ModelPublicThoughtLinks) TableName() string {
return "public.thought_links"
}
// TableNameOnly returns the table name without schema for ModelPublicThoughtLinks
func (m ModelPublicThoughtLinks) TableNameOnly() string {
return "thought_links"
}
// SchemaName returns the schema name for ModelPublicThoughtLinks
func (m ModelPublicThoughtLinks) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicThoughtLinks) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicThoughtLinks) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicThoughtLinks) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicThoughtLinks) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicThoughtLinks) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicThoughtLinks) GetPrefix() string {
return "TLH"
}

View File

@@ -0,0 +1,71 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicThoughts struct {
bun.BaseModel `bun:"table:public.thoughts,alias:thoughts"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
ArchivedAt resolvespec_common.SqlTimeStamp `bun:"archived_at,type:timestamptz,nullzero," json:"archived_at"`
Content resolvespec_common.SqlString `bun:"content,type:text,notnull," json:"content"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),nullzero," json:"created_at"`
GUID resolvespec_common.SqlUUID `bun:"guid,type:uuid,default:gen_random_uuid(),notnull," json:"guid"`
Metadata resolvespec_common.SqlJSONB `bun:"metadata,type:jsonb,default:'{}::jsonb',nullzero," json:"metadata"`
ProjectID resolvespec_common.SqlUUID `bun:"project_id,type:uuid,nullzero," json:"project_id"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),nullzero," json:"updated_at"`
RelProjectID *ModelPublicProjects `bun:"rel:has-one,join:project_id=guid" json:"relprojectid,omitempty"` // Has one ModelPublicProjects
RelFromIDPublicThoughtLinks []*ModelPublicThoughtLinks `bun:"rel:has-many,join:id=from_id" json:"relfromidpublicthoughtlinks,omitempty"` // Has many ModelPublicThoughtLinks
RelToIDPublicThoughtLinks []*ModelPublicThoughtLinks `bun:"rel:has-many,join:id=to_id" json:"reltoidpublicthoughtlinks,omitempty"` // Has many ModelPublicThoughtLinks
RelThoughtIDPublicEmbeddings []*ModelPublicEmbeddings `bun:"rel:has-many,join:guid=thought_id" json:"relthoughtidpublicembeddings,omitempty"` // Has many ModelPublicEmbeddings
RelThoughtIDPublicStoredFiles []*ModelPublicStoredFiles `bun:"rel:has-many,join:guid=thought_id" json:"relthoughtidpublicstoredfiles,omitempty"` // Has many ModelPublicStoredFiles
RelRelatedThoughtIDPublicLearnings []*ModelPublicLearnings `bun:"rel:has-many,join:guid=related_thought_id" json:"relrelatedthoughtidpubliclearnings,omitempty"` // Has many ModelPublicLearnings
}
// TableName returns the table name for ModelPublicThoughts
func (m ModelPublicThoughts) TableName() string {
return "public.thoughts"
}
// TableNameOnly returns the table name without schema for ModelPublicThoughts
func (m ModelPublicThoughts) TableNameOnly() string {
return "thoughts"
}
// SchemaName returns the schema name for ModelPublicThoughts
func (m ModelPublicThoughts) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicThoughts) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicThoughts) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicThoughts) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicThoughts) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicThoughts) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicThoughts) GetPrefix() string {
return "THO"
}

View File

@@ -0,0 +1,62 @@
// Code generated by relspecgo. DO NOT EDIT.
package generatedmodels
import (
"fmt"
resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
"github.com/uptrace/bun"
)
type ModelPublicToolAnnotations struct {
bun.BaseModel `bun:"table:public.tool_annotations,alias:tool_annotations"`
ID resolvespec_common.SqlInt64 `bun:"id,type:bigserial,pk,autoincrement," json:"id"`
CreatedAt resolvespec_common.SqlTimeStamp `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
Notes resolvespec_common.SqlString `bun:"notes,type:text,default:'',notnull," json:"notes"`
ToolName resolvespec_common.SqlString `bun:"tool_name,type:text,notnull," json:"tool_name"`
UpdatedAt resolvespec_common.SqlTimeStamp `bun:"updated_at,type:timestamptz,default:now(),notnull," json:"updated_at"`
}
// TableName returns the table name for ModelPublicToolAnnotations
func (m ModelPublicToolAnnotations) TableName() string {
return "public.tool_annotations"
}
// TableNameOnly returns the table name without schema for ModelPublicToolAnnotations
func (m ModelPublicToolAnnotations) TableNameOnly() string {
return "tool_annotations"
}
// SchemaName returns the schema name for ModelPublicToolAnnotations
func (m ModelPublicToolAnnotations) SchemaName() string {
return "public"
}
// GetID returns the primary key value
func (m ModelPublicToolAnnotations) GetID() int64 {
return m.ID.Int64()
}
// GetIDStr returns the primary key as a string
func (m ModelPublicToolAnnotations) GetIDStr() string {
return fmt.Sprintf("%v", m.ID)
}
// SetID sets the primary key value
func (m ModelPublicToolAnnotations) SetID(newid int64) {
m.UpdateID(newid)
}
// UpdateID updates the primary key value
func (m *ModelPublicToolAnnotations) UpdateID(newid int64) {
m.ID.FromString(fmt.Sprintf("%d", newid))
}
// GetIDName returns the name of the primary key column
func (m ModelPublicToolAnnotations) GetIDName() string {
return "id"
}
// GetPrefix returns the table prefix
func (m ModelPublicToolAnnotations) GetPrefix() string {
return "TAO"
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types" ext "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -19,9 +20,12 @@ func (db *DB) AddFamilyMember(ctx context.Context, m ext.FamilyMember) (ext.Fami
`, m.Name, nullStr(m.Relationship), m.BirthDate, nullStr(m.Notes)) `, m.Name, nullStr(m.Relationship), m.BirthDate, nullStr(m.Notes))
created := m created := m
if err := row.Scan(&created.ID, &created.CreatedAt); err != nil { var model generatedmodels.ModelPublicFamilyMembers
if err := row.Scan(&model.ID, &model.CreatedAt); err != nil {
return ext.FamilyMember{}, fmt.Errorf("insert family member: %w", err) return ext.FamilyMember{}, fmt.Errorf("insert family member: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
return created, nil return created, nil
} }
@@ -34,14 +38,11 @@ func (db *DB) ListFamilyMembers(ctx context.Context) ([]ext.FamilyMember, error)
var members []ext.FamilyMember var members []ext.FamilyMember
for rows.Next() { for rows.Next() {
var m ext.FamilyMember var model generatedmodels.ModelPublicFamilyMembers
var relationship, notes *string if err := rows.Scan(&model.ID, &model.Name, &model.Relationship, &model.BirthDate, &model.Notes, &model.CreatedAt); err != nil {
if err := rows.Scan(&m.ID, &m.Name, &relationship, &m.BirthDate, &notes, &m.CreatedAt); err != nil {
return nil, fmt.Errorf("scan family member: %w", err) return nil, fmt.Errorf("scan family member: %w", err)
} }
m.Relationship = strVal(relationship) members = append(members, familyMemberFromModel(model))
m.Notes = strVal(notes)
members = append(members, m)
} }
return members, rows.Err() return members, rows.Err()
} }
@@ -56,9 +57,12 @@ func (db *DB) AddActivity(ctx context.Context, a ext.Activity) (ext.Activity, er
nullStr(a.Location), nullStr(a.Notes)) nullStr(a.Location), nullStr(a.Notes))
created := a created := a
if err := row.Scan(&created.ID, &created.CreatedAt); err != nil { var model generatedmodels.ModelPublicActivities
if err := row.Scan(&model.ID, &model.CreatedAt); err != nil {
return ext.Activity{}, fmt.Errorf("insert activity: %w", err) return ext.Activity{}, fmt.Errorf("insert activity: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
return created, nil return created, nil
} }
@@ -129,9 +133,12 @@ func (db *DB) AddImportantDate(ctx context.Context, d ext.ImportantDate) (ext.Im
`, d.FamilyMemberID, d.Title, d.DateValue, d.RecurringYearly, d.ReminderDaysBefore, nullStr(d.Notes)) `, d.FamilyMemberID, d.Title, d.DateValue, d.RecurringYearly, d.ReminderDaysBefore, nullStr(d.Notes))
created := d created := d
if err := row.Scan(&created.ID, &created.CreatedAt); err != nil { var model generatedmodels.ModelPublicImportantDates
if err := row.Scan(&model.ID, &model.CreatedAt); err != nil {
return ext.ImportantDate{}, fmt.Errorf("insert important date: %w", err) return ext.ImportantDate{}, fmt.Errorf("insert important date: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
return created, nil return created, nil
} }
@@ -164,17 +171,13 @@ func (db *DB) GetUpcomingDates(ctx context.Context, daysAhead int) ([]ext.Import
var dates []ext.ImportantDate var dates []ext.ImportantDate
for rows.Next() { for rows.Next() {
var d ext.ImportantDate var model generatedmodels.ModelPublicImportantDates
var memberID *uuid.UUID var memberName *string
var memberName, notes *string if err := rows.Scan(&model.ID, &model.FamilyMemberID, &memberName, &model.Title, &model.DateValue,
if err := rows.Scan(&d.ID, &memberID, &memberName, &d.Title, &d.DateValue, &model.RecurringYearly, &model.ReminderDaysBefore, &model.Notes, &model.CreatedAt); err != nil {
&d.RecurringYearly, &d.ReminderDaysBefore, &notes, &d.CreatedAt); err != nil {
return nil, fmt.Errorf("scan important date: %w", err) return nil, fmt.Errorf("scan important date: %w", err)
} }
d.FamilyMemberID = memberID dates = append(dates, importantDateFromModel(model, strVal(memberName)))
d.MemberName = strVal(memberName)
d.Notes = strVal(notes)
dates = append(dates, d)
} }
return dates, rows.Err() return dates, rows.Err()
} }
@@ -188,23 +191,16 @@ func scanActivities(rows interface {
defer rows.Close() defer rows.Close()
var activities []ext.Activity var activities []ext.Activity
for rows.Next() { for rows.Next() {
var a ext.Activity var model generatedmodels.ModelPublicActivities
var memberName, activityType, dayOfWeek, startTime, endTime, location, notes *string var memberName *string
if err := rows.Scan( if err := rows.Scan(
&a.ID, &a.FamilyMemberID, &memberName, &a.Title, &activityType, &model.ID, &model.FamilyMemberID, &memberName, &model.Title, &model.ActivityType,
&dayOfWeek, &startTime, &endTime, &model.DayOfWeek, &model.StartTime, &model.EndTime,
&a.StartDate, &a.EndDate, &location, &notes, &a.CreatedAt, &model.StartDate, &model.EndDate, &model.Location, &model.Notes, &model.CreatedAt,
); err != nil { ); err != nil {
return nil, fmt.Errorf("scan activity: %w", err) return nil, fmt.Errorf("scan activity: %w", err)
} }
a.MemberName = strVal(memberName) activities = append(activities, activityFromModel(model, strVal(memberName)))
a.ActivityType = strVal(activityType)
a.DayOfWeek = strVal(dayOfWeek)
a.StartTime = strVal(startTime)
a.EndTime = strVal(endTime)
a.Location = strVal(location)
a.Notes = strVal(notes)
activities = append(activities, a)
} }
return activities, rows.Err() return activities, rows.Err()
} }

View File

@@ -10,6 +10,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types" ext "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -34,9 +35,13 @@ func (db *DB) SaveChatHistory(ctx context.Context, h ext.ChatHistory) (ext.ChatH
) )
created := h created := h
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicChatHistories
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.ChatHistory{}, fmt.Errorf("insert chat history: %w", err) return ext.ChatHistory{}, fmt.Errorf("insert chat history: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -157,26 +162,33 @@ type rowScanner interface {
} }
func scanChatHistory(row rowScanner) (ext.ChatHistory, error) { func scanChatHistory(row rowScanner) (ext.ChatHistory, error) {
var h ext.ChatHistory var model generatedmodels.ModelPublicChatHistories
var title, channel, agentID, summary *string
var messagesJSON, metaJSON []byte
if err := row.Scan( if err := row.Scan(
&h.ID, &h.SessionID, &title, &channel, &agentID, &h.ProjectID, &model.ID, &model.SessionID, &model.Title, &model.Channel, &model.AgentID, &model.ProjectID,
&messagesJSON, &summary, &metaJSON, &h.CreatedAt, &h.UpdatedAt, &model.Messages, &model.Summary, &model.Metadata, &model.CreatedAt, &model.UpdatedAt,
); err != nil { ); err != nil {
return ext.ChatHistory{}, err return ext.ChatHistory{}, err
} }
h.Title = strVal(title) h := ext.ChatHistory{
h.Channel = strVal(channel) ID: model.ID.UUID(),
h.AgentID = strVal(agentID) SessionID: model.SessionID.String(),
h.Summary = strVal(summary) Title: model.Title.String(),
Channel: model.Channel.String(),
AgentID: model.AgentID.String(),
Summary: model.Summary.String(),
CreatedAt: model.CreatedAt.Time(),
UpdatedAt: model.UpdatedAt.Time(),
}
if model.ProjectID.Valid {
id := model.ProjectID.UUID()
h.ProjectID = &id
}
if err := json.Unmarshal(messagesJSON, &h.Messages); err != nil { if err := json.Unmarshal(model.Messages, &h.Messages); err != nil {
return ext.ChatHistory{}, fmt.Errorf("unmarshal messages: %w", err) return ext.ChatHistory{}, fmt.Errorf("unmarshal messages: %w", err)
} }
if err := json.Unmarshal(metaJSON, &h.Metadata); err != nil { if err := json.Unmarshal(model.Metadata, &h.Metadata); err != nil {
return ext.ChatHistory{}, fmt.Errorf("unmarshal metadata: %w", err) return ext.ChatHistory{}, fmt.Errorf("unmarshal metadata: %w", err)
} }
if h.Messages == nil { if h.Messages == nil {

View File

@@ -8,6 +8,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types" ext "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -24,9 +25,13 @@ func (db *DB) AddProfessionalContact(ctx context.Context, c ext.ProfessionalCont
nullStr(c.LinkedInURL), nullStr(c.HowWeMet), c.Tags, nullStr(c.Notes), c.FollowUpDate) nullStr(c.LinkedInURL), nullStr(c.HowWeMet), c.Tags, nullStr(c.Notes), c.FollowUpDate)
created := c created := c
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicProfessionalContacts
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.ProfessionalContact{}, fmt.Errorf("insert contact: %w", err) return ext.ProfessionalContact{}, fmt.Errorf("insert contact: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -45,7 +50,7 @@ func (db *DB) SearchContacts(ctx context.Context, query string, tags []string) (
conditions = append(conditions, fmt.Sprintf("tags @> $%d", len(args))) conditions = append(conditions, fmt.Sprintf("tags @> $%d", len(args)))
} }
q := `select id, name, company, title, email, phone, linkedin_url, how_we_met, tags, notes, last_contacted, follow_up_date, created_at, updated_at from professional_contacts` q := `select id, name, company, title, email, phone, linkedin_url, how_we_met, tags::text[], notes, last_contacted, follow_up_date, created_at, updated_at from professional_contacts`
if len(conditions) > 0 { if len(conditions) > 0 {
q += " where " + strings.Join(conditions, " and ") q += " where " + strings.Join(conditions, " and ")
} }
@@ -62,27 +67,18 @@ func (db *DB) SearchContacts(ctx context.Context, query string, tags []string) (
func (db *DB) GetContact(ctx context.Context, id uuid.UUID) (ext.ProfessionalContact, error) { func (db *DB) GetContact(ctx context.Context, id uuid.UUID) (ext.ProfessionalContact, error) {
row := db.pool.QueryRow(ctx, ` row := db.pool.QueryRow(ctx, `
select id, name, company, title, email, phone, linkedin_url, how_we_met, tags, notes, last_contacted, follow_up_date, created_at, updated_at select id, name, company, title, email, phone, linkedin_url, how_we_met, tags::text[], notes, last_contacted, follow_up_date, created_at, updated_at
from professional_contacts where id = $1 from professional_contacts where id = $1
`, id) `, id)
var c ext.ProfessionalContact var model generatedmodels.ModelPublicProfessionalContacts
var company, title, email, phone, linkedInURL, howWeMet, notes *string var tags []string
if err := row.Scan(&c.ID, &c.Name, &company, &title, &email, &phone, if err := row.Scan(&model.ID, &model.Name, &model.Company, &model.Title, &model.Email, &model.Phone,
&linkedInURL, &howWeMet, &c.Tags, &notes, &c.LastContacted, &c.FollowUpDate, &model.LinkedinURL, &model.HowWeMet, &tags, &model.Notes, &model.LastContacted, &model.FollowUpDate,
&c.CreatedAt, &c.UpdatedAt); err != nil { &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.ProfessionalContact{}, fmt.Errorf("get contact: %w", err) return ext.ProfessionalContact{}, fmt.Errorf("get contact: %w", err)
} }
c.Company = strVal(company) c := professionalContactFromModel(model, tags)
c.Title = strVal(title)
c.Email = strVal(email)
c.Phone = strVal(phone)
c.LinkedInURL = strVal(linkedInURL)
c.HowWeMet = strVal(howWeMet)
c.Notes = strVal(notes)
if c.Tags == nil {
c.Tags = []string{}
}
return c, nil return c, nil
} }
@@ -101,9 +97,12 @@ func (db *DB) LogInteraction(ctx context.Context, interaction ext.ContactInterac
created := interaction created := interaction
created.OccurredAt = occurredAt created.OccurredAt = occurredAt
if err := row.Scan(&created.ID, &created.CreatedAt); err != nil { var model generatedmodels.ModelPublicContactInteractions
if err := row.Scan(&model.ID, &model.CreatedAt); err != nil {
return ext.ContactInteraction{}, fmt.Errorf("insert interaction: %w", err) return ext.ContactInteraction{}, fmt.Errorf("insert interaction: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
return created, nil return created, nil
} }
@@ -124,14 +123,12 @@ func (db *DB) GetContactHistory(ctx context.Context, contactID uuid.UUID) (ext.C
var interactions []ext.ContactInteraction var interactions []ext.ContactInteraction
for rows.Next() { for rows.Next() {
var i ext.ContactInteraction var model generatedmodels.ModelPublicContactInteractions
var followUpNotes *string if err := rows.Scan(&model.ID, &model.ContactID, &model.InteractionType, &model.OccurredAt, &model.Summary,
if err := rows.Scan(&i.ID, &i.ContactID, &i.InteractionType, &i.OccurredAt, &i.Summary, &model.FollowUpNeeded, &model.FollowUpNotes, &model.CreatedAt); err != nil {
&i.FollowUpNeeded, &followUpNotes, &i.CreatedAt); err != nil {
return ext.ContactHistory{}, fmt.Errorf("scan interaction: %w", err) return ext.ContactHistory{}, fmt.Errorf("scan interaction: %w", err)
} }
i.FollowUpNotes = strVal(followUpNotes) interactions = append(interactions, contactInteractionFromModel(model))
interactions = append(interactions, i)
} }
if err := rows.Err(); err != nil { if err := rows.Err(); err != nil {
return ext.ContactHistory{}, err return ext.ContactHistory{}, err
@@ -148,15 +145,12 @@ func (db *DB) GetContactHistory(ctx context.Context, contactID uuid.UUID) (ext.C
var opportunities []ext.Opportunity var opportunities []ext.Opportunity
for oppRows.Next() { for oppRows.Next() {
var o ext.Opportunity var model generatedmodels.ModelPublicOpportunities
var description, notes *string if err := oppRows.Scan(&model.ID, &model.ContactID, &model.Title, &model.Description, &model.Stage, &model.Value,
if err := oppRows.Scan(&o.ID, &o.ContactID, &o.Title, &description, &o.Stage, &o.Value, &model.ExpectedCloseDate, &model.Notes, &model.CreatedAt, &model.UpdatedAt); err != nil {
&o.ExpectedCloseDate, &notes, &o.CreatedAt, &o.UpdatedAt); err != nil {
return ext.ContactHistory{}, fmt.Errorf("scan opportunity: %w", err) return ext.ContactHistory{}, fmt.Errorf("scan opportunity: %w", err)
} }
o.Description = strVal(description) opportunities = append(opportunities, opportunityFromModel(model))
o.Notes = strVal(notes)
opportunities = append(opportunities, o)
} }
if err := oppRows.Err(); err != nil { if err := oppRows.Err(); err != nil {
return ext.ContactHistory{}, err return ext.ContactHistory{}, err
@@ -177,9 +171,13 @@ func (db *DB) CreateOpportunity(ctx context.Context, o ext.Opportunity) (ext.Opp
`, o.ContactID, o.Title, nullStr(o.Description), o.Stage, o.Value, o.ExpectedCloseDate, nullStr(o.Notes)) `, o.ContactID, o.Title, nullStr(o.Description), o.Stage, o.Value, o.ExpectedCloseDate, nullStr(o.Notes))
created := o created := o
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicOpportunities
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.Opportunity{}, fmt.Errorf("insert opportunity: %w", err) return ext.Opportunity{}, fmt.Errorf("insert opportunity: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -190,7 +188,7 @@ func (db *DB) GetFollowUpsDue(ctx context.Context, daysAhead int) ([]ext.Profess
cutoff := time.Now().AddDate(0, 0, daysAhead) cutoff := time.Now().AddDate(0, 0, daysAhead)
rows, err := db.pool.Query(ctx, ` rows, err := db.pool.Query(ctx, `
select id, name, company, title, email, phone, linkedin_url, how_we_met, tags, notes, last_contacted, follow_up_date, created_at, updated_at select id, name, company, title, email, phone, linkedin_url, how_we_met, tags::text[], notes, last_contacted, follow_up_date, created_at, updated_at
from professional_contacts from professional_contacts
where follow_up_date <= $1 where follow_up_date <= $1
order by follow_up_date asc order by follow_up_date asc
@@ -224,24 +222,14 @@ func scanContacts(rows interface {
defer rows.Close() defer rows.Close()
var contacts []ext.ProfessionalContact var contacts []ext.ProfessionalContact
for rows.Next() { for rows.Next() {
var c ext.ProfessionalContact var model generatedmodels.ModelPublicProfessionalContacts
var company, title, email, phone, linkedInURL, howWeMet, notes *string var tags []string
if err := rows.Scan(&c.ID, &c.Name, &company, &title, &email, &phone, if err := rows.Scan(&model.ID, &model.Name, &model.Company, &model.Title, &model.Email, &model.Phone,
&linkedInURL, &howWeMet, &c.Tags, &notes, &c.LastContacted, &c.FollowUpDate, &model.LinkedinURL, &model.HowWeMet, &tags, &model.Notes, &model.LastContacted, &model.FollowUpDate,
&c.CreatedAt, &c.UpdatedAt); err != nil { &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan contact: %w", err) return nil, fmt.Errorf("scan contact: %w", err)
} }
c.Company = strVal(company) contacts = append(contacts, professionalContactFromModel(model, tags))
c.Title = strVal(title)
c.Email = strVal(email)
c.Phone = strVal(phone)
c.LinkedInURL = strVal(linkedInURL)
c.HowWeMet = strVal(howWeMet)
c.Notes = strVal(notes)
if c.Tags == nil {
c.Tags = []string{}
}
contacts = append(contacts, c)
} }
return contacts, rows.Err() return contacts, rows.Err()
} }

View File

@@ -2,18 +2,23 @@ package store
import ( import (
"context" "context"
"database/sql"
"fmt" "fmt"
"time" "time"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/pgxpool"
pgxvec "github.com/pgvector/pgvector-go/pgx" pgxvec "github.com/pgvector/pgvector-go/pgx"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/driver/pgdriver"
"git.warky.dev/wdevs/amcs/internal/config" "git.warky.dev/wdevs/amcs/internal/config"
) )
type DB struct { type DB struct {
pool *pgxpool.Pool pool *pgxpool.Pool
bun *bun.DB
} }
func New(ctx context.Context, cfg config.DatabaseConfig) (*DB, error) { func New(ctx context.Context, cfg config.DatabaseConfig) (*DB, error) {
@@ -35,8 +40,20 @@ func New(ctx context.Context, cfg config.DatabaseConfig) (*DB, error) {
return nil, fmt.Errorf("create database pool: %w", err) return nil, fmt.Errorf("create database pool: %w", err)
} }
db := &DB{pool: pool} bunSQLDB := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(cfg.URL)))
bunSQLDB.SetMaxOpenConns(int(cfg.MaxConns))
bunSQLDB.SetMaxIdleConns(int(cfg.MinConns))
bunSQLDB.SetConnMaxLifetime(cfg.MaxConnLifetime)
bunSQLDB.SetConnMaxIdleTime(cfg.MaxConnIdleTime)
db := &DB{
pool: pool,
bun: bun.NewDB(bunSQLDB, pgdialect.New()),
}
if err := db.Ping(ctx); err != nil { if err := db.Ping(ctx); err != nil {
if db.bun != nil {
_ = db.bun.Close()
}
pool.Close() pool.Close()
return nil, err return nil, err
} }
@@ -45,12 +62,17 @@ func New(ctx context.Context, cfg config.DatabaseConfig) (*DB, error) {
} }
func (db *DB) Close() { func (db *DB) Close() {
if db == nil || db.pool == nil { if db == nil {
return return
} }
if db.bun != nil {
_ = db.bun.Close()
}
if db.pool != nil {
db.pool.Close() db.pool.Close()
} }
}
func (db *DB) Ping(ctx context.Context) error { func (db *DB) Ping(ctx context.Context) error {
if err := db.pool.Ping(ctx); err != nil { if err := db.pool.Ping(ctx); err != nil {
@@ -102,3 +124,10 @@ func (db *DB) VerifyRequirements(ctx context.Context) error {
return nil return nil
} }
func (db *DB) Bun() *bun.DB {
if db == nil {
return nil
}
return db.bun
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
thoughttypes "git.warky.dev/wdevs/amcs/internal/types" thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -19,24 +20,24 @@ func (db *DB) InsertStoredFile(ctx context.Context, file thoughttypes.StoredFile
returning guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, created_at, updated_at returning guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, created_at, updated_at
`, file.ThoughtID, file.ProjectID, file.Name, file.MediaType, file.Kind, file.Encoding, file.SizeBytes, file.SHA256, file.Content) `, file.ThoughtID, file.ProjectID, file.Name, file.MediaType, file.Kind, file.Encoding, file.SizeBytes, file.SHA256, file.Content)
var created thoughttypes.StoredFile var model generatedmodels.ModelPublicStoredFiles
if err := row.Scan( if err := row.Scan(
&created.ID, &model.GUID,
&created.ThoughtID, &model.ThoughtID,
&created.ProjectID, &model.ProjectID,
&created.Name, &model.Name,
&created.MediaType, &model.MediaType,
&created.Kind, &model.Kind,
&created.Encoding, &model.Encoding,
&created.SizeBytes, &model.SizeBytes,
&created.SHA256, &model.Sha256,
&created.CreatedAt, &model.CreatedAt,
&created.UpdatedAt, &model.UpdatedAt,
); err != nil { ); err != nil {
return thoughttypes.StoredFile{}, fmt.Errorf("insert stored file: %w", err) return thoughttypes.StoredFile{}, fmt.Errorf("insert stored file: %w", err)
} }
return created, nil return storedFileFromModel(model), nil
} }
func (db *DB) GetStoredFile(ctx context.Context, id uuid.UUID) (thoughttypes.StoredFile, error) { func (db *DB) GetStoredFile(ctx context.Context, id uuid.UUID) (thoughttypes.StoredFile, error) {
@@ -46,20 +47,20 @@ func (db *DB) GetStoredFile(ctx context.Context, id uuid.UUID) (thoughttypes.Sto
where guid = $1 where guid = $1
`, id) `, id)
var file thoughttypes.StoredFile var model generatedmodels.ModelPublicStoredFiles
if err := row.Scan( if err := row.Scan(
&file.ID, &model.GUID,
&file.ThoughtID, &model.ThoughtID,
&file.ProjectID, &model.ProjectID,
&file.Name, &model.Name,
&file.MediaType, &model.MediaType,
&file.Kind, &model.Kind,
&file.Encoding, &model.Encoding,
&file.SizeBytes, &model.SizeBytes,
&file.SHA256, &model.Sha256,
&file.Content, &model.Content,
&file.CreatedAt, &model.CreatedAt,
&file.UpdatedAt, &model.UpdatedAt,
); err != nil { ); err != nil {
if err == pgx.ErrNoRows { if err == pgx.ErrNoRows {
return thoughttypes.StoredFile{}, err return thoughttypes.StoredFile{}, err
@@ -67,7 +68,7 @@ func (db *DB) GetStoredFile(ctx context.Context, id uuid.UUID) (thoughttypes.Sto
return thoughttypes.StoredFile{}, fmt.Errorf("get stored file: %w", err) return thoughttypes.StoredFile{}, fmt.Errorf("get stored file: %w", err)
} }
return file, nil return storedFileFromModel(model), nil
} }
func (db *DB) ListStoredFiles(ctx context.Context, filter thoughttypes.StoredFileFilter) ([]thoughttypes.StoredFile, error) { func (db *DB) ListStoredFiles(ctx context.Context, filter thoughttypes.StoredFileFilter) ([]thoughttypes.StoredFile, error) {
@@ -106,23 +107,23 @@ func (db *DB) ListStoredFiles(ctx context.Context, filter thoughttypes.StoredFil
files := make([]thoughttypes.StoredFile, 0, filter.Limit) files := make([]thoughttypes.StoredFile, 0, filter.Limit)
for rows.Next() { for rows.Next() {
var file thoughttypes.StoredFile var model generatedmodels.ModelPublicStoredFiles
if err := rows.Scan( if err := rows.Scan(
&file.ID, &model.GUID,
&file.ThoughtID, &model.ThoughtID,
&file.ProjectID, &model.ProjectID,
&file.Name, &model.Name,
&file.MediaType, &model.MediaType,
&file.Kind, &model.Kind,
&file.Encoding, &model.Encoding,
&file.SizeBytes, &model.SizeBytes,
&file.SHA256, &model.Sha256,
&file.CreatedAt, &model.CreatedAt,
&file.UpdatedAt, &model.UpdatedAt,
); err != nil { ); err != nil {
return nil, fmt.Errorf("scan stored file: %w", err) return nil, fmt.Errorf("scan stored file: %w", err)
} }
files = append(files, file) files = append(files, storedFileFromModel(model))
} }
if err := rows.Err(); err != nil { if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate stored files: %w", err) return nil, fmt.Errorf("iterate stored files: %w", err)

View File

@@ -5,10 +5,10 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings" "strings"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types" ext "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -25,9 +25,13 @@ func (db *DB) AddHouseholdItem(ctx context.Context, item ext.HouseholdItem) (ext
`, item.Name, nullStr(item.Category), nullStr(item.Location), details, nullStr(item.Notes)) `, item.Name, nullStr(item.Category), nullStr(item.Location), details, nullStr(item.Notes))
created := item created := item
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicHouseholdItems
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.HouseholdItem{}, fmt.Errorf("insert household item: %w", err) return ext.HouseholdItem{}, fmt.Errorf("insert household item: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -62,19 +66,11 @@ func (db *DB) SearchHouseholdItems(ctx context.Context, query, category, locatio
var items []ext.HouseholdItem var items []ext.HouseholdItem
for rows.Next() { for rows.Next() {
var item ext.HouseholdItem var model generatedmodels.ModelPublicHouseholdItems
var detailsBytes []byte if err := rows.Scan(&model.ID, &model.Name, &model.Category, &model.Location, &model.Details, &model.Notes, &model.CreatedAt, &model.UpdatedAt); err != nil {
var category, location, notes *string
if err := rows.Scan(&item.ID, &item.Name, &category, &location, &detailsBytes, &notes, &item.CreatedAt, &item.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan household item: %w", err) return nil, fmt.Errorf("scan household item: %w", err)
} }
item.Category = strVal(category) items = append(items, householdItemFromModel(model))
item.Location = strVal(location)
item.Notes = strVal(notes)
if err := json.Unmarshal(detailsBytes, &item.Details); err != nil {
item.Details = map[string]any{}
}
items = append(items, item)
} }
return items, rows.Err() return items, rows.Err()
} }
@@ -85,19 +81,11 @@ func (db *DB) GetHouseholdItem(ctx context.Context, id uuid.UUID) (ext.Household
from household_items where id = $1 from household_items where id = $1
`, id) `, id)
var item ext.HouseholdItem var model generatedmodels.ModelPublicHouseholdItems
var detailsBytes []byte if err := row.Scan(&model.ID, &model.Name, &model.Category, &model.Location, &model.Details, &model.Notes, &model.CreatedAt, &model.UpdatedAt); err != nil {
var category, location, notes *string
if err := row.Scan(&item.ID, &item.Name, &category, &location, &detailsBytes, &notes, &item.CreatedAt, &item.UpdatedAt); err != nil {
return ext.HouseholdItem{}, fmt.Errorf("get household item: %w", err) return ext.HouseholdItem{}, fmt.Errorf("get household item: %w", err)
} }
item.Category = strVal(category) return householdItemFromModel(model), nil
item.Location = strVal(location)
item.Notes = strVal(notes)
if err := json.Unmarshal(detailsBytes, &item.Details); err != nil {
item.Details = map[string]any{}
}
return item, nil
} }
func (db *DB) AddVendor(ctx context.Context, v ext.HouseholdVendor) (ext.HouseholdVendor, error) { func (db *DB) AddVendor(ctx context.Context, v ext.HouseholdVendor) (ext.HouseholdVendor, error) {
@@ -109,9 +97,12 @@ func (db *DB) AddVendor(ctx context.Context, v ext.HouseholdVendor) (ext.Househo
nullStr(v.Website), nullStr(v.Notes), v.Rating, v.LastUsed) nullStr(v.Website), nullStr(v.Notes), v.Rating, v.LastUsed)
created := v created := v
if err := row.Scan(&created.ID, &created.CreatedAt); err != nil { var model generatedmodels.ModelPublicHouseholdVendors
if err := row.Scan(&model.ID, &model.CreatedAt); err != nil {
return ext.HouseholdVendor{}, fmt.Errorf("insert vendor: %w", err) return ext.HouseholdVendor{}, fmt.Errorf("insert vendor: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
return created, nil return created, nil
} }
@@ -132,19 +123,11 @@ func (db *DB) ListVendors(ctx context.Context, serviceType string) ([]ext.Househ
var vendors []ext.HouseholdVendor var vendors []ext.HouseholdVendor
for rows.Next() { for rows.Next() {
var v ext.HouseholdVendor var model generatedmodels.ModelPublicHouseholdVendors
var serviceType, phone, email, website, notes *string if err := rows.Scan(&model.ID, &model.Name, &model.ServiceType, &model.Phone, &model.Email, &model.Website, &model.Notes, &model.Rating, &model.LastUsed, &model.CreatedAt); err != nil {
var lastUsed *time.Time
if err := rows.Scan(&v.ID, &v.Name, &serviceType, &phone, &email, &website, &notes, &v.Rating, &lastUsed, &v.CreatedAt); err != nil {
return nil, fmt.Errorf("scan vendor: %w", err) return nil, fmt.Errorf("scan vendor: %w", err)
} }
v.ServiceType = strVal(serviceType) vendors = append(vendors, householdVendorFromModel(model))
v.Phone = strVal(phone)
v.Email = strVal(email)
v.Website = strVal(website)
v.Notes = strVal(notes)
v.LastUsed = lastUsed
vendors = append(vendors, v)
} }
return vendors, rows.Err() return vendors, rows.Err()
} }

View File

@@ -5,9 +5,9 @@ import (
"fmt" "fmt"
"strings" "strings"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
thoughttypes "git.warky.dev/wdevs/amcs/internal/types" thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -48,9 +48,13 @@ func (db *DB) CreateLearning(ctx context.Context, learning thoughttypes.Learning
) )
created := learning created := learning
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicLearnings
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return thoughttypes.Learning{}, fmt.Errorf("create learning: %w", err) return thoughttypes.Learning{}, fmt.Errorf("create learning: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -59,7 +63,7 @@ func (db *DB) GetLearning(ctx context.Context, id uuid.UUID) (thoughttypes.Learn
select id, summary, details, category, area, status, priority, confidence, select id, summary, details, category, area, status, priority, confidence,
action_required, source_type, source_ref, project_id, related_thought_id, action_required, source_type, source_ref, project_id, related_thought_id,
related_skill_id, reviewed_by, reviewed_at, duplicate_of_learning_id, related_skill_id, reviewed_by, reviewed_at, duplicate_of_learning_id,
supersedes_learning_id, tags, created_at, updated_at supersedes_learning_id, tags::text[], created_at, updated_at
from learnings from learnings
where id = $1 where id = $1
`, id) `, id)
@@ -111,7 +115,7 @@ func (db *DB) ListLearnings(ctx context.Context, filter thoughttypes.LearningFil
select id, summary, details, category, area, status, priority, confidence, select id, summary, details, category, area, status, priority, confidence,
action_required, source_type, source_ref, project_id, related_thought_id, action_required, source_type, source_ref, project_id, related_thought_id,
related_skill_id, reviewed_by, reviewed_at, duplicate_of_learning_id, related_skill_id, reviewed_by, reviewed_at, duplicate_of_learning_id,
supersedes_learning_id, tags, created_at, updated_at supersedes_learning_id, tags::text[], created_at, updated_at
from learnings from learnings
` `
if len(conditions) > 0 { if len(conditions) > 0 {
@@ -148,51 +152,40 @@ type learningScanner interface {
} }
func scanLearning(row learningScanner) (thoughttypes.Learning, error) { func scanLearning(row learningScanner) (thoughttypes.Learning, error) {
var learning thoughttypes.Learning var model generatedmodels.ModelPublicLearnings
var sourceType pgtype.Text
var sourceRef pgtype.Text
var reviewedBy pgtype.Text
var tags []string var tags []string
err := row.Scan( err := row.Scan(
&learning.ID, &model.ID,
&learning.Summary, &model.Summary,
&learning.Details, &model.Details,
&learning.Category, &model.Category,
&learning.Area, &model.Area,
&learning.Status, &model.Status,
&learning.Priority, &model.Priority,
&learning.Confidence, &model.Confidence,
&learning.ActionRequired, &model.ActionRequired,
&sourceType, &model.SourceType,
&sourceRef, &model.SourceRef,
&learning.ProjectID, &model.ProjectID,
&learning.RelatedThoughtID, &model.RelatedThoughtID,
&learning.RelatedSkillID, &model.RelatedSkillID,
&reviewedBy, &model.ReviewedBy,
&learning.ReviewedAt, &model.ReviewedAt,
&learning.DuplicateOfLearningID, &model.DuplicateOfLearningID,
&learning.SupersedesLearningID, &model.SupersedesLearningID,
&tags, &tags,
&learning.CreatedAt, &model.CreatedAt,
&learning.UpdatedAt, &model.UpdatedAt,
) )
if err != nil { if err != nil {
return thoughttypes.Learning{}, err return thoughttypes.Learning{}, err
} }
learning.SourceType = sourceType.String
learning.SourceRef = sourceRef.String
if reviewedBy.Valid {
value := reviewedBy.String
learning.ReviewedBy = &value
}
if tags == nil { if tags == nil {
learning.Tags = []string{} tags = []string{}
} else {
learning.Tags = tags
} }
return learning, nil return learningFromModel(model, tags), nil
} }
func nullableText(value string) *string { func nullableText(value string) *string {

View File

@@ -2,11 +2,11 @@ package store
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"github.com/google/uuid" "github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
thoughttypes "git.warky.dev/wdevs/amcs/internal/types" thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -44,24 +44,26 @@ func (db *DB) LinkedThoughts(ctx context.Context, thoughtID uuid.UUID) ([]though
links := make([]thoughttypes.LinkedThought, 0) links := make([]thoughttypes.LinkedThought, 0)
for rows.Next() { for rows.Next() {
var linked thoughttypes.LinkedThought var linked thoughttypes.LinkedThought
var metadataBytes []byte var model generatedmodels.ModelPublicThoughts
if err := rows.Scan( if err := rows.Scan(
&linked.Thought.ID, &model.GUID,
&linked.Thought.Content, &model.Content,
&metadataBytes, &model.Metadata,
&linked.Thought.ProjectID, &model.ProjectID,
&linked.Thought.ArchivedAt, &model.ArchivedAt,
&linked.Thought.CreatedAt, &model.CreatedAt,
&linked.Thought.UpdatedAt, &model.UpdatedAt,
&linked.Relation, &linked.Relation,
&linked.Direction, &linked.Direction,
&linked.CreatedAt, &linked.CreatedAt,
); err != nil { ); err != nil {
return nil, fmt.Errorf("scan linked thought: %w", err) return nil, fmt.Errorf("scan linked thought: %w", err)
} }
if err := json.Unmarshal(metadataBytes, &linked.Thought.Metadata); err != nil { thought, err := thoughtFromModel(model)
return nil, fmt.Errorf("decode linked thought metadata: %w", err) if err != nil {
return nil, fmt.Errorf("map linked thought: %w", err)
} }
linked.Thought = thought
links = append(links, linked) links = append(links, linked)
} }
if err := rows.Err(); err != nil { if err := rows.Err(); err != nil {

View File

@@ -6,6 +6,7 @@ import (
"strings" "strings"
"time" "time"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types" ext "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -17,9 +18,13 @@ func (db *DB) AddMaintenanceTask(ctx context.Context, t ext.MaintenanceTask) (ex
`, t.Name, nullStr(t.Category), t.FrequencyDays, t.NextDue, t.Priority, nullStr(t.Notes)) `, t.Name, nullStr(t.Category), t.FrequencyDays, t.NextDue, t.Priority, nullStr(t.Notes))
created := t created := t
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicMaintenanceTasks
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.MaintenanceTask{}, fmt.Errorf("insert maintenance task: %w", err) return ext.MaintenanceTask{}, fmt.Errorf("insert maintenance task: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -37,9 +42,11 @@ func (db *DB) LogMaintenance(ctx context.Context, log ext.MaintenanceLog) (ext.M
created := log created := log
created.CompletedAt = completedAt created.CompletedAt = completedAt
if err := row.Scan(&created.ID); err != nil { var model generatedmodels.ModelPublicMaintenanceLogs
if err := row.Scan(&model.ID); err != nil {
return ext.MaintenanceLog{}, fmt.Errorf("insert maintenance log: %w", err) return ext.MaintenanceLog{}, fmt.Errorf("insert maintenance log: %w", err)
} }
created.ID = model.ID.UUID()
return created, nil return created, nil
} }
@@ -60,7 +67,15 @@ func (db *DB) GetUpcomingMaintenance(ctx context.Context, daysAhead int) ([]ext.
} }
defer rows.Close() defer rows.Close()
return scanMaintenanceTasks(rows) tasks := make([]ext.MaintenanceTask, 0)
for rows.Next() {
var model generatedmodels.ModelPublicMaintenanceTasks
if err := rows.Scan(&model.ID, &model.Name, &model.Category, &model.FrequencyDays, &model.LastCompleted, &model.NextDue, &model.Priority, &model.Notes, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan maintenance task: %w", err)
}
tasks = append(tasks, maintenanceTaskFromModel(model))
}
return tasks, rows.Err()
} }
func (db *DB) SearchMaintenanceHistory(ctx context.Context, query, category string, start, end *time.Time) ([]ext.MaintenanceLogWithTask, error) { func (db *DB) SearchMaintenanceHistory(ctx context.Context, query, category string, start, end *time.Time) ([]ext.MaintenanceLogWithTask, error) {
@@ -103,40 +118,20 @@ func (db *DB) SearchMaintenanceHistory(ctx context.Context, query, category stri
var logs []ext.MaintenanceLogWithTask var logs []ext.MaintenanceLogWithTask
for rows.Next() { for rows.Next() {
var l ext.MaintenanceLogWithTask var model generatedmodels.ModelPublicMaintenanceLogs
var performedBy, notes, nextAction, taskCategory *string var taskName, taskCategory string
if err := rows.Scan( if err := rows.Scan(
&l.ID, &l.TaskID, &l.CompletedAt, &performedBy, &l.Cost, &notes, &nextAction, &model.ID, &model.TaskID, &model.CompletedAt, &model.PerformedBy, &model.Cost, &model.Notes, &model.NextAction,
&l.TaskName, &taskCategory, &taskName, &taskCategory,
); err != nil { ); err != nil {
return nil, fmt.Errorf("scan maintenance log: %w", err) return nil, fmt.Errorf("scan maintenance log: %w", err)
} }
l.PerformedBy = strVal(performedBy) l := ext.MaintenanceLogWithTask{
l.Notes = strVal(notes) MaintenanceLog: maintenanceLogFromModel(model),
l.NextAction = strVal(nextAction) TaskName: taskName,
l.TaskCategory = strVal(taskCategory) TaskCategory: taskCategory,
}
logs = append(logs, l) logs = append(logs, l)
} }
return logs, rows.Err() return logs, rows.Err()
} }
func scanMaintenanceTasks(rows interface {
Next() bool
Scan(...any) error
Err() error
Close()
}) ([]ext.MaintenanceTask, error) {
defer rows.Close()
var tasks []ext.MaintenanceTask
for rows.Next() {
var t ext.MaintenanceTask
var category, notes *string
if err := rows.Scan(&t.ID, &t.Name, &category, &t.FrequencyDays, &t.LastCompleted, &t.NextDue, &t.Priority, &notes, &t.CreatedAt, &t.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan maintenance task: %w", err)
}
t.Category = strVal(category)
t.Notes = strVal(notes)
tasks = append(tasks, t)
}
return tasks, rows.Err()
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types" ext "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -33,9 +34,13 @@ func (db *DB) AddRecipe(ctx context.Context, r ext.Recipe) (ext.Recipe, error) {
ingredients, instructions, r.Tags, r.Rating, nullStr(r.Notes)) ingredients, instructions, r.Tags, r.Rating, nullStr(r.Notes))
created := r created := r
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicRecipes
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.Recipe{}, fmt.Errorf("insert recipe: %w", err) return ext.Recipe{}, fmt.Errorf("insert recipe: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -60,7 +65,7 @@ func (db *DB) SearchRecipes(ctx context.Context, query, cuisine string, tags []s
conditions = append(conditions, fmt.Sprintf("ingredients::text ILIKE $%d", len(args))) conditions = append(conditions, fmt.Sprintf("ingredients::text ILIKE $%d", len(args)))
} }
q := `select id, name, cuisine, prep_time_minutes, cook_time_minutes, servings, ingredients, instructions, tags, rating, notes, created_at, updated_at from recipes` q := `select id, name, cuisine, prep_time_minutes, cook_time_minutes, servings, ingredients, instructions, tags::text[], rating, notes, created_at, updated_at from recipes`
if len(conditions) > 0 { if len(conditions) > 0 {
q += " where " + strings.Join(conditions, " and ") q += " where " + strings.Join(conditions, " and ")
} }
@@ -85,29 +90,20 @@ func (db *DB) SearchRecipes(ctx context.Context, query, cuisine string, tags []s
func (db *DB) GetRecipe(ctx context.Context, id uuid.UUID) (ext.Recipe, error) { func (db *DB) GetRecipe(ctx context.Context, id uuid.UUID) (ext.Recipe, error) {
row := db.pool.QueryRow(ctx, ` row := db.pool.QueryRow(ctx, `
select id, name, cuisine, prep_time_minutes, cook_time_minutes, servings, ingredients, instructions, tags, rating, notes, created_at, updated_at select id, name, cuisine, prep_time_minutes, cook_time_minutes, servings, ingredients, instructions, tags::text[], rating, notes, created_at, updated_at
from recipes where id = $1 from recipes where id = $1
`, id) `, id)
var r ext.Recipe var model generatedmodels.ModelPublicRecipes
var cuisine, notes *string var tags []string
var ingredientsBytes, instructionsBytes []byte if err := row.Scan(&model.ID, &model.Name, &model.Cuisine, &model.PrepTimeMinutes, &model.CookTimeMinutes, &model.Servings,
if err := row.Scan(&r.ID, &r.Name, &cuisine, &r.PrepTimeMinutes, &r.CookTimeMinutes, &r.Servings, &model.Ingredients, &model.Instructions, &tags, &model.Rating, &model.Notes, &model.CreatedAt, &model.UpdatedAt); err != nil {
&ingredientsBytes, &instructionsBytes, &r.Tags, &r.Rating, &notes, &r.CreatedAt, &r.UpdatedAt); err != nil {
return ext.Recipe{}, fmt.Errorf("get recipe: %w", err) return ext.Recipe{}, fmt.Errorf("get recipe: %w", err)
} }
r.Cuisine = strVal(cuisine) if tags == nil {
r.Notes = strVal(notes) tags = []string{}
if r.Tags == nil {
r.Tags = []string{}
} }
if err := json.Unmarshal(ingredientsBytes, &r.Ingredients); err != nil { return recipeFromModel(model, tags), nil
r.Ingredients = []ext.Ingredient{}
}
if err := json.Unmarshal(instructionsBytes, &r.Instructions); err != nil {
r.Instructions = []string{}
}
return r, nil
} }
func (db *DB) UpdateRecipe(ctx context.Context, id uuid.UUID, r ext.Recipe) (ext.Recipe, error) { func (db *DB) UpdateRecipe(ctx context.Context, id uuid.UUID, r ext.Recipe) (ext.Recipe, error) {
@@ -159,9 +155,12 @@ func (db *DB) CreateMealPlan(ctx context.Context, weekStart time.Time, entries [
Servings: e.Servings, Servings: e.Servings,
Notes: e.Notes, Notes: e.Notes,
} }
if err := row.Scan(&entry.ID, &entry.CreatedAt); err != nil { var model generatedmodels.ModelPublicMealPlans
if err := row.Scan(&model.ID, &model.CreatedAt); err != nil {
return nil, fmt.Errorf("insert meal plan entry: %w", err) return nil, fmt.Errorf("insert meal plan entry: %w", err)
} }
entry.ID = model.ID.UUID()
entry.CreatedAt = model.CreatedAt.Time()
results = append(results, entry) results = append(results, entry)
} }
return results, nil return results, nil
@@ -191,15 +190,12 @@ func (db *DB) GetMealPlan(ctx context.Context, weekStart time.Time) ([]ext.MealP
var entries []ext.MealPlanEntry var entries []ext.MealPlanEntry
for rows.Next() { for rows.Next() {
var e ext.MealPlanEntry var model generatedmodels.ModelPublicMealPlans
var recipeName, customMeal, notes *string var recipeName *string
if err := rows.Scan(&e.ID, &e.WeekStart, &e.DayOfWeek, &e.MealType, &e.RecipeID, &recipeName, &customMeal, &e.Servings, &notes, &e.CreatedAt); err != nil { if err := rows.Scan(&model.ID, &model.WeekStart, &model.DayOfWeek, &model.MealType, &model.RecipeID, &recipeName, &model.CustomMeal, &model.Servings, &model.Notes, &model.CreatedAt); err != nil {
return nil, fmt.Errorf("scan meal plan entry: %w", err) return nil, fmt.Errorf("scan meal plan entry: %w", err)
} }
e.RecipeName = strVal(recipeName) entries = append(entries, mealPlanEntryFromModel(model, strVal(recipeName)))
e.CustomMeal = strVal(customMeal)
e.Notes = strVal(notes)
entries = append(entries, e)
} }
return entries, rows.Err() return entries, rows.Err()
} }
@@ -259,31 +255,26 @@ func (db *DB) GenerateShoppingList(ctx context.Context, weekStart time.Time) (ex
returning id, created_at, updated_at returning id, created_at, updated_at
`, weekStart, itemsJSON) `, weekStart, itemsJSON)
var model generatedmodels.ModelPublicShoppingLists
list := ext.ShoppingList{WeekStart: weekStart, Items: items} list := ext.ShoppingList{WeekStart: weekStart, Items: items}
if err := row.Scan(&list.ID, &list.CreatedAt, &list.UpdatedAt); err != nil { if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.ShoppingList{}, fmt.Errorf("upsert shopping list: %w", err) return ext.ShoppingList{}, fmt.Errorf("upsert shopping list: %w", err)
} }
list.ID = model.ID.UUID()
list.CreatedAt = model.CreatedAt.Time()
list.UpdatedAt = model.UpdatedAt.Time()
return list, nil return list, nil
} }
func scanRecipeRow(rows interface{ Scan(...any) error }) (ext.Recipe, error) { func scanRecipeRow(rows interface{ Scan(...any) error }) (ext.Recipe, error) {
var r ext.Recipe var model generatedmodels.ModelPublicRecipes
var cuisine, notes *string var tags []string
var ingredientsBytes, instructionsBytes []byte if err := rows.Scan(&model.ID, &model.Name, &model.Cuisine, &model.PrepTimeMinutes, &model.CookTimeMinutes, &model.Servings,
if err := rows.Scan(&r.ID, &r.Name, &cuisine, &r.PrepTimeMinutes, &r.CookTimeMinutes, &r.Servings, &model.Ingredients, &model.Instructions, &tags, &model.Rating, &model.Notes, &model.CreatedAt, &model.UpdatedAt); err != nil {
&ingredientsBytes, &instructionsBytes, &r.Tags, &r.Rating, &notes, &r.CreatedAt, &r.UpdatedAt); err != nil {
return ext.Recipe{}, fmt.Errorf("scan recipe: %w", err) return ext.Recipe{}, fmt.Errorf("scan recipe: %w", err)
} }
r.Cuisine = strVal(cuisine) if tags == nil {
r.Notes = strVal(notes) tags = []string{}
if r.Tags == nil {
r.Tags = []string{}
} }
if err := json.Unmarshal(ingredientsBytes, &r.Ingredients); err != nil { return recipeFromModel(model, tags), nil
r.Ingredients = []ext.Ingredient{}
}
if err := json.Unmarshal(instructionsBytes, &r.Instructions); err != nil {
r.Instructions = []string{}
}
return r, nil
} }

View File

@@ -0,0 +1,487 @@
package store
import (
"encoding/json"
"fmt"
"time"
"github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types"
)
func projectFromModel(m generatedmodels.ModelPublicProjects) ext.Project {
return ext.Project{
ID: m.GUID.UUID(),
Name: m.Name.String(),
Description: m.Description.String(),
CreatedAt: m.CreatedAt.Time(),
LastActiveAt: m.LastActiveAt.Time(),
}
}
func thoughtFromModel(m generatedmodels.ModelPublicThoughts) (ext.Thought, error) {
var metadata ext.ThoughtMetadata
if len(m.Metadata) > 0 {
if err := json.Unmarshal(m.Metadata, &metadata); err != nil {
return ext.Thought{}, fmt.Errorf("decode thought metadata: %w", err)
}
}
var projectID *uuid.UUID
if m.ProjectID.Valid {
id := m.ProjectID.UUID()
projectID = &id
}
var archivedAt *time.Time
if m.ArchivedAt.Valid {
t := m.ArchivedAt.Time()
archivedAt = &t
}
return ext.Thought{
ID: m.GUID.UUID(),
Content: m.Content.String(),
Metadata: metadata,
ProjectID: projectID,
ArchivedAt: archivedAt,
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}, nil
}
func storedFileFromModel(m generatedmodels.ModelPublicStoredFiles) ext.StoredFile {
var thoughtID *uuid.UUID
if m.ThoughtID.Valid {
id := m.ThoughtID.UUID()
thoughtID = &id
}
var projectID *uuid.UUID
if m.ProjectID.Valid {
id := m.ProjectID.UUID()
projectID = &id
}
return ext.StoredFile{
ID: m.GUID.UUID(),
ThoughtID: thoughtID,
ProjectID: projectID,
Name: m.Name.String(),
MediaType: m.MediaType.String(),
Kind: m.Kind.String(),
Encoding: m.Encoding.String(),
SizeBytes: m.SizeBytes,
SHA256: m.Sha256.String(),
Content: m.Content,
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
}
func maintenanceTaskFromModel(m generatedmodels.ModelPublicMaintenanceTasks) ext.MaintenanceTask {
var frequencyDays *int
if m.FrequencyDays.Valid {
n := int(m.FrequencyDays.Int64())
frequencyDays = &n
}
var lastCompleted *time.Time
if m.LastCompleted.Valid {
t := m.LastCompleted.Time()
lastCompleted = &t
}
var nextDue *time.Time
if m.NextDue.Valid {
t := m.NextDue.Time()
nextDue = &t
}
return ext.MaintenanceTask{
ID: m.ID.UUID(),
Name: m.Name.String(),
Category: m.Category.String(),
FrequencyDays: frequencyDays,
LastCompleted: lastCompleted,
NextDue: nextDue,
Priority: m.Priority.String(),
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
}
func maintenanceLogFromModel(m generatedmodels.ModelPublicMaintenanceLogs) ext.MaintenanceLog {
var cost *float64
if m.Cost.Valid {
v := m.Cost.Float64()
cost = &v
}
return ext.MaintenanceLog{
ID: m.ID.UUID(),
TaskID: m.TaskID.UUID(),
CompletedAt: m.CompletedAt.Time(),
PerformedBy: m.PerformedBy.String(),
Cost: cost,
Notes: m.Notes.String(),
NextAction: m.NextAction.String(),
}
}
func householdItemFromModel(m generatedmodels.ModelPublicHouseholdItems) ext.HouseholdItem {
details := map[string]any{}
if len(m.Details) > 0 {
if err := json.Unmarshal(m.Details, &details); err != nil {
details = map[string]any{}
}
}
return ext.HouseholdItem{
ID: m.ID.UUID(),
Name: m.Name.String(),
Category: m.Category.String(),
Location: m.Location.String(),
Details: details,
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
}
func householdVendorFromModel(m generatedmodels.ModelPublicHouseholdVendors) ext.HouseholdVendor {
var rating *int
if m.Rating.Valid {
v := int(m.Rating.Int64())
rating = &v
}
var lastUsed *time.Time
if m.LastUsed.Valid {
t := m.LastUsed.Time()
lastUsed = &t
}
return ext.HouseholdVendor{
ID: m.ID.UUID(),
Name: m.Name.String(),
ServiceType: m.ServiceType.String(),
Phone: m.Phone.String(),
Email: m.Email.String(),
Website: m.Website.String(),
Notes: m.Notes.String(),
Rating: rating,
LastUsed: lastUsed,
CreatedAt: m.CreatedAt.Time(),
}
}
func familyMemberFromModel(m generatedmodels.ModelPublicFamilyMembers) ext.FamilyMember {
var birthDate *time.Time
if m.BirthDate.Valid {
t := m.BirthDate.Time()
birthDate = &t
}
return ext.FamilyMember{
ID: m.ID.UUID(),
Name: m.Name.String(),
Relationship: m.Relationship.String(),
BirthDate: birthDate,
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
}
}
func activityFromModel(m generatedmodels.ModelPublicActivities, memberName string) ext.Activity {
var familyMemberID *uuid.UUID
if m.FamilyMemberID.Valid {
id := m.FamilyMemberID.UUID()
familyMemberID = &id
}
var startDate *time.Time
if m.StartDate.Valid {
t := m.StartDate.Time()
startDate = &t
}
var endDate *time.Time
if m.EndDate.Valid {
t := m.EndDate.Time()
endDate = &t
}
return ext.Activity{
ID: m.ID.UUID(),
FamilyMemberID: familyMemberID,
MemberName: memberName,
Title: m.Title.String(),
ActivityType: m.ActivityType.String(),
DayOfWeek: m.DayOfWeek.String(),
StartTime: m.StartTime.String(),
EndTime: m.EndTime.String(),
StartDate: startDate,
EndDate: endDate,
Location: m.Location.String(),
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
}
}
func importantDateFromModel(m generatedmodels.ModelPublicImportantDates, memberName string) ext.ImportantDate {
var familyMemberID *uuid.UUID
if m.FamilyMemberID.Valid {
id := m.FamilyMemberID.UUID()
familyMemberID = &id
}
return ext.ImportantDate{
ID: m.ID.UUID(),
FamilyMemberID: familyMemberID,
MemberName: memberName,
Title: m.Title.String(),
DateValue: m.DateValue.Time(),
RecurringYearly: m.RecurringYearly,
ReminderDaysBefore: int(m.ReminderDaysBefore.Int64()),
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
}
}
func professionalContactFromModel(m generatedmodels.ModelPublicProfessionalContacts, tags []string) ext.ProfessionalContact {
var lastContacted *time.Time
if m.LastContacted.Valid {
t := m.LastContacted.Time()
lastContacted = &t
}
var followUpDate *time.Time
if m.FollowUpDate.Valid {
t := m.FollowUpDate.Time()
followUpDate = &t
}
return ext.ProfessionalContact{
ID: m.ID.UUID(),
Name: m.Name.String(),
Company: m.Company.String(),
Title: m.Title.String(),
Email: m.Email.String(),
Phone: m.Phone.String(),
LinkedInURL: m.LinkedinURL.String(),
HowWeMet: m.HowWeMet.String(),
Tags: tags,
Notes: m.Notes.String(),
LastContacted: lastContacted,
FollowUpDate: followUpDate,
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
}
func contactInteractionFromModel(m generatedmodels.ModelPublicContactInteractions) ext.ContactInteraction {
return ext.ContactInteraction{
ID: m.ID.UUID(),
ContactID: m.ContactID.UUID(),
InteractionType: m.InteractionType.String(),
OccurredAt: m.OccurredAt.Time(),
Summary: m.Summary.String(),
FollowUpNeeded: m.FollowUpNeeded,
FollowUpNotes: m.FollowUpNotes.String(),
CreatedAt: m.CreatedAt.Time(),
}
}
func opportunityFromModel(m generatedmodels.ModelPublicOpportunities) ext.Opportunity {
var contactID *uuid.UUID
if m.ContactID.Valid {
id := m.ContactID.UUID()
contactID = &id
}
var value *float64
if m.Value.Valid {
v := m.Value.Float64()
value = &v
}
var expectedCloseDate *time.Time
if m.ExpectedCloseDate.Valid {
t := m.ExpectedCloseDate.Time()
expectedCloseDate = &t
}
return ext.Opportunity{
ID: m.ID.UUID(),
ContactID: contactID,
Title: m.Title.String(),
Description: m.Description.String(),
Stage: m.Stage.String(),
Value: value,
ExpectedCloseDate: expectedCloseDate,
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
}
func recipeFromModel(m generatedmodels.ModelPublicRecipes, tags []string) ext.Recipe {
var prepTimeMinutes *int
if m.PrepTimeMinutes.Valid {
v := int(m.PrepTimeMinutes.Int64())
prepTimeMinutes = &v
}
var cookTimeMinutes *int
if m.CookTimeMinutes.Valid {
v := int(m.CookTimeMinutes.Int64())
cookTimeMinutes = &v
}
var servings *int
if m.Servings.Valid {
v := int(m.Servings.Int64())
servings = &v
}
var rating *int
if m.Rating.Valid {
v := int(m.Rating.Int64())
rating = &v
}
recipe := ext.Recipe{
ID: m.ID.UUID(),
Name: m.Name.String(),
Cuisine: m.Cuisine.String(),
PrepTimeMinutes: prepTimeMinutes,
CookTimeMinutes: cookTimeMinutes,
Servings: servings,
Tags: tags,
Rating: rating,
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
if err := json.Unmarshal(m.Ingredients, &recipe.Ingredients); err != nil {
recipe.Ingredients = []ext.Ingredient{}
}
if err := json.Unmarshal(m.Instructions, &recipe.Instructions); err != nil {
recipe.Instructions = []string{}
}
return recipe
}
func mealPlanEntryFromModel(m generatedmodels.ModelPublicMealPlans, recipeName string) ext.MealPlanEntry {
var recipeID *uuid.UUID
if m.RecipeID.Valid {
id := m.RecipeID.UUID()
recipeID = &id
}
var servings *int
if m.Servings.Valid {
v := int(m.Servings.Int64())
servings = &v
}
return ext.MealPlanEntry{
ID: m.ID.UUID(),
WeekStart: m.WeekStart.Time(),
DayOfWeek: m.DayOfWeek.String(),
MealType: m.MealType.String(),
RecipeID: recipeID,
RecipeName: recipeName,
CustomMeal: m.CustomMeal.String(),
Servings: servings,
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
}
}
func shoppingListFromModel(m generatedmodels.ModelPublicShoppingLists) ext.ShoppingList {
list := ext.ShoppingList{
ID: m.ID.UUID(),
WeekStart: m.WeekStart.Time(),
Notes: m.Notes.String(),
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
if err := json.Unmarshal(m.Items, &list.Items); err != nil {
list.Items = []ext.ShoppingItem{}
}
return list
}
func learningFromModel(m generatedmodels.ModelPublicLearnings, tags []string) ext.Learning {
var projectID *uuid.UUID
if m.ProjectID.Valid {
id := m.ProjectID.UUID()
projectID = &id
}
var relatedThoughtID *uuid.UUID
if m.RelatedThoughtID.Valid {
id := m.RelatedThoughtID.UUID()
relatedThoughtID = &id
}
var relatedSkillID *uuid.UUID
if m.RelatedSkillID.Valid {
id := m.RelatedSkillID.UUID()
relatedSkillID = &id
}
var duplicateOfLearningID *uuid.UUID
if m.DuplicateOfLearningID.Valid {
id := m.DuplicateOfLearningID.UUID()
duplicateOfLearningID = &id
}
var supersedesLearningID *uuid.UUID
if m.SupersedesLearningID.Valid {
id := m.SupersedesLearningID.UUID()
supersedesLearningID = &id
}
var reviewedBy *string
if m.ReviewedBy.Valid {
value := m.ReviewedBy.String()
reviewedBy = &value
}
var reviewedAt *time.Time
if m.ReviewedAt.Valid {
t := m.ReviewedAt.Time()
reviewedAt = &t
}
return ext.Learning{
ID: m.ID.UUID(),
Summary: m.Summary.String(),
Details: m.Details.String(),
Category: m.Category.String(),
Area: m.Area.String(),
Status: ext.LearningStatus(m.Status.String()),
Priority: ext.LearningPriority(m.Priority.String()),
Confidence: ext.LearningEvidenceLevel(m.Confidence.String()),
ActionRequired: m.ActionRequired,
SourceType: m.SourceType.String(),
SourceRef: m.SourceRef.String(),
ProjectID: projectID,
RelatedThoughtID: relatedThoughtID,
RelatedSkillID: relatedSkillID,
ReviewedBy: reviewedBy,
ReviewedAt: reviewedAt,
DuplicateOfLearningID: duplicateOfLearningID,
SupersedesLearningID: supersedesLearningID,
Tags: tags,
CreatedAt: m.CreatedAt.Time(),
UpdatedAt: m.UpdatedAt.Time(),
}
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
thoughttypes "git.warky.dev/wdevs/amcs/internal/types" thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -18,11 +19,11 @@ func (db *DB) CreateProject(ctx context.Context, name, description string) (thou
returning guid, name, description, created_at, last_active_at returning guid, name, description, created_at, last_active_at
`, name, description) `, name, description)
var project thoughttypes.Project var model generatedmodels.ModelPublicProjects
if err := row.Scan(&project.ID, &project.Name, &project.Description, &project.CreatedAt, &project.LastActiveAt); err != nil { if err := row.Scan(&model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt); err != nil {
return thoughttypes.Project{}, fmt.Errorf("create project: %w", err) return thoughttypes.Project{}, fmt.Errorf("create project: %w", err)
} }
return project, nil return projectFromModel(model), nil
} }
func (db *DB) GetProject(ctx context.Context, nameOrID string) (thoughttypes.Project, error) { func (db *DB) GetProject(ctx context.Context, nameOrID string) (thoughttypes.Project, error) {
@@ -62,14 +63,14 @@ func (db *DB) getProjectByName(ctx context.Context, name string) (thoughttypes.P
} }
func scanProject(row pgx.Row) (thoughttypes.Project, error) { func scanProject(row pgx.Row) (thoughttypes.Project, error) {
var project thoughttypes.Project var model generatedmodels.ModelPublicProjects
if err := row.Scan(&project.ID, &project.Name, &project.Description, &project.CreatedAt, &project.LastActiveAt); err != nil { if err := row.Scan(&model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt); err != nil {
if err == pgx.ErrNoRows { if err == pgx.ErrNoRows {
return thoughttypes.Project{}, err return thoughttypes.Project{}, err
} }
return thoughttypes.Project{}, fmt.Errorf("get project: %w", err) return thoughttypes.Project{}, fmt.Errorf("get project: %w", err)
} }
return project, nil return projectFromModel(model), nil
} }
func (db *DB) ListProjects(ctx context.Context) ([]thoughttypes.ProjectSummary, error) { func (db *DB) ListProjects(ctx context.Context) ([]thoughttypes.ProjectSummary, error) {
@@ -87,11 +88,15 @@ func (db *DB) ListProjects(ctx context.Context) ([]thoughttypes.ProjectSummary,
projects := make([]thoughttypes.ProjectSummary, 0) projects := make([]thoughttypes.ProjectSummary, 0)
for rows.Next() { for rows.Next() {
var project thoughttypes.ProjectSummary var model generatedmodels.ModelPublicProjects
if err := rows.Scan(&project.ID, &project.Name, &project.Description, &project.CreatedAt, &project.LastActiveAt, &project.ThoughtCount); err != nil { var thoughtCount int
if err := rows.Scan(&model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt, &thoughtCount); err != nil {
return nil, fmt.Errorf("scan project summary: %w", err) return nil, fmt.Errorf("scan project summary: %w", err)
} }
projects = append(projects, project) projects = append(projects, thoughttypes.ProjectSummary{
Project: projectFromModel(model),
ThoughtCount: thoughtCount,
})
} }
if err := rows.Err(); err != nil { if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate projects: %w", err) return nil, fmt.Errorf("iterate projects: %w", err)

View File

@@ -7,6 +7,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types" ext "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -23,9 +24,13 @@ func (db *DB) AddSkill(ctx context.Context, skill ext.AgentSkill) (ext.AgentSkil
`, skill.Name, skill.Description, skill.Content, skill.Tags) `, skill.Name, skill.Description, skill.Content, skill.Tags)
created := skill created := skill
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicAgentSkills
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.AgentSkill{}, fmt.Errorf("insert agent skill: %w", err) return ext.AgentSkill{}, fmt.Errorf("insert agent skill: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -41,7 +46,7 @@ func (db *DB) RemoveSkill(ctx context.Context, id uuid.UUID) error {
} }
func (db *DB) ListSkills(ctx context.Context, tag string) ([]ext.AgentSkill, error) { func (db *DB) ListSkills(ctx context.Context, tag string) ([]ext.AgentSkill, error) {
q := `select id, name, description, content, tags, created_at, updated_at from agent_skills` q := `select id, name, description, content, tags::text[], created_at, updated_at from agent_skills`
args := []any{} args := []any{}
if t := strings.TrimSpace(tag); t != "" { if t := strings.TrimSpace(tag); t != "" {
args = append(args, t) args = append(args, t)
@@ -57,12 +62,20 @@ func (db *DB) ListSkills(ctx context.Context, tag string) ([]ext.AgentSkill, err
var skills []ext.AgentSkill var skills []ext.AgentSkill
for rows.Next() { for rows.Next() {
var s ext.AgentSkill var model generatedmodels.ModelPublicAgentSkills
var desc *string var tags []string
if err := rows.Scan(&s.ID, &s.Name, &desc, &s.Content, &s.Tags, &s.CreatedAt, &s.UpdatedAt); err != nil { if err := rows.Scan(&model.ID, &model.Name, &model.Description, &model.Content, &tags, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan agent skill: %w", err) return nil, fmt.Errorf("scan agent skill: %w", err)
} }
s.Description = strVal(desc) s := ext.AgentSkill{
ID: model.ID.UUID(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
Tags: tags,
CreatedAt: model.CreatedAt.Time(),
UpdatedAt: model.UpdatedAt.Time(),
}
if s.Tags == nil { if s.Tags == nil {
s.Tags = []string{} s.Tags = []string{}
} }
@@ -73,16 +86,24 @@ func (db *DB) ListSkills(ctx context.Context, tag string) ([]ext.AgentSkill, err
func (db *DB) GetSkill(ctx context.Context, id uuid.UUID) (ext.AgentSkill, error) { func (db *DB) GetSkill(ctx context.Context, id uuid.UUID) (ext.AgentSkill, error) {
row := db.pool.QueryRow(ctx, ` row := db.pool.QueryRow(ctx, `
select id, name, description, content, tags, created_at, updated_at select id, name, description, content, tags::text[], created_at, updated_at
from agent_skills where id = $1 from agent_skills where id = $1
`, id) `, id)
var s ext.AgentSkill var model generatedmodels.ModelPublicAgentSkills
var desc *string var tags []string
if err := row.Scan(&s.ID, &s.Name, &desc, &s.Content, &s.Tags, &s.CreatedAt, &s.UpdatedAt); err != nil { if err := row.Scan(&model.ID, &model.Name, &model.Description, &model.Content, &tags, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.AgentSkill{}, fmt.Errorf("get agent skill: %w", err) return ext.AgentSkill{}, fmt.Errorf("get agent skill: %w", err)
} }
s.Description = strVal(desc) s := ext.AgentSkill{
ID: model.ID.UUID(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
Tags: tags,
CreatedAt: model.CreatedAt.Time(),
UpdatedAt: model.UpdatedAt.Time(),
}
if s.Tags == nil { if s.Tags == nil {
s.Tags = []string{} s.Tags = []string{}
} }
@@ -105,9 +126,13 @@ func (db *DB) AddGuardrail(ctx context.Context, g ext.AgentGuardrail) (ext.Agent
`, g.Name, g.Description, g.Content, g.Severity, g.Tags) `, g.Name, g.Description, g.Content, g.Severity, g.Tags)
created := g created := g
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil { var model generatedmodels.ModelPublicAgentGuardrails
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.AgentGuardrail{}, fmt.Errorf("insert agent guardrail: %w", err) return ext.AgentGuardrail{}, fmt.Errorf("insert agent guardrail: %w", err)
} }
created.ID = model.ID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil return created, nil
} }
@@ -135,7 +160,7 @@ func (db *DB) ListGuardrails(ctx context.Context, tag, severity string) ([]ext.A
conditions = append(conditions, fmt.Sprintf("severity = $%d", len(args))) conditions = append(conditions, fmt.Sprintf("severity = $%d", len(args)))
} }
q := `select id, name, description, content, severity, tags, created_at, updated_at from agent_guardrails` q := `select id, name, description, content, severity, tags::text[], created_at, updated_at from agent_guardrails`
if len(conditions) > 0 { if len(conditions) > 0 {
q += " where " + strings.Join(conditions, " and ") q += " where " + strings.Join(conditions, " and ")
} }
@@ -149,12 +174,21 @@ func (db *DB) ListGuardrails(ctx context.Context, tag, severity string) ([]ext.A
var guardrails []ext.AgentGuardrail var guardrails []ext.AgentGuardrail
for rows.Next() { for rows.Next() {
var g ext.AgentGuardrail var model generatedmodels.ModelPublicAgentGuardrails
var desc *string var tags []string
if err := rows.Scan(&g.ID, &g.Name, &desc, &g.Content, &g.Severity, &g.Tags, &g.CreatedAt, &g.UpdatedAt); err != nil { if err := rows.Scan(&model.ID, &model.Name, &model.Description, &model.Content, &model.Severity, &tags, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan agent guardrail: %w", err) return nil, fmt.Errorf("scan agent guardrail: %w", err)
} }
g.Description = strVal(desc) g := ext.AgentGuardrail{
ID: model.ID.UUID(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
Severity: model.Severity.String(),
Tags: tags,
CreatedAt: model.CreatedAt.Time(),
UpdatedAt: model.UpdatedAt.Time(),
}
if g.Tags == nil { if g.Tags == nil {
g.Tags = []string{} g.Tags = []string{}
} }
@@ -165,16 +199,25 @@ func (db *DB) ListGuardrails(ctx context.Context, tag, severity string) ([]ext.A
func (db *DB) GetGuardrail(ctx context.Context, id uuid.UUID) (ext.AgentGuardrail, error) { func (db *DB) GetGuardrail(ctx context.Context, id uuid.UUID) (ext.AgentGuardrail, error) {
row := db.pool.QueryRow(ctx, ` row := db.pool.QueryRow(ctx, `
select id, name, description, content, severity, tags, created_at, updated_at select id, name, description, content, severity, tags::text[], created_at, updated_at
from agent_guardrails where id = $1 from agent_guardrails where id = $1
`, id) `, id)
var g ext.AgentGuardrail var model generatedmodels.ModelPublicAgentGuardrails
var desc *string var tags []string
if err := row.Scan(&g.ID, &g.Name, &desc, &g.Content, &g.Severity, &g.Tags, &g.CreatedAt, &g.UpdatedAt); err != nil { if err := row.Scan(&model.ID, &model.Name, &model.Description, &model.Content, &model.Severity, &tags, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.AgentGuardrail{}, fmt.Errorf("get agent guardrail: %w", err) return ext.AgentGuardrail{}, fmt.Errorf("get agent guardrail: %w", err)
} }
g.Description = strVal(desc) g := ext.AgentGuardrail{
ID: model.ID.UUID(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
Severity: model.Severity.String(),
Tags: tags,
CreatedAt: model.CreatedAt.Time(),
UpdatedAt: model.UpdatedAt.Time(),
}
if g.Tags == nil { if g.Tags == nil {
g.Tags = []string{} g.Tags = []string{}
} }
@@ -210,7 +253,7 @@ func (db *DB) RemoveProjectSkill(ctx context.Context, projectID, skillID uuid.UU
func (db *DB) ListProjectSkills(ctx context.Context, projectID uuid.UUID) ([]ext.AgentSkill, error) { func (db *DB) ListProjectSkills(ctx context.Context, projectID uuid.UUID) ([]ext.AgentSkill, error) {
rows, err := db.pool.Query(ctx, ` rows, err := db.pool.Query(ctx, `
select s.id, s.name, s.description, s.content, s.tags, s.created_at, s.updated_at select s.id, s.name, s.description, s.content, s.tags::text[], s.created_at, s.updated_at
from agent_skills s from agent_skills s
join project_skills ps on ps.skill_id = s.id join project_skills ps on ps.skill_id = s.id
where ps.project_id = $1 where ps.project_id = $1
@@ -223,12 +266,20 @@ func (db *DB) ListProjectSkills(ctx context.Context, projectID uuid.UUID) ([]ext
var skills []ext.AgentSkill var skills []ext.AgentSkill
for rows.Next() { for rows.Next() {
var s ext.AgentSkill var model generatedmodels.ModelPublicAgentSkills
var desc *string var tags []string
if err := rows.Scan(&s.ID, &s.Name, &desc, &s.Content, &s.Tags, &s.CreatedAt, &s.UpdatedAt); err != nil { if err := rows.Scan(&model.ID, &model.Name, &model.Description, &model.Content, &tags, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan project skill: %w", err) return nil, fmt.Errorf("scan project skill: %w", err)
} }
s.Description = strVal(desc) s := ext.AgentSkill{
ID: model.ID.UUID(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
Tags: tags,
CreatedAt: model.CreatedAt.Time(),
UpdatedAt: model.UpdatedAt.Time(),
}
if s.Tags == nil { if s.Tags == nil {
s.Tags = []string{} s.Tags = []string{}
} }
@@ -266,7 +317,7 @@ func (db *DB) RemoveProjectGuardrail(ctx context.Context, projectID, guardrailID
func (db *DB) ListProjectGuardrails(ctx context.Context, projectID uuid.UUID) ([]ext.AgentGuardrail, error) { func (db *DB) ListProjectGuardrails(ctx context.Context, projectID uuid.UUID) ([]ext.AgentGuardrail, error) {
rows, err := db.pool.Query(ctx, ` rows, err := db.pool.Query(ctx, `
select g.id, g.name, g.description, g.content, g.severity, g.tags, g.created_at, g.updated_at select g.id, g.name, g.description, g.content, g.severity, g.tags::text[], g.created_at, g.updated_at
from agent_guardrails g from agent_guardrails g
join project_guardrails pg on pg.guardrail_id = g.id join project_guardrails pg on pg.guardrail_id = g.id
where pg.project_id = $1 where pg.project_id = $1
@@ -279,12 +330,21 @@ func (db *DB) ListProjectGuardrails(ctx context.Context, projectID uuid.UUID) ([
var guardrails []ext.AgentGuardrail var guardrails []ext.AgentGuardrail
for rows.Next() { for rows.Next() {
var g ext.AgentGuardrail var model generatedmodels.ModelPublicAgentGuardrails
var desc *string var tags []string
if err := rows.Scan(&g.ID, &g.Name, &desc, &g.Content, &g.Severity, &g.Tags, &g.CreatedAt, &g.UpdatedAt); err != nil { if err := rows.Scan(&model.ID, &model.Name, &model.Description, &model.Content, &model.Severity, &tags, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan project guardrail: %w", err) return nil, fmt.Errorf("scan project guardrail: %w", err)
} }
g.Description = strVal(desc) g := ext.AgentGuardrail{
ID: model.ID.UUID(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
Severity: model.Severity.String(),
Tags: tags,
CreatedAt: model.CreatedAt.Time(),
UpdatedAt: model.UpdatedAt.Time(),
}
if g.Tags == nil { if g.Tags == nil {
g.Tags = []string{} g.Tags = []string{}
} }

View File

@@ -12,6 +12,7 @@ import (
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/pgvector/pgvector-go" "github.com/pgvector/pgvector-go"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
thoughttypes "git.warky.dev/wdevs/amcs/internal/types" thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
) )
@@ -149,13 +150,13 @@ func (db *DB) ListThoughts(ctx context.Context, filter thoughttypes.ListFilter)
thoughts := make([]thoughttypes.Thought, 0, filter.Limit) thoughts := make([]thoughttypes.Thought, 0, filter.Limit)
for rows.Next() { for rows.Next() {
var thought thoughttypes.Thought var model generatedmodels.ModelPublicThoughts
var metadataBytes []byte if err := rows.Scan(&model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := rows.Scan(&thought.ID, &thought.Content, &metadataBytes, &thought.ProjectID, &thought.ArchivedAt, &thought.CreatedAt, &thought.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan listed thought: %w", err) return nil, fmt.Errorf("scan listed thought: %w", err)
} }
if err := json.Unmarshal(metadataBytes, &thought.Metadata); err != nil { thought, err := thoughtFromModel(model)
return nil, fmt.Errorf("decode listed metadata: %w", err) if err != nil {
return nil, fmt.Errorf("map listed thought: %w", err)
} }
thoughts = append(thoughts, thought) thoughts = append(thoughts, thought)
} }
@@ -222,17 +223,17 @@ func (db *DB) GetThought(ctx context.Context, id uuid.UUID) (thoughttypes.Though
where guid = $1 where guid = $1
`, id) `, id)
var thought thoughttypes.Thought var model generatedmodels.ModelPublicThoughts
var metadataBytes []byte if err := row.Scan(&model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := row.Scan(&thought.ID, &thought.Content, &metadataBytes, &thought.ProjectID, &thought.ArchivedAt, &thought.CreatedAt, &thought.UpdatedAt); err != nil {
if err == pgx.ErrNoRows { if err == pgx.ErrNoRows {
return thoughttypes.Thought{}, err return thoughttypes.Thought{}, err
} }
return thoughttypes.Thought{}, fmt.Errorf("get thought: %w", err) return thoughttypes.Thought{}, fmt.Errorf("get thought: %w", err)
} }
if err := json.Unmarshal(metadataBytes, &thought.Metadata); err != nil { thought, err := thoughtFromModel(model)
return thoughttypes.Thought{}, fmt.Errorf("decode thought metadata: %w", err) if err != nil {
return thoughttypes.Thought{}, fmt.Errorf("map thought: %w", err)
} }
return thought, nil return thought, nil

View File

@@ -3,6 +3,8 @@ package store
import ( import (
"context" "context"
"fmt" "fmt"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
) )
func (db *DB) UpsertToolAnnotation(ctx context.Context, toolName, notes string) error { func (db *DB) UpsertToolAnnotation(ctx context.Context, toolName, notes string) error {
@@ -28,11 +30,11 @@ func (db *DB) GetToolAnnotations(ctx context.Context) (map[string]string, error)
annotations := make(map[string]string) annotations := make(map[string]string)
for rows.Next() { for rows.Next() {
var toolName, notes string var model generatedmodels.ModelPublicToolAnnotations
if err := rows.Scan(&toolName, &notes); err != nil { if err := rows.Scan(&model.ToolName, &model.Notes); err != nil {
return nil, fmt.Errorf("scan tool annotation: %w", err) return nil, fmt.Errorf("scan tool annotation: %w", err)
} }
annotations[toolName] = notes annotations[model.ToolName.String()] = model.Notes.String()
} }
return annotations, rows.Err() return annotations, rows.Err()
} }

View File

@@ -14,6 +14,19 @@ This uses `relspec` to convert the DBML files into PostgreSQL SQL and writes the
- `migrations/020_generated_schema.sql` - `migrations/020_generated_schema.sql`
## Generate ResolveSpec models
Run:
```bash
make generate-models
```
This uses `relspec` to convert `schema/*.dbml` into Bun/ResolveSpec-compatible
Go models in:
- `internal/generatedmodels/`
## Check schema drift ## Check schema drift
Run: Run:
@@ -29,7 +42,8 @@ If the generated output differs, the command fails so CI can catch schema drift.
1. Update the DBML files in `schema/` 1. Update the DBML files in `schema/`
2. Run `make generate-migrations` 2. Run `make generate-migrations`
3. Review the generated SQL 3. Run `make generate-models`
4. Commit both the DBML changes and the generated migration 4. Review generated SQL and generated models
5. Commit DBML changes and generated outputs
Existing handwritten migrations stay in place. Going forward, update the DBML first and regenerate the SQL from there. Existing handwritten migrations stay in place. Going forward, update the DBML first and regenerate the SQL from there.

View File

@@ -19,6 +19,7 @@ Table projects {
} }
Table thought_links { Table thought_links {
id serial [pk]
from_id bigint [not null, ref: > thoughts.id] from_id bigint [not null, ref: > thoughts.id]
to_id bigint [not null, ref: > thoughts.id] to_id bigint [not null, ref: > thoughts.id]
relation text [not null] relation text [not null]

View File

@@ -20,6 +20,7 @@ Table agent_guardrails {
} }
Table project_skills { Table project_skills {
id serial [pk]
project_id uuid [not null, ref: > projects.guid] project_id uuid [not null, ref: > projects.guid]
skill_id uuid [not null, ref: > agent_skills.id] skill_id uuid [not null, ref: > agent_skills.id]
created_at timestamptz [not null, default: `now()`] created_at timestamptz [not null, default: `now()`]
@@ -31,6 +32,7 @@ Table project_skills {
} }
Table project_guardrails { Table project_guardrails {
id serial [pk]
project_id uuid [not null, ref: > projects.guid] project_id uuid [not null, ref: > projects.guid]
guardrail_id uuid [not null, ref: > agent_guardrails.id] guardrail_id uuid [not null, ref: > agent_guardrails.id]
created_at timestamptz [not null, default: `now()`] created_at timestamptz [not null, default: `now()`]

56
scripts/generate-models.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
out_dir="${repo_root}/internal/generatedmodels"
resolve_relspec() {
if [[ -n "${RELSPEC:-}" ]]; then
printf '%s' "${RELSPEC}"
return
fi
if command -v relspec >/dev/null 2>&1; then
printf '%s' "relspec"
return
fi
if [[ -x "${HOME}/go/bin/relspec" ]]; then
printf '%s' "${HOME}/go/bin/relspec"
return
fi
echo "relspec not found; install git.warky.dev/wdevs/relspecgo/cmd/relspec@latest" >&2
exit 1
}
relspec_bin="$(resolve_relspec)"
cd "${repo_root}"
mapfile -t schema_files < <(find schema -maxdepth 1 -type f -name '*.dbml' | sort)
if [[ "${#schema_files[@]}" -eq 0 ]]; then
echo "No DBML schema files found in schema/" >&2
exit 1
fi
schema_list="$(IFS=,; echo "${schema_files[*]}")"
rm -rf "${out_dir}"
mkdir -p "${out_dir}"
"${relspec_bin}" convert \
--from dbml \
--from-list "${schema_list}" \
--to bun \
--to-path "${out_dir}" \
--package generatedmodels
# relspec currently emits a few files with unused fmt imports; strip only when fmt is unused.
for file in "${out_dir}"/*.go; do
sed -i 's/fmt.Sprintf("%d", m.ID)/fmt.Sprintf("%v", m.ID)/g' "${file}"
if ! grep -q 'fmt\.' "${file}"; then
sed -i '/^[[:space:]]*"fmt"$/d' "${file}"
fi
done
gofmt -w "${out_dir}"/*.go

View File

@@ -26,10 +26,18 @@
GlobalStateStore.setState({ GlobalStateStore.setState({
onFetchSession: async (state) => { onFetchSession: async (state) => {
const token = state.session.authToken; const token = state.session?.authToken;
if (!token) return null; if (!token) return {};
const res = await fetch('/api/admin/stats', { const res = await fetch('/api/rs/public/projects', {
headers: { Authorization: `Bearer ${token}` } method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
},
body: JSON.stringify({
operation: 'read',
options: { limit: 1 }
})
}); });
if (!res.ok) return { session: { loggedIn: false } }; if (!res.ok) return { session: { loggedIn: false } };
return { session: { loggedIn: true, authToken: token } }; return { session: { loggedIn: true, authToken: token } };
@@ -47,14 +55,7 @@
try { try {
const token = await loginWithCredentials(username, password); const token = await loginWithCredentials(username, password);
const state = GlobalStateStore.getState(); await GlobalStateStore.getState().login(token, { username });
state.setSession({
authToken: token,
loggedIn: true,
validated: true,
expiryDate: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
});
state.setUser({ username });
authMessage = 'Login successful.'; authMessage = 'Login successful.';
await loadStatus(); await loadStatus();
} catch (err) { } catch (err) {
@@ -128,7 +129,9 @@
return; return;
} }
if (isLoggedIn.current) { await GlobalStateStore.getState().fetchData();
if (GlobalStateStore.getState().isLoggedIn()) {
await loadStatus(); await loadStatus();
} }
}); });

View File

@@ -5,6 +5,49 @@ function authHeaders(): HeadersInit {
return token ? { Authorization: `Bearer ${token}` } : {}; return token ? { Authorization: `Bearer ${token}` } : {};
} }
type ResolveSpecResponse<T> = {
success: boolean;
data: T;
metadata?: unknown;
error?: { code: string; message: string; detail?: string };
};
type ResolveSpecFilter = {
column: string;
operator: string;
value?: unknown;
};
function normalizeTags(value: unknown): string[] {
if (Array.isArray(value)) {
return value.map((tag) => String(tag).trim()).filter(Boolean);
}
if (typeof value !== 'string') {
return [];
}
const trimmed = value.trim();
if (!trimmed) return [];
// Handle Postgres text[] wire shape: "{tag1,tag2}".
if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
return trimmed
.slice(1, -1)
.split(',')
.map((tag) => tag.trim().replace(/^"(.*)"$/, '$1'))
.filter(Boolean);
}
if (trimmed.includes(',')) {
return trimmed
.split(',')
.map((tag) => tag.trim())
.filter(Boolean);
}
return [trimmed];
}
async function get<T>(path: string): Promise<T> { async function get<T>(path: string): Promise<T> {
const res = await fetch(path, { headers: authHeaders() }); const res = await fetch(path, { headers: authHeaders() });
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
@@ -27,55 +70,193 @@ async function del(path: string): Promise<void> {
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
} }
async function rsCall<T>(
path: string,
operation: 'read' | 'create' | 'update' | 'delete',
payload?: { data?: unknown; options?: unknown }
): Promise<T> {
const res = await fetch(path, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify({
operation,
...(payload?.data !== undefined ? { data: payload.data } : {}),
...(payload?.options !== undefined ? { options: payload.options } : {})
})
});
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
const body = (await res.json()) as ResolveSpecResponse<T>;
if (!body.success) {
throw new Error(body.error?.message ?? 'ResolveSpec request failed');
}
return body.data;
}
function rsReadMany<T>(
entity: string,
options?: { filters?: ResolveSpecFilter[]; limit?: number; sort?: { column: string; direction: 'asc' | 'desc' }[] }
): Promise<T[]> {
return rsCall<T[]>(`/api/rs/public/${entity}`, 'read', {
options: {
...(options?.filters?.length ? { filters: options.filters } : {}),
...(options?.sort?.length ? { sort: options.sort } : {}),
...(options?.limit ? { limit: options.limit } : {})
}
});
}
export const api = { export const api = {
projects: { projects: {
list: () => get<import('./types').ProjectSummary[]>('/api/admin/projects'), list: async () => {
type ProjectRow = {
guid: string;
name: string;
description: string | null;
created_at: string;
last_active_at: string;
thought_count?: number;
};
const projects = await rsCall<ProjectRow[]>('/api/rs/public/projects', 'read', {
options: {
columns: ['guid', 'name', 'description', 'created_at', 'last_active_at'],
computedColumns: [
{
name: 'thought_count',
expression: 'COALESCE((SELECT COUNT(*) FROM public.thoughts t WHERE t.project_id = projects.guid), 0)'
}
],
sort: [{ column: 'created_at', direction: 'desc' }],
limit: 500
}
});
return projects.map((project) => ({
id: project.guid,
name: project.name,
description: project.description ?? '',
created_at: project.created_at,
last_active_at: project.last_active_at,
thought_count: project.thought_count ?? 0
}));
},
create: (name: string, description: string) => create: (name: string, description: string) =>
post<import('./types').Project>('/api/admin/projects', { name, description }) rsCall<import('./types').Project>('/api/rs/public/projects', 'create', {
data: { name, description }
})
}, },
thoughts: { thoughts: {
list: (params: { q?: string; project_id?: string; limit?: number; include_archived?: boolean }) => { list: (params: { q?: string; project_id?: string; limit?: number; include_archived?: boolean }) => {
const qs = new URLSearchParams(); const filters: ResolveSpecFilter[] = [];
if (params.q) qs.set('q', params.q); if (params.q) {
if (params.project_id) qs.set('project_id', params.project_id); filters.push({ column: 'content', operator: 'ilike', value: `%${params.q}%` });
if (params.limit) qs.set('limit', String(params.limit)); }
if (params.include_archived) qs.set('include_archived', 'true'); if (params.project_id) {
return get<(import('./types').Thought | import('./types').SearchResult)[]>( filters.push({ column: 'project_id', operator: 'eq', value: params.project_id });
`/api/admin/thoughts${qs.size ? '?' + qs : ''}` }
); if (!params.include_archived) {
filters.push({ column: 'archived_at', operator: 'empty' });
}
return rsReadMany<import('./types').Thought>('thoughts', {
filters,
limit: params.limit ?? 100,
sort: [{ column: 'created_at', direction: 'desc' }]
});
}, },
get: (id: string) => get<import('./types').Thought>(`/api/admin/thoughts/${id}`), get: (id: string) => rsCall<import('./types').Thought>(`/api/rs/public/thoughts/${id}`, 'read'),
delete: (id: string) => del(`/api/admin/thoughts/${id}`), delete: (id: string) => rsCall<void>(`/api/rs/public/thoughts/${id}`, 'delete'),
archive: (id: string) => post<void>(`/api/admin/thoughts/${id}/archive`, {}) archive: (id: string) =>
rsCall<void>(`/api/rs/public/thoughts/${id}`, 'update', {
data: { archived_at: new Date().toISOString() }
})
}, },
skills: { skills: {
list: (tag?: string) => { list: async (tag?: string) => {
const qs = tag ? `?tag=${encodeURIComponent(tag)}` : ''; const rows = await rsReadMany<Omit<import('./types').AgentSkill, 'tags'> & { tags?: unknown }>('agent_skills', {
return get<import('./types').AgentSkill[]>(`/api/admin/skills${qs}`); filters: tag ? [{ column: 'tags', operator: 'contains', value: tag }] : undefined,
limit: 500,
sort: [{ column: 'created_at', direction: 'desc' }]
});
return rows.map((row) => ({ ...row, tags: normalizeTags(row.tags) }));
}, },
delete: (id: string) => del(`/api/admin/skills/${id}`) delete: (id: string) => rsCall<void>(`/api/rs/public/agent_skills/${id}`, 'delete')
}, },
guardrails: { guardrails: {
list: (params?: { tag?: string; severity?: string }) => { list: async (params?: { tag?: string; severity?: string }) => {
const qs = new URLSearchParams(); const filters: ResolveSpecFilter[] = [];
if (params?.tag) qs.set('tag', params.tag); if (params?.tag) filters.push({ column: 'tags', operator: 'contains', value: params.tag });
if (params?.severity) qs.set('severity', params.severity); if (params?.severity) filters.push({ column: 'severity', operator: 'eq', value: params.severity });
return get<import('./types').AgentGuardrail[]>(
`/api/admin/guardrails${qs.size ? '?' + qs : ''}` const rows = await rsReadMany<Omit<import('./types').AgentGuardrail, 'tags'> & { tags?: unknown }>('agent_guardrails', {
); filters,
limit: 500,
sort: [{ column: 'created_at', direction: 'desc' }]
});
return rows.map((row) => ({ ...row, tags: normalizeTags(row.tags) }));
}, },
delete: (id: string) => del(`/api/admin/guardrails/${id}`) delete: (id: string) => rsCall<void>(`/api/rs/public/agent_guardrails/${id}`, 'delete')
}, },
files: { files: {
list: (params?: { project_id?: string; thought_id?: string; kind?: string }) => { list: (params?: { project_id?: string; thought_id?: string; kind?: string }) => {
const qs = new URLSearchParams(); const filters: ResolveSpecFilter[] = [];
if (params?.project_id) qs.set('project_id', params.project_id); if (params?.project_id) filters.push({ column: 'project_id', operator: 'eq', value: params.project_id });
if (params?.thought_id) qs.set('thought_id', params.thought_id); if (params?.thought_id) filters.push({ column: 'thought_id', operator: 'eq', value: params.thought_id });
if (params?.kind) qs.set('kind', params.kind); if (params?.kind) filters.push({ column: 'kind', operator: 'eq', value: params.kind });
return get<import('./types').StoredFile[]>( return rsReadMany<import('./types').StoredFile>('stored_files', {
`/api/admin/files${qs.size ? '?' + qs : ''}` filters,
); limit: 500,
sort: [{ column: 'created_at', direction: 'desc' }]
});
} }
}, },
stats: () => get<import('./types').ThoughtStats>('/api/admin/stats') stats: async () => {
type StatsThoughtRow = {
metadata?: {
type?: string;
topics?: string[];
people?: string[];
};
};
const thoughts = await rsReadMany<StatsThoughtRow>('thoughts', {
limit: 5000,
sort: [{ column: 'created_at', direction: 'desc' }]
});
const typeCounts: Record<string, number> = {};
const topicCounts: Record<string, number> = {};
const peopleCounts: Record<string, number> = {};
for (const thought of thoughts) {
const type = thought.metadata?.type?.trim() || 'unknown';
typeCounts[type] = (typeCounts[type] ?? 0) + 1;
for (const topic of thought.metadata?.topics ?? []) {
const key = topic.trim();
if (!key) continue;
topicCounts[key] = (topicCounts[key] ?? 0) + 1;
}
for (const person of thought.metadata?.people ?? []) {
const key = person.trim();
if (!key) continue;
peopleCounts[key] = (peopleCounts[key] ?? 0) + 1;
}
}
const topEntries = (map: Record<string, number>) =>
Object.entries(map)
.sort((a, b) => b[1] - a[1])
.slice(0, 10)
.map(([key, count]) => ({ key, count }));
const stats: import('./types').ThoughtStats = {
total_count: thoughts.length,
type_counts: typeCounts,
top_topics: topEntries(topicCounts),
top_people: topEntries(peopleCounts)
};
return stats;
}
}; };