Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
a3def8f
ce feat: implement unmasking workflow use cases and data structures
Seechi-Yolo Apr 22, 2026
447043a
ce refactor: move Confidence type and constants to a new file for bet…
Seechi-Yolo Apr 22, 2026
a22b3e9
ce feat: implement DownloadOriginalDataExportWorkflow functionality
Seechi-Yolo Apr 22, 2026
6f86d9a
ce feat: DMSService: add UnmaskingWorkflowUsecase field for export or…
LordofAvernus May 11, 2026
020b415
ce feat: enhance SQL result masking with project UID support
Seechi-Yolo Apr 22, 2026
32faa88
ce feat: implement unmasking workflow endpoints and middleware
Seechi-Yolo Apr 22, 2026
d522ad0
ce feat: enhance DataExportWorkflowUsecase with projectUID and unmask…
LordofAvernus May 11, 2026
1acb95e
ce feat: DMSService: align UnmaskingWorkflowUsecase field type (CE)
LordofAvernus May 11, 2026
8d984e2
ce feat: add ListTableColumns method for DMSService
Seechi-Yolo Apr 22, 2026
399d69c
ce feat: add unmasking workflow messages for English and Chinese locales
Seechi-Yolo Apr 22, 2026
4dda14a
ce feat: add build verification script for multiple edition combinations
Seechi-Yolo Apr 22, 2026
607c58c
fix: update ListMaskingRulesReq to clarify projectUid parameter usage
LordofAvernus May 9, 2026
4d0a7ed
refactor: update ApproveUnmaskingWorkflowReq to make approve_unmaskin…
LordofAvernus May 9, 2026
afb696e
refactor: improve SQL audit middleware error handling and request par…
LordofAvernus May 9, 2026
d6d303f
refactor: streamline Cloudbeaver and DataExportWorkflow usecases by r…
LordofAvernus May 11, 2026
162dc22
fix(api): align data export and db structure column contracts with EE
LordofAvernus May 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ dms_unit_test_clean:
dms_test_dms:
go test -v -p 1 ./internal/dms/...

# 提交前校验:社区版 / 试用版 / 企业版 / DMS 企业版 四种 GO_BUILD_TAGS 组合下均能 make install
verify_edition_builds:
bash ./scripts/verify_build_editions.sh

############################### generate ##################################
gen_repo_fields:
go run ./internal/dms/cmd/gencli/gencli.go -d generate-node-repo-fields ./internal/dms/storage/model/ ./internal/dms/biz/
Expand Down
5 changes: 5 additions & 0 deletions api/dms/service/v1/data_export_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package v1
import (
"time"

maskingBiz "github.com/actiontech/dms/internal/data_masking/biz"
base "github.com/actiontech/dms/pkg/dms-common/api/base/v1"
)

