Compare commits
2 Commits
24c4127024
...
1aecb4424c
| Author | SHA1 | Date | |
|---|---|---|---|
|
1aecb4424c
|
|||
|
deaa14f9f6
|
@@ -8,10 +8,10 @@ tmp_dir = "tmp"
|
|||||||
[build]
|
[build]
|
||||||
args_bin = []
|
args_bin = []
|
||||||
bin = "./tmp/main"
|
bin = "./tmp/main"
|
||||||
cmd = "go build -o ./tmp/main cmd/api/main.go"
|
cmd = "sqlc generate && go build -o ./tmp/main cmd/api/main.go"
|
||||||
delay = 1000
|
delay = 1000
|
||||||
entrypoint = ["./tmp/main"]
|
entrypoint = ["./tmp/main"]
|
||||||
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
|
exclude_dir = ["assets", "tmp", "vendor", "testdata", "internal/repository"]
|
||||||
exclude_file = []
|
exclude_file = []
|
||||||
exclude_regex = ["_test.go"]
|
exclude_regex = ["_test.go"]
|
||||||
exclude_unchanged = false
|
exclude_unchanged = false
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"log"
|
"log"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"gitea.starryskymeow.cn/B309/datamarket/internal/config"
|
||||||
"gitea.starryskymeow.cn/B309/datamarket/internal/repository"
|
"gitea.starryskymeow.cn/B309/datamarket/internal/repository"
|
||||||
"gitea.starryskymeow.cn/B309/datamarket/internal/router"
|
"gitea.starryskymeow.cn/B309/datamarket/internal/router"
|
||||||
"gitea.starryskymeow.cn/B309/datamarket/internal/service"
|
"gitea.starryskymeow.cn/B309/datamarket/internal/service"
|
||||||
@@ -59,8 +61,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
queries := repository.New(pool)
|
queries := repository.New(pool)
|
||||||
appService := service.New(queries)
|
cfg, err := config.New(queries)
|
||||||
r := router.New(appService)
|
if err != nil {
|
||||||
|
slog.Error("Error loading config")
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
appService := service.New(queries, cfg)
|
||||||
|
r := router.New(appService, cfg)
|
||||||
|
|
||||||
addr := os.Getenv("SERVER_ADDR")
|
addr := os.Getenv("SERVER_ADDR")
|
||||||
|
|
||||||
|
|||||||
53
db/migration/000002_v2.down.sql
Normal file
53
db/migration/000002_v2.down.sql
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
-- remove user reference from orders
|
||||||
|
ALTER TABLE orders
|
||||||
|
DROP COLUMN IF EXISTS user_id;
|
||||||
|
|
||||||
|
-- remove agent columns from validations
|
||||||
|
ALTER TABLE validations
|
||||||
|
DROP COLUMN IF EXISTS agent_risk_notice;
|
||||||
|
|
||||||
|
ALTER TABLE validations
|
||||||
|
DROP COLUMN IF EXISTS agent_delivery_advice;
|
||||||
|
|
||||||
|
ALTER TABLE validations
|
||||||
|
DROP COLUMN IF EXISTS agent_continue_trade_advice;
|
||||||
|
|
||||||
|
ALTER TABLE validations
|
||||||
|
DROP COLUMN IF EXISTS agent_validation_explanation;
|
||||||
|
|
||||||
|
-- remove agent columns from pricing_results
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
DROP COLUMN IF EXISTS agent_next_action;
|
||||||
|
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
DROP COLUMN IF EXISTS agent_budget_advice;
|
||||||
|
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
DROP COLUMN IF EXISTS agent_risk_advice;
|
||||||
|
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
DROP COLUMN IF EXISTS agent_task_match_explanation;
|
||||||
|
|
||||||
|
-- remove user reference from buyer_requests
|
||||||
|
ALTER TABLE buyer_requests
|
||||||
|
DROP COLUMN IF EXISTS user_id;
|
||||||
|
|
||||||
|
-- remove agent columns from data_assets
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
DROP COLUMN IF EXISTS agent_asset_explanation;
|
||||||
|
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
DROP COLUMN IF EXISTS agent_risk_per_mission_advice;
|
||||||
|
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
DROP COLUMN IF EXISTS agent_recommended_tasks;
|
||||||
|
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
DROP COLUMN IF EXISTS agent_asset_summary;
|
||||||
|
|
||||||
|
-- remove user reference from data_assets
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
DROP COLUMN IF EXISTS user_id;
|
||||||
|
|
||||||
|
-- drop users table
|
||||||
|
DROP TABLE IF EXISTS users;
|
||||||
77
db/migration/000002_v2.up.sql
Normal file
77
db/migration/000002_v2.up.sql
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
-- new user table
|
||||||
|
CREATE TABLE IF NOT EXISTS users
|
||||||
|
(
|
||||||
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
username text NOT NULL UNIQUE,
|
||||||
|
password text NOT NULL,
|
||||||
|
role text NOT NULL, -- admin user
|
||||||
|
display_name text NOT NULL,
|
||||||
|
account_status text NOT NULL DEFAULT 'active',
|
||||||
|
last_login_at timestamptz,
|
||||||
|
created_at timestamptz DEFAULT now()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- add user reference to data_assets
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
ADD COLUMN IF NOT EXISTS user_id uuid REFERENCES users (id);
|
||||||
|
|
||||||
|
-- add agent columns to data_assets
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_asset_summary text;
|
||||||
|
COMMENT ON COLUMN data_assets.agent_asset_summary IS '智能助手对当前资产的简短画像总结';
|
||||||
|
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_recommended_tasks jsonb;
|
||||||
|
COMMENT ON COLUMN data_assets.agent_recommended_tasks IS '推荐的适用任务列表';
|
||||||
|
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_risk_per_mission_advice text;
|
||||||
|
COMMENT ON COLUMN data_assets.agent_risk_per_mission_advice IS '当前资产更适合的权限与风险建议';
|
||||||
|
|
||||||
|
ALTER TABLE data_assets
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_asset_explanation text;
|
||||||
|
COMMENT ON COLUMN data_assets.agent_asset_explanation IS '为什么该资产当前基础价值较高/中/低';
|
||||||
|
|
||||||
|
-- add user reference to buyer_requests
|
||||||
|
ALTER TABLE buyer_requests
|
||||||
|
ADD COLUMN IF NOT EXISTS user_id uuid REFERENCES users (id);
|
||||||
|
|
||||||
|
-- add agent to pricing_results
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_task_match_explanation text;
|
||||||
|
COMMENT ON COLUMN pricing_results.agent_task_match_explanation IS '解释当前数据与任务的匹配关系';
|
||||||
|
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_risk_advice text;
|
||||||
|
COMMENT ON COLUMN pricing_results.agent_risk_advice IS '解释当前隐私风险与权限建议';
|
||||||
|
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_budget_advice text;
|
||||||
|
COMMENT ON COLUMN pricing_results.agent_budget_advice IS '根据预算给出的建议';
|
||||||
|
|
||||||
|
ALTER TABLE pricing_results
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_next_action text;
|
||||||
|
COMMENT ON COLUMN pricing_results.agent_next_action IS '建议接下来做什么';
|
||||||
|
|
||||||
|
-- add agent to
|
||||||
|
ALTER TABLE validations
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_validation_explanation text;
|
||||||
|
COMMENT ON COLUMN validations.agent_validation_explanation IS '对当前验证结果的自然语言解释';
|
||||||
|
|
||||||
|
ALTER TABLE validations
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_continue_trade_advice text;
|
||||||
|
COMMENT ON COLUMN validations.agent_continue_trade_advice IS '对是否继续成交的建议';
|
||||||
|
|
||||||
|
ALTER TABLE validations
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_delivery_advice text;
|
||||||
|
COMMENT ON COLUMN validations.agent_delivery_advice IS '对交付方式的建议';
|
||||||
|
|
||||||
|
ALTER TABLE validations
|
||||||
|
ADD COLUMN IF NOT EXISTS agent_risk_notice text;
|
||||||
|
COMMENT ON COLUMN validations.agent_risk_notice IS '对后续交易的风险提示';
|
||||||
|
|
||||||
|
-- add user to order
|
||||||
|
ALTER TABLE orders
|
||||||
|
ADD COLUMN IF NOT EXISTS user_id uuid REFERENCES users (id);
|
||||||
|
|
||||||
|
|
||||||
1
db/migration/000003_add_jwt_config.down.sql
Normal file
1
db/migration/000003_add_jwt_config.down.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DROP TABLE IF EXISTS config;
|
||||||
11
db/migration/000003_add_jwt_config.up.sql
Normal file
11
db/migration/000003_add_jwt_config.up.sql
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
-- add config(jwt)
|
||||||
|
CREATE TABLE IF NOT EXISTS config
|
||||||
|
(
|
||||||
|
id integer PRIMARY KEY, -- always 0
|
||||||
|
"Jwt.Alg" text NOT NULL DEFAULT 'HS256',
|
||||||
|
"Jwt.SignKey" text NOT NULL DEFAULT gen_random_uuid(),
|
||||||
|
"Jwt.VerifyKye" text DEFAULT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO config (id)
|
||||||
|
VALUES (0);
|
||||||
4
db/query/config.sql
Normal file
4
db/query/config.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
-- name: GetConfig :one
|
||||||
|
SELECT *
|
||||||
|
FROM config
|
||||||
|
WHERE id = 0;
|
||||||
@@ -53,12 +53,12 @@ WHERE (
|
|||||||
);
|
);
|
||||||
|
|
||||||
-- name: GetDataAsset :one
|
-- name: GetDataAsset :one
|
||||||
SELECT id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at
|
SELECT *
|
||||||
FROM data_assets
|
FROM data_assets
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
||||||
-- name: ListDataAssets :many
|
-- name: ListDataAssets :many
|
||||||
SELECT id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at
|
SELECT *
|
||||||
FROM data_assets
|
FROM data_assets
|
||||||
WHERE (
|
WHERE (
|
||||||
NULLIF(sqlc.narg(keyword)::text, '') IS NULL
|
NULLIF(sqlc.narg(keyword)::text, '') IS NULL
|
||||||
@@ -89,7 +89,7 @@ UPDATE data_assets
|
|||||||
SET asset_status = $2,
|
SET asset_status = $2,
|
||||||
updated_at = now()
|
updated_at = now()
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: CreateBuyerRequest :one
|
-- name: CreateBuyerRequest :one
|
||||||
INSERT INTO buyer_requests (
|
INSERT INTO buyer_requests (
|
||||||
@@ -104,15 +104,15 @@ INSERT INTO buyer_requests (
|
|||||||
request_status
|
request_status
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||||
RETURNING id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetBuyerRequest :one
|
-- name: GetBuyerRequest :one
|
||||||
SELECT id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at
|
SELECT *
|
||||||
FROM buyer_requests
|
FROM buyer_requests
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
||||||
-- name: ListBuyerRequests :many
|
-- name: ListBuyerRequests :many
|
||||||
SELECT id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at
|
SELECT *
|
||||||
FROM buyer_requests
|
FROM buyer_requests
|
||||||
ORDER BY created_at DESC, id DESC
|
ORDER BY created_at DESC, id DESC
|
||||||
LIMIT $1 OFFSET $2;
|
LIMIT $1 OFFSET $2;
|
||||||
@@ -133,15 +133,15 @@ INSERT INTO pricing_results (
|
|||||||
pricing_status
|
pricing_status
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||||
RETURNING id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetPricingResult :one
|
-- name: GetPricingResult :one
|
||||||
SELECT id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at
|
SELECT *
|
||||||
FROM pricing_results
|
FROM pricing_results
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
||||||
-- name: ListPricingResults :many
|
-- name: ListPricingResults :many
|
||||||
SELECT id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at
|
SELECT *
|
||||||
FROM pricing_results
|
FROM pricing_results
|
||||||
ORDER BY created_at DESC, id DESC
|
ORDER BY created_at DESC, id DESC
|
||||||
LIMIT $1 OFFSET $2;
|
LIMIT $1 OFFSET $2;
|
||||||
@@ -160,7 +160,7 @@ INSERT INTO validations (
|
|||||||
validation_finished_at
|
validation_finished_at
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||||
RETURNING id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: UpdateValidationResult :one
|
-- name: UpdateValidationResult :one
|
||||||
UPDATE validations
|
UPDATE validations
|
||||||
@@ -171,15 +171,15 @@ SET validation_status = $2,
|
|||||||
continue_recommendation = $6,
|
continue_recommendation = $6,
|
||||||
validation_finished_at = $7
|
validation_finished_at = $7
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetValidation :one
|
-- name: GetValidation :one
|
||||||
SELECT id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at
|
SELECT *
|
||||||
FROM validations
|
FROM validations
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
||||||
-- name: ListValidations :many
|
-- name: ListValidations :many
|
||||||
SELECT id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at
|
SELECT *
|
||||||
FROM validations
|
FROM validations
|
||||||
ORDER BY validation_created_at DESC, id DESC
|
ORDER BY validation_created_at DESC, id DESC
|
||||||
LIMIT $1 OFFSET $2;
|
LIMIT $1 OFFSET $2;
|
||||||
@@ -203,15 +203,15 @@ INSERT INTO orders (
|
|||||||
order_status
|
order_status
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||||
RETURNING id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetOrder :one
|
-- name: GetOrder :one
|
||||||
SELECT id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at
|
SELECT *
|
||||||
FROM orders
|
FROM orders
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
|
|
||||||
-- name: ListOrders :many
|
-- name: ListOrders :many
|
||||||
SELECT id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at
|
SELECT *
|
||||||
FROM orders
|
FROM orders
|
||||||
WHERE NULLIF(sqlc.narg(order_status)::text, '') IS NULL
|
WHERE NULLIF(sqlc.narg(order_status)::text, '') IS NULL
|
||||||
OR order_status = sqlc.narg(order_status)::text
|
OR order_status = sqlc.narg(order_status)::text
|
||||||
@@ -229,4 +229,4 @@ UPDATE orders
|
|||||||
SET order_status = $2,
|
SET order_status = $2,
|
||||||
order_updated_at = now()
|
order_updated_at = now()
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at;
|
RETURNING *;
|
||||||
|
|||||||
4
db/query/user.sql
Normal file
4
db/query/user.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
-- name: GetUserByUsername :one
|
||||||
|
SELECT *
|
||||||
|
FROM users
|
||||||
|
WHERE username = $1;
|
||||||
15
go.mod
15
go.mod
@@ -12,10 +12,21 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ajg/form v1.5.1 // indirect
|
github.com/ajg/form v1.5.1 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||||
|
github.com/go-chi/jwtauth/v5 v5.4.0 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.3 // 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/lestrrat-go/blackmagic v1.0.3 // indirect
|
||||||
|
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
||||||
|
github.com/lestrrat-go/httprc/v3 v3.0.0-beta2 // indirect
|
||||||
|
github.com/lestrrat-go/jwx/v3 v3.0.2 // indirect
|
||||||
|
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||||
github.com/lib/pq v1.10.9 // indirect
|
github.com/lib/pq v1.10.9 // indirect
|
||||||
golang.org/x/sync v0.18.0 // indirect
|
github.com/segmentio/asm v1.2.0 // indirect
|
||||||
golang.org/x/text v0.31.0 // indirect
|
golang.org/x/crypto v0.49.0 // indirect
|
||||||
|
golang.org/x/sync v0.20.0 // indirect
|
||||||
|
golang.org/x/sys v0.42.0 // indirect
|
||||||
|
golang.org/x/text v0.35.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
30
go.sum
30
go.sum
@@ -11,6 +11,8 @@ github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmC
|
|||||||
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.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||||
github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4=
|
github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4=
|
||||||
github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU=
|
github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU=
|
||||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||||
@@ -25,12 +27,16 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
|
|||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
||||||
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
||||||
|
github.com/go-chi/jwtauth/v5 v5.4.0 h1:Ieh0xMJsFvqylqJ02/mQHKzbbKO9DYNBh4DPKCwTwYI=
|
||||||
|
github.com/go-chi/jwtauth/v5 v5.4.0/go.mod h1:w6yjqUUXz1b8+oiJel64Sz1KJwduQM6qUA5QNzO5+bQ=
|
||||||
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||||
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
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/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 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
|
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
|
||||||
@@ -45,6 +51,16 @@ 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/lestrrat-go/blackmagic v1.0.3 h1:94HXkVLxkZO9vJI/w2u1T0DAoprShFd13xtnSINtDWs=
|
||||||
|
github.com/lestrrat-go/blackmagic v1.0.3/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw=
|
||||||
|
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
|
||||||
|
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
|
||||||
|
github.com/lestrrat-go/httprc/v3 v3.0.0-beta2 h1:SDxjGoH7qj0nBXVrcrxX8eD94wEnjR+EEuqqmeqQYlY=
|
||||||
|
github.com/lestrrat-go/httprc/v3 v3.0.0-beta2/go.mod h1:Nwo81sMxE0DcvTB+rJyynNhv/DUu2yZErV7sscw9pHE=
|
||||||
|
github.com/lestrrat-go/jwx/v3 v3.0.2 h1:N+XLjTJEzDZRP3S0SezclXFAfopwL+o5vaL+qg6rX1I=
|
||||||
|
github.com/lestrrat-go/jwx/v3 v3.0.2/go.mod h1:qO9w1qkQH77a0r9OXNM33YQPnV/evetKYRg58h1rBNE=
|
||||||
|
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
|
||||||
|
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||||
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/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||||
@@ -62,9 +78,13 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||||
|
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||||
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/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.6.1/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.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.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=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||||
@@ -77,12 +97,22 @@ go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/Wgbsd
|
|||||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||||
|
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||||
|
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||||
|
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
||||||
|
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
||||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
|
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||||
|
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
|
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||||
|
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||||
|
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||||
|
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||||
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/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=
|
||||||
|
|||||||
22
internal/config/config.go
Normal file
22
internal/config/config.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gitea.starryskymeow.cn/B309/datamarket/internal/repository"
|
||||||
|
"github.com/go-chi/jwtauth/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
JWTAuth *jwtauth.JWTAuth
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(repo *repository.Queries) (*Config, error) {
|
||||||
|
config := new(Config)
|
||||||
|
cfg, err := repo.GetConfig(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.JWTAuth = jwtauth.New(cfg.JwtAlg, []byte(cfg.JwtSignKey), nil)
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
73
internal/handler/auth.go
Normal file
73
internal/handler/auth.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"gitea.starryskymeow.cn/B309/datamarket/internal/service"
|
||||||
|
"github.com/go-chi/jwtauth/v5"
|
||||||
|
"github.com/go-chi/render"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LoginRequest struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const usernameExpr = `^\S{3,32}$`
|
||||||
|
const passwordExpr = `^\S{8,64}$`
|
||||||
|
|
||||||
|
func (req *LoginRequest) Bind(_ *http.Request) error {
|
||||||
|
// username
|
||||||
|
if ok, _ := regexp.MatchString(usernameExpr, req.Username); !ok {
|
||||||
|
return fmt.Errorf("invalid username, must match %q", usernameExpr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// password
|
||||||
|
if ok, _ := regexp.MatchString(passwordExpr, req.Password); !ok {
|
||||||
|
return fmt.Errorf("invalid password, must match %q", passwordExpr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoginHandler POST /api/auth/login
|
||||||
|
func LoginHandler(auth service.AuthService) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
req := &LoginRequest{}
|
||||||
|
if err := render.Bind(r, req); err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
renderServiceError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user, err := auth.VerifyUser(r.Context(), service.VerifyUserInput{
|
||||||
|
Username: req.Username,
|
||||||
|
Password: req.Password,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
renderServiceError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: "jwt",
|
||||||
|
Value: user.Token,
|
||||||
|
Path: "/",
|
||||||
|
HttpOnly: true,
|
||||||
|
Secure: true,
|
||||||
|
MaxAge: 60 * 60 * 24, // 1d
|
||||||
|
SameSite: http.SameSiteLaxMode,
|
||||||
|
})
|
||||||
|
renderSuccess(w, r, http.StatusAccepted, "登录成功", user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MeHandler(auth service.AuthService) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, claims, err := jwtauth.FromContext(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
renderServiceError(w, r, err)
|
||||||
|
}
|
||||||
|
renderSuccess(w, r, http.StatusOK, "logged in", claims)
|
||||||
|
}
|
||||||
|
}
|
||||||
28
internal/repository/config.sql.go
Normal file
28
internal/repository/config.sql.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: config.sql
|
||||||
|
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
const getConfig = `-- name: GetConfig :one
|
||||||
|
SELECT id, "Jwt.Alg", "Jwt.SignKey", "Jwt.VerifyKye"
|
||||||
|
FROM config
|
||||||
|
WHERE id = 0
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetConfig(ctx context.Context) (Config, error) {
|
||||||
|
row := q.db.QueryRow(ctx, getConfig)
|
||||||
|
var i Config
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.JwtAlg,
|
||||||
|
&i.JwtSignKey,
|
||||||
|
&i.JwtVerifyKye,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
@@ -97,7 +97,7 @@ INSERT INTO buyer_requests (
|
|||||||
request_status
|
request_status
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||||
RETURNING id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at
|
RETURNING id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at, user_id
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateBuyerRequestParams struct {
|
type CreateBuyerRequestParams struct {
|
||||||
@@ -138,6 +138,7 @@ func (q *Queries) CreateBuyerRequest(ctx context.Context, arg CreateBuyerRequest
|
|||||||
&i.RequestStatus,
|
&i.RequestStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -195,7 +196,33 @@ type CreateDataAssetParams struct {
|
|||||||
AssetStatus string `json:"asset_status"`
|
AssetStatus string `json:"asset_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateDataAsset(ctx context.Context, arg CreateDataAssetParams) (DataAsset, error) {
|
type CreateDataAssetRow struct {
|
||||||
|
ID pgtype.UUID `json:"id"`
|
||||||
|
AssetName string `json:"asset_name"`
|
||||||
|
AssetType string `json:"asset_type"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
ApplicationScene pgtype.Text `json:"application_scene"`
|
||||||
|
DataDescription string `json:"data_description"`
|
||||||
|
DataScale string `json:"data_scale"`
|
||||||
|
CollectionMethod string `json:"collection_method"`
|
||||||
|
LabelingStatus pgtype.Text `json:"labeling_status"`
|
||||||
|
UpdateFrequency pgtype.Text `json:"update_frequency"`
|
||||||
|
PrivacyLevel string `json:"privacy_level"`
|
||||||
|
PermissionMode string `json:"permission_mode"`
|
||||||
|
SupportsValidation bool `json:"supports_validation"`
|
||||||
|
SellerExpectedPriceMin pgtype.Numeric `json:"seller_expected_price_min"`
|
||||||
|
SellerExpectedPriceMax pgtype.Numeric `json:"seller_expected_price_max"`
|
||||||
|
QualityLevel pgtype.Text `json:"quality_level"`
|
||||||
|
ScarcityLevel pgtype.Text `json:"scarcity_level"`
|
||||||
|
BaseValueScore pgtype.Numeric `json:"base_value_score"`
|
||||||
|
BasePriceMin pgtype.Numeric `json:"base_price_min"`
|
||||||
|
BasePriceMax pgtype.Numeric `json:"base_price_max"`
|
||||||
|
AssetStatus string `json:"asset_status"`
|
||||||
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||||
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateDataAsset(ctx context.Context, arg CreateDataAssetParams) (CreateDataAssetRow, error) {
|
||||||
row := q.db.QueryRow(ctx, createDataAsset,
|
row := q.db.QueryRow(ctx, createDataAsset,
|
||||||
arg.AssetName,
|
arg.AssetName,
|
||||||
arg.AssetType,
|
arg.AssetType,
|
||||||
@@ -218,7 +245,7 @@ func (q *Queries) CreateDataAsset(ctx context.Context, arg CreateDataAssetParams
|
|||||||
arg.BasePriceMax,
|
arg.BasePriceMax,
|
||||||
arg.AssetStatus,
|
arg.AssetStatus,
|
||||||
)
|
)
|
||||||
var i DataAsset
|
var i CreateDataAssetRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AssetName,
|
&i.AssetName,
|
||||||
@@ -262,7 +289,7 @@ INSERT INTO orders (
|
|||||||
order_status
|
order_status
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||||
RETURNING id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at
|
RETURNING id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at, user_id
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateOrderParams struct {
|
type CreateOrderParams struct {
|
||||||
@@ -309,6 +336,7 @@ func (q *Queries) CreateOrder(ctx context.Context, arg CreateOrderParams) (Order
|
|||||||
&i.OrderStatus,
|
&i.OrderStatus,
|
||||||
&i.OrderCreatedAt,
|
&i.OrderCreatedAt,
|
||||||
&i.OrderUpdatedAt,
|
&i.OrderUpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -329,7 +357,7 @@ INSERT INTO pricing_results (
|
|||||||
pricing_status
|
pricing_status
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||||
RETURNING id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at
|
RETURNING id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at, agent_task_match_explanation, agent_risk_advice, agent_budget_advice, agent_next_action
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreatePricingResultParams struct {
|
type CreatePricingResultParams struct {
|
||||||
@@ -379,6 +407,10 @@ func (q *Queries) CreatePricingResult(ctx context.Context, arg CreatePricingResu
|
|||||||
&i.PricingStatus,
|
&i.PricingStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.AgentTaskMatchExplanation,
|
||||||
|
&i.AgentRiskAdvice,
|
||||||
|
&i.AgentBudgetAdvice,
|
||||||
|
&i.AgentNextAction,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -397,7 +429,7 @@ INSERT INTO validations (
|
|||||||
validation_finished_at
|
validation_finished_at
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||||
RETURNING id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at
|
RETURNING id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at, agent_validation_explanation, agent_continue_trade_advice, agent_delivery_advice, agent_risk_notice
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateValidationParams struct {
|
type CreateValidationParams struct {
|
||||||
@@ -440,12 +472,16 @@ func (q *Queries) CreateValidation(ctx context.Context, arg CreateValidationPara
|
|||||||
&i.ContinueRecommendation,
|
&i.ContinueRecommendation,
|
||||||
&i.ValidationCreatedAt,
|
&i.ValidationCreatedAt,
|
||||||
&i.ValidationFinishedAt,
|
&i.ValidationFinishedAt,
|
||||||
|
&i.AgentValidationExplanation,
|
||||||
|
&i.AgentContinueTradeAdvice,
|
||||||
|
&i.AgentDeliveryAdvice,
|
||||||
|
&i.AgentRiskNotice,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBuyerRequest = `-- name: GetBuyerRequest :one
|
const getBuyerRequest = `-- name: GetBuyerRequest :one
|
||||||
SELECT id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at
|
SELECT id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at, user_id
|
||||||
FROM buyer_requests
|
FROM buyer_requests
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
@@ -466,12 +502,13 @@ func (q *Queries) GetBuyerRequest(ctx context.Context, id pgtype.UUID) (BuyerReq
|
|||||||
&i.RequestStatus,
|
&i.RequestStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDataAsset = `-- name: GetDataAsset :one
|
const getDataAsset = `-- name: GetDataAsset :one
|
||||||
SELECT id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at
|
SELECT id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at, user_id, agent_asset_summary, agent_recommended_tasks, agent_risk_per_mission_advice, agent_asset_explanation
|
||||||
FROM data_assets
|
FROM data_assets
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
@@ -503,12 +540,17 @@ func (q *Queries) GetDataAsset(ctx context.Context, id pgtype.UUID) (DataAsset,
|
|||||||
&i.AssetStatus,
|
&i.AssetStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
|
&i.AgentAssetSummary,
|
||||||
|
&i.AgentRecommendedTasks,
|
||||||
|
&i.AgentRiskPerMissionAdvice,
|
||||||
|
&i.AgentAssetExplanation,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrder = `-- name: GetOrder :one
|
const getOrder = `-- name: GetOrder :one
|
||||||
SELECT id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at
|
SELECT id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at, user_id
|
||||||
FROM orders
|
FROM orders
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
@@ -531,12 +573,13 @@ func (q *Queries) GetOrder(ctx context.Context, id pgtype.UUID) (Order, error) {
|
|||||||
&i.OrderStatus,
|
&i.OrderStatus,
|
||||||
&i.OrderCreatedAt,
|
&i.OrderCreatedAt,
|
||||||
&i.OrderUpdatedAt,
|
&i.OrderUpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPricingResult = `-- name: GetPricingResult :one
|
const getPricingResult = `-- name: GetPricingResult :one
|
||||||
SELECT id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at
|
SELECT id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at, agent_task_match_explanation, agent_risk_advice, agent_budget_advice, agent_next_action
|
||||||
FROM pricing_results
|
FROM pricing_results
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
@@ -560,12 +603,16 @@ func (q *Queries) GetPricingResult(ctx context.Context, id pgtype.UUID) (Pricing
|
|||||||
&i.PricingStatus,
|
&i.PricingStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.AgentTaskMatchExplanation,
|
||||||
|
&i.AgentRiskAdvice,
|
||||||
|
&i.AgentBudgetAdvice,
|
||||||
|
&i.AgentNextAction,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getValidation = `-- name: GetValidation :one
|
const getValidation = `-- name: GetValidation :one
|
||||||
SELECT id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at
|
SELECT id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at, agent_validation_explanation, agent_continue_trade_advice, agent_delivery_advice, agent_risk_notice
|
||||||
FROM validations
|
FROM validations
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
@@ -586,12 +633,16 @@ func (q *Queries) GetValidation(ctx context.Context, id pgtype.UUID) (Validation
|
|||||||
&i.ContinueRecommendation,
|
&i.ContinueRecommendation,
|
||||||
&i.ValidationCreatedAt,
|
&i.ValidationCreatedAt,
|
||||||
&i.ValidationFinishedAt,
|
&i.ValidationFinishedAt,
|
||||||
|
&i.AgentValidationExplanation,
|
||||||
|
&i.AgentContinueTradeAdvice,
|
||||||
|
&i.AgentDeliveryAdvice,
|
||||||
|
&i.AgentRiskNotice,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const listBuyerRequests = `-- name: ListBuyerRequests :many
|
const listBuyerRequests = `-- name: ListBuyerRequests :many
|
||||||
SELECT id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at
|
SELECT id, asset_id, task_type, model_type, buyer_budget_min, buyer_budget_max, privacy_requirement, usage_purpose, request_note, request_status, created_at, updated_at, user_id
|
||||||
FROM buyer_requests
|
FROM buyer_requests
|
||||||
ORDER BY created_at DESC, id DESC
|
ORDER BY created_at DESC, id DESC
|
||||||
LIMIT $1 OFFSET $2
|
LIMIT $1 OFFSET $2
|
||||||
@@ -624,6 +675,7 @@ func (q *Queries) ListBuyerRequests(ctx context.Context, arg ListBuyerRequestsPa
|
|||||||
&i.RequestStatus,
|
&i.RequestStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -636,7 +688,7 @@ func (q *Queries) ListBuyerRequests(ctx context.Context, arg ListBuyerRequestsPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
const listDataAssets = `-- name: ListDataAssets :many
|
const listDataAssets = `-- name: ListDataAssets :many
|
||||||
SELECT id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at
|
SELECT id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at, user_id, agent_asset_summary, agent_recommended_tasks, agent_risk_per_mission_advice, agent_asset_explanation
|
||||||
FROM data_assets
|
FROM data_assets
|
||||||
WHERE (
|
WHERE (
|
||||||
NULLIF($3::text, '') IS NULL
|
NULLIF($3::text, '') IS NULL
|
||||||
@@ -714,6 +766,11 @@ func (q *Queries) ListDataAssets(ctx context.Context, arg ListDataAssetsParams)
|
|||||||
&i.AssetStatus,
|
&i.AssetStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
|
&i.AgentAssetSummary,
|
||||||
|
&i.AgentRecommendedTasks,
|
||||||
|
&i.AgentRiskPerMissionAdvice,
|
||||||
|
&i.AgentAssetExplanation,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -726,7 +783,7 @@ func (q *Queries) ListDataAssets(ctx context.Context, arg ListDataAssetsParams)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const listOrders = `-- name: ListOrders :many
|
const listOrders = `-- name: ListOrders :many
|
||||||
SELECT id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at
|
SELECT id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at, user_id
|
||||||
FROM orders
|
FROM orders
|
||||||
WHERE NULLIF($3::text, '') IS NULL
|
WHERE NULLIF($3::text, '') IS NULL
|
||||||
OR order_status = $3::text
|
OR order_status = $3::text
|
||||||
@@ -764,6 +821,7 @@ func (q *Queries) ListOrders(ctx context.Context, arg ListOrdersParams) ([]Order
|
|||||||
&i.OrderStatus,
|
&i.OrderStatus,
|
||||||
&i.OrderCreatedAt,
|
&i.OrderCreatedAt,
|
||||||
&i.OrderUpdatedAt,
|
&i.OrderUpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -776,7 +834,7 @@ func (q *Queries) ListOrders(ctx context.Context, arg ListOrdersParams) ([]Order
|
|||||||
}
|
}
|
||||||
|
|
||||||
const listPricingResults = `-- name: ListPricingResults :many
|
const listPricingResults = `-- name: ListPricingResults :many
|
||||||
SELECT id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at
|
SELECT id, asset_id, request_id, scenario_value_score, scenario_price_min, scenario_price_max, suggested_price, success_probability, pricing_reason_1, pricing_reason_2, pricing_reason_3, verification_suggestion, pricing_status, created_at, updated_at, agent_task_match_explanation, agent_risk_advice, agent_budget_advice, agent_next_action
|
||||||
FROM pricing_results
|
FROM pricing_results
|
||||||
ORDER BY created_at DESC, id DESC
|
ORDER BY created_at DESC, id DESC
|
||||||
LIMIT $1 OFFSET $2
|
LIMIT $1 OFFSET $2
|
||||||
@@ -812,6 +870,10 @@ func (q *Queries) ListPricingResults(ctx context.Context, arg ListPricingResults
|
|||||||
&i.PricingStatus,
|
&i.PricingStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.AgentTaskMatchExplanation,
|
||||||
|
&i.AgentRiskAdvice,
|
||||||
|
&i.AgentBudgetAdvice,
|
||||||
|
&i.AgentNextAction,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -824,7 +886,7 @@ func (q *Queries) ListPricingResults(ctx context.Context, arg ListPricingResults
|
|||||||
}
|
}
|
||||||
|
|
||||||
const listValidations = `-- name: ListValidations :many
|
const listValidations = `-- name: ListValidations :many
|
||||||
SELECT id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at
|
SELECT id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at, agent_validation_explanation, agent_continue_trade_advice, agent_delivery_advice, agent_risk_notice
|
||||||
FROM validations
|
FROM validations
|
||||||
ORDER BY validation_created_at DESC, id DESC
|
ORDER BY validation_created_at DESC, id DESC
|
||||||
LIMIT $1 OFFSET $2
|
LIMIT $1 OFFSET $2
|
||||||
@@ -857,6 +919,10 @@ func (q *Queries) ListValidations(ctx context.Context, arg ListValidationsParams
|
|||||||
&i.ContinueRecommendation,
|
&i.ContinueRecommendation,
|
||||||
&i.ValidationCreatedAt,
|
&i.ValidationCreatedAt,
|
||||||
&i.ValidationFinishedAt,
|
&i.ValidationFinishedAt,
|
||||||
|
&i.AgentValidationExplanation,
|
||||||
|
&i.AgentContinueTradeAdvice,
|
||||||
|
&i.AgentDeliveryAdvice,
|
||||||
|
&i.AgentRiskNotice,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -873,7 +939,7 @@ UPDATE data_assets
|
|||||||
SET asset_status = $2,
|
SET asset_status = $2,
|
||||||
updated_at = now()
|
updated_at = now()
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at
|
RETURNING id, asset_name, asset_type, domain, application_scene, data_description, data_scale, collection_method, labeling_status, update_frequency, privacy_level, permission_mode, supports_validation, seller_expected_price_min, seller_expected_price_max, quality_level, scarcity_level, base_value_score, base_price_min, base_price_max, asset_status, created_at, updated_at, user_id, agent_asset_summary, agent_recommended_tasks, agent_risk_per_mission_advice, agent_asset_explanation
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateDataAssetStatusParams struct {
|
type UpdateDataAssetStatusParams struct {
|
||||||
@@ -908,6 +974,11 @@ func (q *Queries) UpdateDataAssetStatus(ctx context.Context, arg UpdateDataAsset
|
|||||||
&i.AssetStatus,
|
&i.AssetStatus,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
|
&i.AgentAssetSummary,
|
||||||
|
&i.AgentRecommendedTasks,
|
||||||
|
&i.AgentRiskPerMissionAdvice,
|
||||||
|
&i.AgentAssetExplanation,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -917,7 +988,7 @@ UPDATE orders
|
|||||||
SET order_status = $2,
|
SET order_status = $2,
|
||||||
order_updated_at = now()
|
order_updated_at = now()
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at
|
RETURNING id, asset_id, request_id, pricing_id, validation_id, asset_name, current_price, negotiation_min, negotiation_max, validation_used, delivery_mode, order_status, order_created_at, order_updated_at, user_id
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateOrderStatusParams struct {
|
type UpdateOrderStatusParams struct {
|
||||||
@@ -943,6 +1014,7 @@ func (q *Queries) UpdateOrderStatus(ctx context.Context, arg UpdateOrderStatusPa
|
|||||||
&i.OrderStatus,
|
&i.OrderStatus,
|
||||||
&i.OrderCreatedAt,
|
&i.OrderCreatedAt,
|
||||||
&i.OrderUpdatedAt,
|
&i.OrderUpdatedAt,
|
||||||
|
&i.UserID,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -956,7 +1028,7 @@ SET validation_status = $2,
|
|||||||
continue_recommendation = $6,
|
continue_recommendation = $6,
|
||||||
validation_finished_at = $7
|
validation_finished_at = $7
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at
|
RETURNING id, asset_id, request_id, validation_type, validation_requested, validation_status, validation_signal, validation_score, risk_warning, continue_recommendation, validation_created_at, validation_finished_at, agent_validation_explanation, agent_continue_trade_advice, agent_delivery_advice, agent_risk_notice
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateValidationResultParams struct {
|
type UpdateValidationResultParams struct {
|
||||||
@@ -993,6 +1065,10 @@ func (q *Queries) UpdateValidationResult(ctx context.Context, arg UpdateValidati
|
|||||||
&i.ContinueRecommendation,
|
&i.ContinueRecommendation,
|
||||||
&i.ValidationCreatedAt,
|
&i.ValidationCreatedAt,
|
||||||
&i.ValidationFinishedAt,
|
&i.ValidationFinishedAt,
|
||||||
|
&i.AgentValidationExplanation,
|
||||||
|
&i.AgentContinueTradeAdvice,
|
||||||
|
&i.AgentDeliveryAdvice,
|
||||||
|
&i.AgentRiskNotice,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ type BuyerRequest struct {
|
|||||||
RequestStatus string `json:"request_status"`
|
RequestStatus string `json:"request_status"`
|
||||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||||
|
UserID pgtype.UUID `json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
JwtAlg string `json:"Jwt.Alg"`
|
||||||
|
JwtSignKey string `json:"Jwt.SignKey"`
|
||||||
|
JwtVerifyKye pgtype.Text `json:"Jwt.VerifyKye"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DataAsset struct {
|
type DataAsset struct {
|
||||||
@@ -47,6 +55,15 @@ type DataAsset struct {
|
|||||||
AssetStatus string `json:"asset_status"`
|
AssetStatus string `json:"asset_status"`
|
||||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||||
|
UserID pgtype.UUID `json:"user_id"`
|
||||||
|
// 智能助手对当前资产的简短画像总结
|
||||||
|
AgentAssetSummary pgtype.Text `json:"agent_asset_summary"`
|
||||||
|
// 推荐的适用任务列表
|
||||||
|
AgentRecommendedTasks []byte `json:"agent_recommended_tasks"`
|
||||||
|
// 当前资产更适合的权限与风险建议
|
||||||
|
AgentRiskPerMissionAdvice pgtype.Text `json:"agent_risk_per_mission_advice"`
|
||||||
|
// 为什么该资产当前基础价值较高/中/低
|
||||||
|
AgentAssetExplanation pgtype.Text `json:"agent_asset_explanation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Order struct {
|
type Order struct {
|
||||||
@@ -64,6 +81,7 @@ type Order struct {
|
|||||||
OrderStatus string `json:"order_status"`
|
OrderStatus string `json:"order_status"`
|
||||||
OrderCreatedAt pgtype.Timestamptz `json:"order_created_at"`
|
OrderCreatedAt pgtype.Timestamptz `json:"order_created_at"`
|
||||||
OrderUpdatedAt pgtype.Timestamptz `json:"order_updated_at"`
|
OrderUpdatedAt pgtype.Timestamptz `json:"order_updated_at"`
|
||||||
|
UserID pgtype.UUID `json:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PricingResult struct {
|
type PricingResult struct {
|
||||||
@@ -82,6 +100,25 @@ type PricingResult struct {
|
|||||||
PricingStatus string `json:"pricing_status"`
|
PricingStatus string `json:"pricing_status"`
|
||||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||||
|
// 解释当前数据与任务的匹配关系
|
||||||
|
AgentTaskMatchExplanation pgtype.Text `json:"agent_task_match_explanation"`
|
||||||
|
// 解释当前隐私风险与权限建议
|
||||||
|
AgentRiskAdvice pgtype.Text `json:"agent_risk_advice"`
|
||||||
|
// 根据预算给出的建议
|
||||||
|
AgentBudgetAdvice pgtype.Text `json:"agent_budget_advice"`
|
||||||
|
// 建议接下来做什么
|
||||||
|
AgentNextAction pgtype.Text `json:"agent_next_action"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID pgtype.UUID `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
AccountStatus string `json:"account_status"`
|
||||||
|
LastLoginAt pgtype.Timestamptz `json:"last_login_at"`
|
||||||
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Validation struct {
|
type Validation struct {
|
||||||
@@ -97,4 +134,12 @@ type Validation struct {
|
|||||||
ContinueRecommendation pgtype.Text `json:"continue_recommendation"`
|
ContinueRecommendation pgtype.Text `json:"continue_recommendation"`
|
||||||
ValidationCreatedAt pgtype.Timestamptz `json:"validation_created_at"`
|
ValidationCreatedAt pgtype.Timestamptz `json:"validation_created_at"`
|
||||||
ValidationFinishedAt pgtype.Timestamptz `json:"validation_finished_at"`
|
ValidationFinishedAt pgtype.Timestamptz `json:"validation_finished_at"`
|
||||||
|
// 对当前验证结果的自然语言解释
|
||||||
|
AgentValidationExplanation pgtype.Text `json:"agent_validation_explanation"`
|
||||||
|
// 对是否继续成交的建议
|
||||||
|
AgentContinueTradeAdvice pgtype.Text `json:"agent_continue_trade_advice"`
|
||||||
|
// 对交付方式的建议
|
||||||
|
AgentDeliveryAdvice pgtype.Text `json:"agent_delivery_advice"`
|
||||||
|
// 对后续交易的风险提示
|
||||||
|
AgentRiskNotice pgtype.Text `json:"agent_risk_notice"`
|
||||||
}
|
}
|
||||||
|
|||||||
32
internal/repository/user.sql.go
Normal file
32
internal/repository/user.sql.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: user.sql
|
||||||
|
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
const getUserByUsername = `-- name: GetUserByUsername :one
|
||||||
|
SELECT id, username, password, role, display_name, account_status, last_login_at, created_at
|
||||||
|
FROM users
|
||||||
|
WHERE username = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetUserByUsername(ctx context.Context, username string) (User, error) {
|
||||||
|
row := q.db.QueryRow(ctx, getUserByUsername, username)
|
||||||
|
var i User
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Username,
|
||||||
|
&i.Password,
|
||||||
|
&i.Role,
|
||||||
|
&i.DisplayName,
|
||||||
|
&i.AccountStatus,
|
||||||
|
&i.LastLoginAt,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
@@ -4,13 +4,15 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gitea.starryskymeow.cn/B309/datamarket/internal/config"
|
||||||
"gitea.starryskymeow.cn/B309/datamarket/internal/handler"
|
"gitea.starryskymeow.cn/B309/datamarket/internal/handler"
|
||||||
"gitea.starryskymeow.cn/B309/datamarket/internal/service"
|
"gitea.starryskymeow.cn/B309/datamarket/internal/service"
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
"github.com/go-chi/jwtauth/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(svc *service.Service) http.Handler {
|
func New(svc *service.Service, config *config.Config) http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
|
||||||
r.Use(middleware.RequestID)
|
r.Use(middleware.RequestID)
|
||||||
@@ -49,6 +51,15 @@ func New(svc *service.Service) http.Handler {
|
|||||||
r.Get("/validations", handler.AdminListValidations(svc))
|
r.Get("/validations", handler.AdminListValidations(svc))
|
||||||
r.Get("/orders", handler.AdminListOrders(svc))
|
r.Get("/orders", handler.AdminListOrders(svc))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.Route("/auth", func(r chi.Router) {
|
||||||
|
r.Post("/login", handler.LoginHandler(svc))
|
||||||
|
r.Group(func(r chi.Router) {
|
||||||
|
r.Use(jwtauth.Verifier(config.JWTAuth))
|
||||||
|
r.Use(jwtauth.Authenticator(config.JWTAuth))
|
||||||
|
r.Get("/me", handler.MeHandler(svc))
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|||||||
44
internal/service/auth.go
Normal file
44
internal/service/auth.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-chi/jwtauth/v5"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) VerifyUser(ctx context.Context, input VerifyUserInput) (VerifyUserResult, error) {
|
||||||
|
u, err := s.queries.GetUserByUsername(ctx, input.Username)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
return VerifyUserResult{}, notFound("user does not exist or password is wrong")
|
||||||
|
}
|
||||||
|
return VerifyUserResult{}, internalError("auth error", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(input.Password)); err != nil {
|
||||||
|
return VerifyUserResult{}, notFound("user does not exist or password is wrong")
|
||||||
|
}
|
||||||
|
|
||||||
|
// jwt
|
||||||
|
claims := make(map[string]any)
|
||||||
|
claims["userid"] = u.ID.String()
|
||||||
|
claims["username"] = u.Username
|
||||||
|
claims["role"] = u.Role
|
||||||
|
claims["account_status"] = u.AccountStatus
|
||||||
|
jwtauth.SetExpiryIn(claims, 24*time.Hour)
|
||||||
|
jwtauth.SetIssuedNow(claims)
|
||||||
|
|
||||||
|
_, token, _ := s.config.JWTAuth.Encode(claims)
|
||||||
|
|
||||||
|
return VerifyUserResult{
|
||||||
|
Token: token,
|
||||||
|
UserId: u.ID.String(),
|
||||||
|
UserName: u.Username,
|
||||||
|
DisplayName: u.DisplayName,
|
||||||
|
Role: u.Role,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
13
internal/service/auth_test.go
Normal file
13
internal/service/auth_test.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateHashedPassword(t *testing.T) {
|
||||||
|
e, _ := bcrypt.GenerateFromPassword([]byte("1145141919810"), bcrypt.DefaultCost)
|
||||||
|
log.Println(string(e))
|
||||||
|
}
|
||||||
1
internal/service/jwt_utils.go
Normal file
1
internal/service/jwt_utils.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package service
|
||||||
@@ -2,13 +2,16 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gitea.starryskymeow.cn/B309/datamarket/internal/config"
|
||||||
"gitea.starryskymeow.cn/B309/datamarket/internal/repository"
|
"gitea.starryskymeow.cn/B309/datamarket/internal/repository"
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
@@ -37,12 +40,14 @@ var (
|
|||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
queries *repository.Queries
|
queries *repository.Queries
|
||||||
|
config *config.Config
|
||||||
now func() time.Time
|
now func() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(queries *repository.Queries) *Service {
|
func New(queries *repository.Queries, cfg *config.Config) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
queries: queries,
|
queries: queries,
|
||||||
|
config: cfg,
|
||||||
now: time.Now,
|
now: time.Now,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -884,29 +889,33 @@ func timestamptzValue(value time.Time) pgtype.Timestamptz {
|
|||||||
|
|
||||||
func toAsset(asset repository.DataAsset) Asset {
|
func toAsset(asset repository.DataAsset) Asset {
|
||||||
return Asset{
|
return Asset{
|
||||||
ID: asset.ID.String(),
|
ID: asset.ID.String(),
|
||||||
AssetName: asset.AssetName,
|
AssetName: asset.AssetName,
|
||||||
AssetType: asset.AssetType,
|
AssetType: asset.AssetType,
|
||||||
Domain: asset.Domain,
|
Domain: asset.Domain,
|
||||||
ApplicationScene: toTextPointer(asset.ApplicationScene),
|
ApplicationScene: toTextPointer(asset.ApplicationScene),
|
||||||
DataDescription: asset.DataDescription,
|
DataDescription: asset.DataDescription,
|
||||||
DataScale: asset.DataScale,
|
DataScale: asset.DataScale,
|
||||||
CollectionMethod: asset.CollectionMethod,
|
CollectionMethod: asset.CollectionMethod,
|
||||||
LabelingStatus: toTextPointer(asset.LabelingStatus),
|
LabelingStatus: toTextPointer(asset.LabelingStatus),
|
||||||
UpdateFrequency: toTextPointer(asset.UpdateFrequency),
|
UpdateFrequency: toTextPointer(asset.UpdateFrequency),
|
||||||
PrivacyLevel: asset.PrivacyLevel,
|
PrivacyLevel: asset.PrivacyLevel,
|
||||||
PermissionMode: asset.PermissionMode,
|
PermissionMode: asset.PermissionMode,
|
||||||
SupportsValidation: asset.SupportsValidation,
|
SupportsValidation: asset.SupportsValidation,
|
||||||
SellerExpectedPriceMin: toNumericPointer(asset.SellerExpectedPriceMin),
|
SellerExpectedPriceMin: toNumericPointer(asset.SellerExpectedPriceMin),
|
||||||
SellerExpectedPriceMax: toNumericPointer(asset.SellerExpectedPriceMax),
|
SellerExpectedPriceMax: toNumericPointer(asset.SellerExpectedPriceMax),
|
||||||
QualityLevel: toTextPointer(asset.QualityLevel),
|
QualityLevel: toTextPointer(asset.QualityLevel),
|
||||||
ScarcityLevel: toTextPointer(asset.ScarcityLevel),
|
ScarcityLevel: toTextPointer(asset.ScarcityLevel),
|
||||||
BaseValueScore: toNumericPointer(asset.BaseValueScore),
|
BaseValueScore: toNumericPointer(asset.BaseValueScore),
|
||||||
BasePriceMin: toNumericPointer(asset.BasePriceMin),
|
BasePriceMin: toNumericPointer(asset.BasePriceMin),
|
||||||
BasePriceMax: toNumericPointer(asset.BasePriceMax),
|
BasePriceMax: toNumericPointer(asset.BasePriceMax),
|
||||||
AssetStatus: asset.AssetStatus,
|
AssetStatus: asset.AssetStatus,
|
||||||
CreatedAt: toTimePointer(asset.CreatedAt),
|
CreatedAt: toTimePointer(asset.CreatedAt),
|
||||||
UpdatedAt: toTimePointer(asset.UpdatedAt),
|
UpdatedAt: toTimePointer(asset.UpdatedAt),
|
||||||
|
AgentAssetSummary: toTextPointer(asset.AgentAssetSummary),
|
||||||
|
AgentRecommendedTasks: toStringArray(asset.AgentRecommendedTasks),
|
||||||
|
AgentRiskPerMissionAdvice: toTextPointer(asset.AgentRiskPerMissionAdvice),
|
||||||
|
AgentAssetExplanation: toTextPointer(asset.AgentAssetExplanation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -979,6 +988,14 @@ func toTextPointer(value pgtype.Text) *string {
|
|||||||
return new(value.String)
|
return new(value.String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toStringArray(value []byte) []string {
|
||||||
|
var result []string
|
||||||
|
if err := json.Unmarshal(value, &result); err != nil {
|
||||||
|
slog.Warn(err.Error(), "value", string(value))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func toNumericPointer(value pgtype.Numeric) *float64 {
|
func toNumericPointer(value pgtype.Numeric) *float64 {
|
||||||
if !value.Valid {
|
if !value.Valid {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ type Asset struct {
|
|||||||
AssetStatus string `json:"asset_status"`
|
AssetStatus string `json:"asset_status"`
|
||||||
CreatedAt *time.Time `json:"created_at,omitempty"`
|
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||||
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
|
// 智能助手对当前资产的简短画像总结
|
||||||
|
AgentAssetSummary *string `json:"agent_asset_summary"`
|
||||||
|
// 推荐的适用任务列表
|
||||||
|
AgentRecommendedTasks []string `json:"agent_recommended_tasks"`
|
||||||
|
// 当前资产更适合的权限与风险建议
|
||||||
|
AgentRiskPerMissionAdvice *string `json:"agent_risk_per_mission_advice"`
|
||||||
|
// 为什么该资产当前基础价值较高/中/低
|
||||||
|
AgentAssetExplanation *string `json:"agent_asset_explanation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AssetCreateInput struct {
|
type AssetCreateInput struct {
|
||||||
@@ -176,17 +184,20 @@ type AssetService interface {
|
|||||||
GetAsset(context.Context, string) (Asset, error)
|
GetAsset(context.Context, string) (Asset, error)
|
||||||
ListAssets(context.Context, AssetListInput) (ListResult[Asset], error)
|
ListAssets(context.Context, AssetListInput) (ListResult[Asset], error)
|
||||||
UpdateAssetStatus(context.Context, string, StatusUpdate) (AssetStatusResult, error)
|
UpdateAssetStatus(context.Context, string, StatusUpdate) (AssetStatusResult, error)
|
||||||
|
//DeleteAsset(context.Context, string) (AssetStatusResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type PricingService interface {
|
type PricingService interface {
|
||||||
CreatePricing(context.Context, PricingCreateInput) (Pricing, error)
|
CreatePricing(context.Context, PricingCreateInput) (Pricing, error)
|
||||||
GetPricing(context.Context, string) (Pricing, error)
|
GetPricing(context.Context, string) (Pricing, error)
|
||||||
|
//DeletePricing(context.Context, string) (Pricing, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidationService interface {
|
type ValidationService interface {
|
||||||
CreateValidation(context.Context, ValidationCreateInput) (ValidationCreateResult, error)
|
CreateValidation(context.Context, ValidationCreateInput) (ValidationCreateResult, error)
|
||||||
GetValidation(context.Context, string) (Validation, error)
|
GetValidation(context.Context, string) (Validation, error)
|
||||||
ListValidations(context.Context, ValidationListInput) (ListResult[Validation], error)
|
ListValidations(context.Context, ValidationListInput) (ListResult[Validation], error)
|
||||||
|
//DeleteValidation(context.Context, string) (Validation, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderService interface {
|
type OrderService interface {
|
||||||
@@ -194,4 +205,22 @@ type OrderService interface {
|
|||||||
GetOrder(context.Context, string) (Order, error)
|
GetOrder(context.Context, string) (Order, error)
|
||||||
ListOrders(context.Context, OrderListInput) (ListResult[Order], error)
|
ListOrders(context.Context, OrderListInput) (ListResult[Order], error)
|
||||||
UpdateOrderStatus(context.Context, string, StatusUpdate) (OrderCreateResult, error)
|
UpdateOrderStatus(context.Context, string, StatusUpdate) (OrderCreateResult, error)
|
||||||
|
//DeleteOrder(context.Context, string) (Order, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifyUserInput struct {
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifyUserResult struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
UserId string `json:"user_id"`
|
||||||
|
UserName string `json:"user_name"`
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthService interface {
|
||||||
|
VerifyUser(context.Context, VerifyUserInput) (VerifyUserResult, error)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user