feat: add operator and business reference fields to tenant ledgers
- Added `operator_user_id`, `biz_ref_type`, and `biz_ref_id` fields to the TenantLedger model for enhanced auditing and traceability. - Updated the tenant ledgers query generation to include new fields. - Introduced new API endpoint for retrieving tenant ledger records with filtering options based on the new fields. - Enhanced Swagger documentation to reflect the new endpoint and its parameters. - Created DTOs for admin ledger filtering and item representation. - Implemented the admin ledger retrieval logic in the tenant service. - Added database migration scripts to introduce new fields and indexes for efficient querying.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE tenant_ledgers
|
||||
ADD COLUMN IF NOT EXISTS operator_user_id bigint,
|
||||
ADD COLUMN IF NOT EXISTS biz_ref_type varchar(32),
|
||||
ADD COLUMN IF NOT EXISTS biz_ref_id bigint;
|
||||
|
||||
-- tenant_ledgers.operator_user_id:操作者(谁触发该流水)
|
||||
-- 用途:用于审计与风控追溯(例如后台代充值/代退款/调账等)。
|
||||
COMMENT ON COLUMN tenant_ledgers.operator_user_id IS '操作者用户ID:谁触发该流水(admin/buyer/system);用于审计与追责;可为空(历史数据或无法识别时)';
|
||||
|
||||
-- tenant_ledgers.biz_ref_type/biz_ref_id:业务引用(幂等与追溯)
|
||||
-- 用途:在 idempotency_key 之外提供结构化引用(例如 order/refund/topup 等),便于报表与按业务对象追溯。
|
||||
COMMENT ON COLUMN tenant_ledgers.biz_ref_type IS '业务引用类型:order/refund/topup/etc;与 biz_ref_id 组成可选的结构化幂等/追溯键';
|
||||
COMMENT ON COLUMN tenant_ledgers.biz_ref_id IS '业务引用ID:与 biz_ref_type 配合使用(例如 orders.id);用于对账与审计';
|
||||
|
||||
-- 索引:按操作者检索敏感操作流水(后台审计用)。
|
||||
CREATE INDEX IF NOT EXISTS ix_tenant_ledgers_tenant_operator ON tenant_ledgers(tenant_id, operator_user_id);
|
||||
|
||||
-- 索引:按业务引用快速定位同一业务对象的流水集合。
|
||||
CREATE INDEX IF NOT EXISTS ix_tenant_ledgers_tenant_biz_ref ON tenant_ledgers(tenant_id, biz_ref_type, biz_ref_id);
|
||||
|
||||
-- 结构化幂等(可选):同一业务引用在同一流水类型下只能出现一条。
|
||||
-- 说明:biz_ref_* 允许为空;仅当两者都非空时才参与唯一性约束。
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_tenant_ledgers_tenant_biz_ref_type_id_type
|
||||
ON tenant_ledgers(tenant_id, biz_ref_type, biz_ref_id, type)
|
||||
WHERE biz_ref_type IS NOT NULL AND biz_ref_id IS NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS ux_tenant_ledgers_tenant_biz_ref_type_id_type;
|
||||
DROP INDEX IF EXISTS ix_tenant_ledgers_tenant_biz_ref;
|
||||
DROP INDEX IF EXISTS ix_tenant_ledgers_tenant_operator;
|
||||
|
||||
ALTER TABLE tenant_ledgers
|
||||
DROP COLUMN IF EXISTS biz_ref_id,
|
||||
DROP COLUMN IF EXISTS biz_ref_type,
|
||||
DROP COLUMN IF EXISTS operator_user_id;
|
||||
-- +goose StatementEnd
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
-- 修正:biz_ref_type/biz_ref_id 在 Go 模型侧为 string/int64(非指针),空值会写入 ''/0,
|
||||
-- 若唯一索引仅判断 NOT NULL,会导致大量流水写入冲突。
|
||||
-- 约束策略:仅当 biz_ref_type 非空 且 biz_ref_id > 0 时才参与唯一性约束。
|
||||
DROP INDEX IF EXISTS ux_tenant_ledgers_tenant_biz_ref_type_id_type;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_tenant_ledgers_tenant_biz_ref_type_id_type
|
||||
ON tenant_ledgers(tenant_id, biz_ref_type, biz_ref_id, type)
|
||||
WHERE biz_ref_type IS NOT NULL AND biz_ref_type <> '' AND biz_ref_id IS NOT NULL AND biz_ref_id <> 0;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS ux_tenant_ledgers_tenant_biz_ref_type_id_type;
|
||||
|
||||
-- Down 回滚为“仅判断 NOT NULL”的版本(不建议在线上使用该版本)。
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_tenant_ledgers_tenant_biz_ref_type_id_type
|
||||
ON tenant_ledgers(tenant_id, biz_ref_type, biz_ref_id, type)
|
||||
WHERE biz_ref_type IS NOT NULL AND biz_ref_id IS NOT NULL;
|
||||
-- +goose StatementEnd
|
||||
|
||||
Reference in New Issue
Block a user