Expand Down Expand Up @@ -127,6 +128,10 @@ type ListDataExportTaskSQL struct {
ExportSQLType string `json:"export_sql_type"`
AuditLevel string `json:"audit_level"`
AuditSQLResult []AuditSQLResult `json:"audit_sql_result"`
// 血缘分析快照(与查看原文工单 SQL 详情字段语义一致)
LineageAnalysisSnapshot *maskingBiz.AnalyzeResult `json:"lineage_analysis_snapshot,omitempty"`
// 脱敏配置快照
MaskingConfigSnapshot []*maskingBiz.ColumnMaskingConfig `json:"masking_config_snapshot,omitempty"`
}
type AuditSQLResult struct {
Level string `json:"level" example:"warn"`
Expand Down
15 changes: 15 additions & 0 deletions api/dms/service/v1/data_export_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,21 @@ type ExportDataExportWorkflowReq struct {
DataExportWorkflowUid string `param:"data_export_workflow_uid" json:"data_export_workflow_uid" validate:"required"`
}

// swagger:parameters DownloadOriginalDataExportWorkflow
type DownloadOriginalDataExportWorkflowReq struct {
// project id
// Required: true
// in:path
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// Required: true
// in:path
DataExportWorkflowUid string `param:"data_export_workflow_uid" json:"data_export_workflow_uid" validate:"required"`
// 已批准的查看原文工单 UID
// Required: true
// in:query
UnmaskingWorkflowUid string `query:"unmasking_workflow_uid" json:"unmasking_workflow_uid" validate:"required"`
}

type RejectDataExportWorkflowPayload struct {
// Required: true
Reason string `json:"reason" validate:"required"`
Expand Down
36 changes: 36 additions & 0 deletions api/dms/service/v1/db_structure_columns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package v1

import (
base "github.com/actiontech/dms/pkg/dms-common/api/base/v1"
)

// swagger:parameters ListTableColumns
type ListTableColumnsReq struct {
// Required: true
// in:path
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// Required: true
// in:path
DBServiceUid string `param:"db_service_uid" json:"db_service_uid" validate:"required"`
// Required: true
// in:path
SchemaName string `param:"schema_name" json:"schema_name" validate:"required"`
// Required: true
// in:path
TableName string `param:"table_name" json:"table_name" validate:"required"`
}

// swagger:model ListTableColumnsReply
type ListTableColumnsReply struct {
Data []*TableColumn `json:"data"`
// Generic reply
base.GenericResp
}

// swagger:model TableColumn
type TableColumn struct {
Name string `json:"name"`
Type string `json:"type"`
Comment string `json:"comment"`
Nullable bool `json:"nullable"`
}
5 changes: 2 additions & 3 deletions api/dms/service/v1/masking.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import (

// swagger:parameters ListMaskingRules
type ListMaskingRulesReq struct {
// project uid
// project uid(项目路径下由 path 注入;全局 GET /v1/dms/masking/rules 可不传,仅返回内置规则)
// in: path
// Required: true
// Example: "project_uid"
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
ProjectUid string `param:"project_uid" query:"project_uid" json:"project_uid"`
// 规则来源筛选: builtin 或 custom,为空时返回全部
// in: query
// Example: "custom"
Expand Down
261 changes: 261 additions & 0 deletions api/dms/service/v1/unmasking_workflow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
package v1

import (
"github.com/actiontech/dms/internal/data_masking/biz"
base "github.com/actiontech/dms/pkg/dms-common/api/base/v1"
)

// swagger:parameters ListUnmaskingWorkflows
type ListUnmaskingWorkflowsReq struct {
// project id
// Required: true
// in: path
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// the maximum count of workflows to be returned
// in: query
// Required: true
PageSize uint32 `query:"page_size" json:"page_size" validate:"required"`
// the offset of workflows to be returned, default is 0
// in: query
PageIndex uint32 `query:"page_index" json:"page_index"`
// filter the approval status
// in: query
FilterByApprovalStatus biz.UnmaskingWorkflowApprovalStatus `query:"filter_by_approval_status" json:"filter_by_approval_status"`
// filter the usage status
// in: query
FilterByUsageStatus biz.UnmaskingWorkflowUsageStatus `query:"filter_by_usage_status" json:"filter_by_usage_status"`
// filter db_service id
// in: query
FilterByDBServiceUid string `query:"filter_by_db_service_uid" json:"filter_by_db_service_uid"`
}

// swagger:model ListUnmaskingWorkflowsReply
type ListUnmaskingWorkflowsReply struct {
Data []*UnmaskingWorkflowListItem `json:"data"`
Total int64 `json:"total_nums"`
// Generic reply
base.GenericResp
}

// swagger:model UnmaskingWorkflowListItem
type UnmaskingWorkflowListItem struct {
// 申请编号
WorkflowID string `json:"workflow_id"`
// 申请人用户名
ApplicantName string `json:"applicant_name"`
// 申请时间 (RFC3339)
CreatedAt string `json:"created_at" example:"2024-01-15T10:30:00Z"`
// 数据源实例名称
DatasourceName string `json:"datasource_name"`
// 数据源实例ID
DatasourceUid string `json:"datasource_uid"`
// 来源类型
SourceType biz.UnmaskingWorkflowSourceType `json:"source_type" validate:"oneof=data_export sql_workbench"`
// 来源对象UID
SourceUID string `json:"source_uid"`
// 审批状态
ApprovalStatus biz.UnmaskingWorkflowApprovalStatus `json:"approval_status" validate:"oneof=pending approved rejected cancelled"`
// 使用情况
UsageStatus biz.UnmaskingWorkflowUsageStatus `json:"usage_status" validate:"oneof=unviewed viewed"`
// 过期时间 (RFC3339)
ExpireTime string `json:"expire_time" example:"2024-01-16T10:30:00Z"`
// 申请理由
ApplyReason string `json:"apply_reason"`
// 当前待处理人
CurrentAssignees []*UidWithName `json:"current_assignees"`
}

// swagger:model CreateUnmaskingWorkflowReq
type CreateUnmaskingWorkflowReq struct {
// swagger:ignore
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// in: body
// Required: true
UnmaskingWorkflow *CreateUnmaskingWorkflow `json:"unmasking_workflow" validate:"required"`
}

// swagger:model CreateUnmaskingWorkflow
type CreateUnmaskingWorkflow struct {
// 数据源 UID
DatasourceUID string `json:"datasource_uid" validate:"required"`
// SQL 默认 schema
DefaultSchema string `json:"default_schema" validate:"required"`
// 来源类型
SourceType biz.UnmaskingWorkflowSourceType `json:"source_type" validate:"required,oneof=data_export sql_workbench"`
// 来源对象 UID (如数据导出任务 UID)
SourceUID string `json:"source_uid"`
// 申请理由
ApplyReason string `json:"apply_reason" validate:"required"`
// 待脱敏 SQL 列表
UnmaskingSQLs []CreateUnmaskingSQLItem `json:"unmasking_sqls" validate:"required,gt=0"`
}

// swagger:model CreateUnmaskingSQLItem
type CreateUnmaskingSQLItem struct {
// 来源侧 SQL 索引 id(如数据导出记录中的 SQL 序号);与 SQL 工作台场景的索引约定可能不同,需结合 source_type、source_uid 解析
SQLIndexID string `json:"sql_index_id" validate:"required"`
// 原始 SQL 内容
SQLContent string `json:"sql_content" validate:"required"`
}

// swagger:model CreateUnmaskingWorkflowReply
type CreateUnmaskingWorkflowReply struct {
Data *CreateUnmaskingWorkflowReplyData `json:"data"`
// Generic reply
base.GenericResp
}

// swagger:model CreateUnmaskingWorkflowReplyData
type CreateUnmaskingWorkflowReplyData struct {
WorkflowID string `json:"workflow_id"`
}

// swagger:parameters GetUnmaskingWorkflow
type GetUnmaskingWorkflowReq struct {
// project id
// Required: true
// in: path
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// in: path
// Required: true
WorkflowID string `param:"workflow_id" json:"workflow_id" validate:"required"`
}

// swagger:model GetUnmaskingWorkflowReply
type GetUnmaskingWorkflowReply struct {
Data *UnmaskingWorkflowDetail `json:"data"`
// Generic reply
base.GenericResp
}

// swagger:model UnmaskingWorkflowDetail
type UnmaskingWorkflowDetail struct {
UnmaskingWorkflowListItem
// 驳回理由 (整单驳回时)
RejectReason string `json:"reject_reason"`
// 当前待处理人
CurrentAssignees []*UidWithName `json:"current_assignees"`
// SQL 详情列表
UnmaskingSQLs []*UnmaskingSQLDetail `json:"unmasking_sqls"`
// 操作日志
OperationLogs []*UnmaskingOperationLogItem `json:"operation_logs"`
}

// swagger:model UnmaskingSQLDetail
type UnmaskingSQLDetail struct {
// SQL 详情 UID
UID string `json:"uid"`
// 来源侧 SQL 索引 id
SQLIndexID string `json:"sql_index_id"`
// 原始 SQL 内容
SQLContent string `json:"sql_content"`
// 脱敏配置快照
MaskingConfigSnapshot []*biz.ColumnMaskingConfig `json:"masking_config_snapshot,omitempty"`
// 血缘分析快照
LineageAnalysisSnapshot *biz.AnalyzeResult `json:"lineage_analysis_snapshot,omitempty"`

UnmaskingSQLPreviewData
}

// swagger:model UnmaskingSQLPreviewData
type UnmaskingSQLPreviewData struct {
// 脱敏后的预览数据 (普通用户仅能看到此数据)
MaskedData *SQLQueryResult `json:"masked_data"`
// 原始采样数据 (仅有权限的审核人能看到)
OriginalData *SQLQueryResult `json:"original_data"`
}

// swagger:model SQLQueryResultRow
// SQLQueryResultRow 一行数据;每个元素为单元格的字符串形式(与 columns 顺序一致)。
type SQLQueryResultRow []string

// swagger:model SQLQueryResult
type SQLQueryResult struct {
// 列名列表
Columns []string `json:"columns"`
// 数据行列表 (每一行的数据顺序与 Columns 一致)
Rows []SQLQueryResultRow `json:"rows"`
// 总行数
RowCount int `json:"row_count"`
}

// swagger:model UnmaskingOperationLogItem
type UnmaskingOperationLogItem struct {
// 操作人 UID
OperatorUID string `json:"operator_uid"`
// 操作人姓名
OperatorName string `json:"operator_name"`
// 操作动作
Action biz.UnmaskingAction `json:"action"`
// 操作时间 (RFC3339)
ActionTime string `json:"action_time"`
// 额外信息 (如拦截原因)
ExtraMessage string `json:"extra_message"`
}

// swagger:model ApproveUnmaskingWorkflowReq
type ApproveUnmaskingWorkflowReq struct {
// swagger:ignore
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// in: path
// Required: true
// swagger:ignore
WorkflowID string `param:"workflow_id" json:"workflow_id" validate:"required"`
// in: body
ApproveUnmaskingWorkflow *ApproveUnmaskingWorkflow `json:"approve_unmasking_workflow,omitempty"`
}

// swagger:model ApproveUnmaskingWorkflow
type ApproveUnmaskingWorkflow struct {
// 审批理由 非必须
ApproveReason string `json:"approve_reason"`
}

// swagger:model ApproveUnmaskingWorkflowReply
type ApproveUnmaskingWorkflowReply struct {
// Generic reply
base.GenericResp
}

// swagger:model RejectUnmaskingWorkflowReq
type RejectUnmaskingWorkflowReq struct {
// swagger:ignore
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// in: path
// Required: true
// swagger:ignore
WorkflowID string `param:"workflow_id" json:"workflow_id" validate:"required"`
// in: body
// Required: true
RejectUnmaskingWorkflow *RejectUnmaskingWorkflow `json:"reject_unmasking_workflow" validate:"required"`
}

// swagger:model RejectUnmaskingWorkflow
type RejectUnmaskingWorkflow struct {
// 驳回理由
// Required: true
RejectReason string `json:"reject_reason" validate:"required"`
}

// swagger:model RejectUnmaskingWorkflowReply
type RejectUnmaskingWorkflowReply struct {
// Generic reply
base.GenericResp
}

// swagger:parameters CancelUnmaskingWorkflow
type CancelUnmaskingWorkflowReq struct {
// project id
// Required: true
// in: path
ProjectUid string `param:"project_uid" json:"project_uid" validate:"required"`
// in: path
// Required: true
WorkflowID string `param:"workflow_id" json:"workflow_id" validate:"required"`
}

// swagger:model CancelUnmaskingWorkflowReply
type CancelUnmaskingWorkflowReply struct {
// Generic reply
base.GenericResp
}
Loading