当前位置: 首页 > ai >正文

Coze源码分析-资源库-删除提示词-后端源码

前言

本文将深入分析Coze Studio项目中用户删除提示词功能的后端实现。当用户登录Coze平台后,点击"资源库" → 在表格中点击要删除的提示词行最右边的"…"号 → 最后点击弹出菜单中的"删除"菜单,触发的是一个完整的提示词资源删除流程。提示词作为AI应用开发的核心组件,其删除操作涉及权限验证、数据清理和多个后端服务层的协同工作。通过源码解读,我们将深入理解提示词删除功能在整个Coze Studio后端架构中的设计思路和技术实现细节。

项目架构概览

提示词删除功能架构设计

Coze Studio的提示词删除功能采用了经典的分层架构模式,专门针对提示词资源的安全删除进行了优化设计。整个架构围绕提示词的权限验证、删除操作、数据清理和事件通知展开:

┌─────────────────────────────────────────────────────────────┐
│                    IDL接口定义层                             │
│  ┌─────────────┐  ┌─────────────┐    ┌─────────────┐        │
│  │ base.thrift │  │playground.  │    │ api.thrift  │        │
│  │             │  │thrift       │    │             │        │
│  └─────────────┘  └─────────────┘    └─────────────┘        │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                    API网关层                                 │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │   Handler   │  │   Router    │  │ Middleware  │          │
│  │   处理器     │  │   路由      │  │   中间件     │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
│└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   应用服务层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              PlaygroundService                      │    │
│  │             DeletePromptResource                    │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   领域服务层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                 promptService                       │    │
│  │                ┌─────────────────┐                  │    │
│  │                │DeletePrompt     │                  │    │
│  │                │Resource         │                  │    │
│  │                └─────────────────┘                  │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   数据访问层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              PromptRepository                       │    │
│  │  ┌──── ─────── ──── ──┐  ┌─────────────────────────┐│    │
│  │  │PromptDAO           │  │prompt_resource.gen.go   ││    │
│  │  │DeletePromptResource│  │GORM Generated Code      ││    │
│  │  └──── ─────── ─── ───┘  └─────────────────────────┘│    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   基础设施层                                 │
│              ┌─ ─ ─── ─ ── ── ─ ─ ─┐                        │
│              │       gorm.DB       │                        │
│              │ es.Client redisImpl │                        │
│              └── ─ ── ── ─ ── ── ─ ┘                        │
└─────────────────────────────────────────────────────────────┘↓
┌─────────────────────────────────────────────────────────────┐
│                   存储服务层                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │       MySQL数据库       Redis数据库                  │    │
│  │            ElasticSearch数据库                      │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

提示词删除流程核心组件

API路由映射:

  • POST /api/playground_api/delete_prompt_resource - 删除提示词

核心数据模型:

type PromptResource struct {ID          int64     `gorm:"primaryKey;autoIncrement"`SpaceID     int64     `gorm:"not null;index"`Name        string    `gorm:"size:255;not null"`Description string    `gorm:"type:text"`PromptText  string    `gorm:"type:longtext;not null"`Status      int32     `gorm:"default:1"`CreatorID   int64     `gorm:"not null;index"`CreatedAt   time.Time `gorm:"autoCreateTime"`UpdatedAt   time.Time `gorm:"autoUpdateTime"`
}

1. IDL接口定义层

IDL基础类型定义(base.thrift)

文件位置:idl/base.thrift
核心代码:

namespace py base
namespace go base
namespace java com.bytedance.thrift.basestruct TrafficEnv {1: bool   Open = false,2: string Env  = ""   ,
}struct Base {1:          string             LogID      = "",2:          string             Caller     = "",3:          string             Addr       = "",4:          string             Client     = "",5: optional TrafficEnv         TrafficEnv     ,6: optional map<string,string> Extra          ,
}struct BaseResp {1:          string             StatusMessage = "",2:          i32                StatusCode    = 0 ,3: optional map<string,string> Extra             ,
}

文件作用:
定义了Coze Studio项目中所有接口的基础数据结构,作为其他IDL文件的依赖基础。

提示词资源接口定义(prompt_resource.thrift)

文件位置:idl/playground/prompt_resource.thrift

当Coze用户登录平台后点击"资源库" → 在表格中点击要删除的提示词行最右边的"…"号 → 最后点击弹出菜单中的"删除"菜单时,前端会调用提示词删除相关的接口。该文件定义了提示词资源删除的核心数据结构和接口。

核心数据结构 - PromptResource
struct PromptResource {1: optional i64 ID (agw.js_conv="str",api.js_conv="true",api.body="id")2: optional i64 SpaceID (agw.js_conv="str",api.js_conv="true",api.body="space_id")3: optional string Name (api.body="name")4: optional string Description (api.body="description")5: optional string PromptText (api.body="prompt_text")
}
删除提示词接口
struct DeletePromptResourceRequest {1: required i64 PromptResourceID (agw.js_conv="str",api.js_conv="true",api.body="prompt_resource_id")255: base.Base Base (api.none="true")
}struct DeletePromptResourceResponse {253: required i64    code254: required string msg255: required base.BaseResp BaseResp
}

删除提示词服务接口(playground.thrift)

文件位置:idl/playground/playground.thrift

该文件定义了Playground服务的核心接口,包括提示词资源管理的服务接口定义。

PlaygroundService服务定义
service PlaygroundService {prompt_resource.DeletePromptResourceResponse DeletePromptResource(1:prompt_resource.DeletePromptResourceRequest request)(api.post='/api/playground_api/delete_prompt_resource', api.category="prompt_resource",agw.preserve_base="true")// 其他服务接口...
}

提示词接口路由映射说明:

  • DeletePromptResource: POST /api/playground_api/delete_prompt_resource - 删除提示词

接口功能说明:

  • 数据结构设计: PromptResource包含ID、空间ID、名称、描述和提示词文本等核心字段
  • CRUD操作: 支持完整的创建、读取、更新、删除操作

IDL主API服务聚合文件(api.thrift)

文件位置:idl/api.thrift

该文件是整个Coze项目的API服务聚合入口点,负责将所有业务模块的IDL服务定义统一聚合,为代码生成工具提供完整的服务接口定义。

核心代码:


include "./playground/playground.thrift"namespace go coze// 资源库核心服务聚合
service PlaygroundService extends playground.PlaygroundService {}
// 其他业务服务聚合

资源库接口聚合说明:
通过 service PlaygroundService extends playground.PlaygroundService {} 聚合定义,api.thrift将playground.thrift中定义的所有资源库相关接口统一暴露.

2. API网关层

接口定义-playground.go文件详细分析

文件位置:backend\api\model\playground\playground.go
核心代码:

type PlaygroundService interface {DeletePromptResource(ctx context.Context, request *DeletePromptResourceRequest) (r *DeletePromptResourceResponse, err error)}
提示词相关接口模型定义

当Coze用户登录平台后点击"资源库" → 在表格中点击要删除的提示词行最右边的"…"号 → 最后点击弹出菜单中的"删除"菜单时,前端会调用提示词删除接口来删除指定的提示词资源。

DeletePromptResourceRequest 删除提示词请求结构体

type DeletePromptResourceRequest struct {// 要删除的提示词资源IDPromptResourceID int64      `thrift:"PromptResourceID,1,required" form:"prompt_resource_id,required" json:"prompt_resource_id,required" query:"prompt_resource_id,required"`Base             *base.Base `thrift:"Base,255" form:"Base" json:"Base" query:"Base"`
}
接口功能说明

业务功能

  • 提示词删除:根据提示词资源ID删除指定的提示词资源
  • 权限验证:确保只有有权限的用户才能删除提示词
  • 数据清理:删除提示词时同时清理相关的依赖数据
  • 操作审计:记录删除操作的日志和审计信息

技术特性

  • 类型安全:使用强类型定义确保提示词数据的一致性
  • 多格式支持:支持thrift、form、json、query等多种序列化格式
  • 参数验证:通过required标记确保必要参数的完整性
  • 统一响应:遵循统一的响应格式规范
  • 游标分页:使用cursor机制实现高效的提示词列表分页

文件作用
由thriftgo自动生成的Go代码文件,基于playground.thrift IDL定义生成对应的Go结构体和接口,提供类型安全的提示词API模型。该文件实现了完整的Thrift RPC通信机制,包括客户端调用、服务端处理、序列化/反序列化等功能,确保了提示词服务间的可靠通信。

提示词接口处理器实现

文件位置:backend/api/handler/coze/playground_service.go

该文件包含了用户登录后点击"资源库" → 在表格中点击要删除的提示词行最右边的"…"号 → 最后点击弹出菜单中的"删除"菜单功能的核心API接口处理器,主要负责处理提示词资源的删除功能。

核心代码:

// DeletePromptResource .
// @router /api/playground_api/delete_prompt_resource [POST]
func DeletePromptResource(ctx context.Context, c *app.RequestContext) {var err errorvar req playground.DeletePromptResourceRequesterr = c.BindAndValidate(&req)if err != nil {invalidParamRequestResponse(c, err.Error())return}resp, err := prompt.PromptSVC.DeletePromptResource(ctx, &req)if err != nil {internalServerErrorResponse(ctx, c, err)return}c.JSON(consts.StatusOK, resp)
}

实现功能

  1. 请求绑定:使用Hertz框架的BindAndValidate方法自动绑定和验证请求参数
  2. 业务调用:调用prompt.PromptSVC服务层的DeletePromptResource方法处理提示词删除业务逻辑
  3. 错误处理:统一的错误处理机制,包括参数错误和内部服务错误
  4. 响应返回:以JSON格式返回标准化的删除操作响应结果

参数校验逻辑

  • 自动绑定验证:使用Hertz框架的BindAndValidate方法自动完成参数绑定和基础验证
  • 请求格式验证:确保请求参数符合定义的数据结构要求
  • 业务逻辑委托:将具体的权限验证和存在性检查委托给应用服务层处理

路由注册实现-api.go文件详细分析

文件位置:backend/api/router/coze/api.go
核心代码:

// Code generated by hertz generator. DO NOT EDIT.
func Register(r *server.Hertz) {root := r.Group("/", rootMw()...){_api := root.Group("/api", _apiMw()...){_playground_api := _api.Group("/playground_api", _playground_apiMw()...)_playground_api.POST("/delete_prompt_resource", append(_deletepromptresourceMw(), coze.DeletePromptResource)...)// ... 其他playground相关路由}}
}

文件作用:
此文件是Coze Studio后端的核心路由注册文件,由hertz generator自动生成,负责将所有HTTP API接口路由与对应的处理函数进行绑定和注册。该文件构建了完整的RESTful API路由树结构。对于提示词模块,构建了层次化的路由结构:

/api/playground_api/delete_prompt_resource [POST]
├── rootMw() # 根级中间件
├── _apiMw() # API组中间件
├── _playground_apiMw() # playground API组中间件
├── _deletepromptresourceMw() # 删除提示词接口中间件
└── coze.DeletePromptResource # 处理函数

中间件系统-middleware.go文件详细分析

文件位置:backend/api/router/coze/middleware.go
核心代码:

func _playground_apiMw() []app.HandlerFunc {// playground API模块中间件return nil
}func _deletepromptresourceMw() []app.HandlerFunc {// 删除提示词接口专用中间件return nil
}

文件作用:

  1. 中间件函数定义:为提示词模块的每个路由组和特定路由提供中间件挂载点
  2. 路由层级管理:按照路由的层级结构组织中间件函数,支持三层中间件架构
  3. 开发者扩展接口:提供统一的接口供开发者添加自定义中间件逻辑,如认证、鉴权、限流、日志记录等
  4. 粒度化控制:支持从模块级别到接口级别的细粒度中间件控制
  5. 功能扩展:可在此处添加提示词访问权限检查、请求日志记录、性能监控等功能

API网关层Restful接口路由-Coze+Hertz

Hertz为每个HTTP方法维护独立的路由树,通过分组路由的方式构建层次化的API结构。对于提示词相关接口的完整路由链路:

/api/playground_api/delete_prompt_resource [POST]
├── rootMw() # 根级中间件(全局认证、CORS等)
├── _apiMw() # API组中间件(API版本控制、通用验证)
├── _playground_apiMw() # playground API组中间件(playground相关权限检查)
├── _deletepromptresourceMw() # 接口级中间件(删除提示词特定逻辑)
└── coze.DeletePromptResource # 处理函数

这种设计的优势:

  • 层次化管理:不同层级的中间件处理不同的关注点,职责清晰
  • 可扩展性:每个层级都可以独立添加中间件,不影响其他层级
  • 性能优化:中间件按需执行,避免不必要的开销
  • 多HTTP方法支持:支持POST和GET请求的JSON数据绑定和验证
  • 提示词管理:专门为提示词功能设计的路由结构,支持完整的CRUD操作
  • 统一错误处理:在中间件层面实现统一的错误处理和响应格式化
  • 安全控制:多层级的安全检查,确保提示词访问的安全性

3. 应用服务层

PromptApplicationService初始化

文件位置:backend/application/prompt/prompt.go

PromptApplicationService是提示词应用服务层的核心组件,专门负责处理提示词资源的删除等业务逻辑,是连接API层和领域层的重要桥梁。在用户点击"资源库" → 在表格中点击要删除的提示词行最右边的"…"号 → 最后点击弹出菜单中的"删除"菜单的场景中,该服务承担着核心的删除业务处理职责。

服务结构定义

文件位置:backend/application/prompt/prompt.go

type PromptApplicationService struct {DomainSVC prompt.Prompteventbus  search.ResourceEventBus
}var PromptSVC = &PromptApplicationService{}
服务初始化实现

文件位置:backend/application/prompt/init.go

// InitService 初始化提示词应用服务,注入领域服务依赖
func InitService(repo repository.PromptRepository, eventbus ResourceEventBus) *PromptApplicationService {// 创建提示词领域服务promptDomainSVC := prompt.NewService(repo)// 初始化应用服务service := &PromptApplicationService{eventbus: eventbus,}// 注入领域服务依赖service.PromptSVC.DomainSVC = promptDomainSVCreturn service
}

服务初始化特点

  1. 依赖注入:通过Repository接口注入数据访问能力,实现依赖倒置
  2. 事件驱动架构:集成资源事件总线,支持异步事件处理和数据同步
  3. 领域服务协调:封装提示词领域服务,提供应用层的业务编排
  4. 轻量级设计:专注于提示词业务,结构简洁清晰

删除提示词核心实现

DeletePromptResource方法详解

文件位置:backend/application/prompt/prompt.go

当用户在资源库中点击要删除的提示词行最右边的"…"号,然后点击弹出菜单中的"删除"菜单时,前端会调用DeletePromptResource方法来删除指定的提示词资源。

func (p *PromptApplicationService) DeletePromptResource(ctx context.Context, req *playground.DeletePromptResourceRequest) (resp *playground.DeletePromptResourceResponse, err error) {uid := ctxutil.GetUIDFromCtx(ctx)if uid == nil {return nil, errorx.New(errno.ErrPromptPermissionCode, errorx.KV("msg", "no session data provided"))}promptInfo, err := p.DomainSVC.GetPromptResource(ctx, req.GetPromptResourceID())if err != nil {return nil, err}if promptInfo.CreatorID != *uid {return nil, errorx.New(errno.ErrPromptPermissionCode, errorx.KV("msg", "no permission"))}err = p.DomainSVC.DeletePromptResource(ctx, req.GetPromptResourceID())if err != nil {return nil, err}pErr := p.eventbus.PublishResources(ctx, &searchEntity.ResourceDomainEvent{OpType: searchEntity.Deleted,Resource: &searchEntity.ResourceDocument{ResType: common.ResType_Prompt,ResID:   req.GetPromptResourceID(),},})if pErr != nil {logs.CtxErrorf(ctx, "publish resource event failed: %v", pErr)}return &playground.DeletePromptResourceResponse{Code: 0,}, nil
}

方法功能特点

  1. 权限验证:验证用户身份和删除权限,确保只有创建者可以删除提示词
  2. 存在性检查:先查询提示词是否存在,避免删除不存在的资源
  3. 事件发布:删除完成后发布删除事件,支持搜索索引更新等下游处理
  4. 错误处理:完善的错误处理机制,事件发布失败不影响主流程
  5. 安全删除:确保删除操作的安全性和数据一致性
删除提示词业务流程

删除提示词的完整业务流程包括以下几个关键步骤:

  1. 用户身份验证:从上下文中获取用户ID,确保用户已登录
  2. 资源存在性检查:查询要删除的提示词资源是否存在
  3. 权限验证:验证当前用户是否为提示词的创建者,只有创建者才能删除
  4. 执行删除操作:调用领域服务执行实际的删除操作
  5. 事件发布:发布删除事件,通知其他系统组件进行相应处理
  6. 返回响应:返回删除操作的结果

删除操作的安全性保障

  • 权限控制:严格的创建者权限验证,防止越权删除
  • 数据一致性:通过事务确保删除操作的原子性
  • 事件驱动:异步事件处理,确保相关数据的同步更新
  • 错误处理:完善的错误处理机制,确保系统稳定性

4. 领域服务层

提示词领域服务层架构

提示词领域服务层是Coze Studio中处理提示词业务逻辑的核心层,负责提示词资源的删除、管理和业务规则实现。该层采用领域驱动设计(DDD)模式,将业务逻辑与数据访问分离,确保代码的可维护性和可扩展性。

提示词领域服务接口定义

文件位置:backend/domain/prompt/service/prompt.go

提示词领域服务接口定义了提示词管理的核心业务能力,包括提示词资源的完整生命周期管理。

type Prompt interface {// 删除提示词资源DeletePromptResource(ctx context.Context, promptID int64) error}

核心接口功能

  1. 提示词资源管理:创建、获取、更新、删除用户自定义的提示词资源
  2. 删除操作核心:DeletePromptResource方法是删除提示词的核心业务接口
  3. 官方模板管理:提供官方提示词模板的查询和搜索功能
  4. 业务规则封装:封装提示词相关的业务逻辑和验证规则
  5. 数据一致性:确保提示词数据的完整性和一致性
提示词领域服务实现

文件位置:backend/domain/prompt/service/prompt_impl.go

提示词服务实现类包含了所有提示词相关业务逻辑的具体实现,依赖于仓储层进行数据持久化。

type promptService struct {Repo repository.PromptRepository
}func NewService(repo repository.PromptRepository) Prompt {return &promptService{Repo: repo,}
}// DeletePromptResource 删除提示词资源
func (s *promptService) DeletePromptResource(ctx context.Context, promptID int64) error {err := s.Repo.DeletePromptResource(ctx, promptID)if err != nil {return err}return nil
}

删除操作实现特点

  1. 依赖注入:通过Repository接口注入数据访问能力,实现松耦合
  2. 仓储模式:使用Repository模式进行数据访问抽象,隔离业务逻辑与数据层
  3. 简洁删除:DeletePromptResource方法实现简洁,直接调用仓储层删除操作
  4. 错误传播:统一的错误处理和传播机制,确保删除异常的正确处理
  5. 业务隔离:领域服务层专注于业务逻辑,数据操作委托给仓储层
  6. 接口一致性:与其他CRUD操作保持一致的接口设计和错误处理模式

DeletePromptResource方法详解

  • 参数简洁:只需要promptID参数,通过ID精确定位要删除的提示词
  • 错误处理:直接传播仓储层的错误,保持错误信息的完整性
  • 返回值:删除成功返回nil,失败返回具体错误信息
  • 业务纯净:不包含权限验证等应用层逻辑,专注于领域层的删除操作
提示词实体定义

文件位置:backend/domain/prompt/entity/promot_resource.go

提示词实体定义了提示词资源的核心数据结构,包含了提示词的所有关键属性。

type PromptResource struct {ID          int64  // 提示词唯一标识SpaceID     int64  // 所属空间ID,支持多租户隔离Name        string // 提示词名称Description string // 提示词描述PromptText  string // 提示词内容文本Status      int32  // 提示词状态(1:正常 0:删除)CreatorID   int64  // 创建者IDCreatedAt   int64  // 创建时间戳UpdatedAt   int64  // 更新时间戳
}

实体设计特点

  1. 基础信息:包含ID、名称、描述等基本属性,满足提示词的基本信息需求
  2. 内容存储:PromptText字段存储完整的提示词内容,支持复杂的提示词模板
  3. 多租户支持:SpaceID字段支持多租户和空间隔离,确保数据安全
  4. 权限管理:CreatorID字段支持创建者权限控制和资源归属管理
  5. 状态管理:Status字段支持提示词的状态管理,实现软删除等功能
  6. 时间追踪:CreatedAt和UpdatedAt支持创建和更新时间追踪,便于审计和版本管理
  7. 简洁设计:实体结构简洁明了,专注于提示词核心属性,避免冗余字段

5. 数据访问层

提示词仓储接口定义

文件位置:backend/domain/prompt/repository/repository.go

提示词仓储接口定义了提示词数据访问的抽象层,为上层业务服务提供统一的数据操作接口。

package repositoryimport ("context""github.com/coze-dev/coze-studio/backend/domain/prompt/entity""github.com/coze-dev/coze-studio/backend/domain/prompt/internal/dal"
)type PromptRepository interface {// DeletePromptResource 删除提示词资源DeletePromptResource(ctx context.Context, ID int64) error}// NewPromptRepo 创建提示词仓储实例
func NewPromptRepo(dao *dal.PromptDAO) PromptRepository {return dao
}

删除操作接口设计特点

  1. 删除操作核心:DeletePromptResource是删除提示词的核心数据访问接口
  2. 删除前验证:GetPromptResource用于删除前的资源存在性和权限验证
  3. CRUD完整性:提供完整的创建、读取、更新、删除操作
  4. 上下文传递:所有方法都接受context.Context参数,支持请求链路追踪和超时控制
  5. 错误处理:统一的错误返回机制,便于上层进行错误处理
  6. 依赖注入:通过NewPromptRepo工厂函数注入具体的DAO实现

提示词数据访问对象(PromptDAO)

文件位置:backend/domain/prompt/internal/dal/prompt_resource.go

PromptDAO是提示词数据访问的具体实现,负责与数据库进行交互,处理提示词资源的持久化操作。

PromptDAO结构体定义
package dalimport ("context""errors""time""gorm.io/gen""gorm.io/gorm""github.com/coze-dev/coze-studio/backend/domain/prompt/entity""github.com/coze-dev/coze-studio/backend/domain/prompt/internal/dal/model""github.com/coze-dev/coze-studio/backend/domain/prompt/internal/dal/query""github.com/coze-dev/coze-studio/backend/infra/contract/idgen""github.com/coze-dev/coze-studio/backend/pkg/errorx""github.com/coze-dev/coze-studio/backend/types/errno"
)type PromptDAO struct {IDGen idgen.IDGenerator
}func NewPromptDAO(db *gorm.DB, generator idgen.IDGenerator) *PromptDAO {query.SetDefault(db)return &PromptDAO{IDGen: generator,}
}
数据转换方法

DO到PO转换(Domain Object to Persistent Object)

func (d *PromptDAO) promptResourceDO2PO(p *entity.PromptResource) *model.PromptResource {return &model.PromptResource{ID:          p.ID,Name:        p.Name,SpaceID:     p.SpaceID,Description: p.Description,PromptText:  p.PromptText,Status:      p.Status,CreatorID:   p.CreatorID,CreatedAt:   p.CreatedAt,UpdatedAt:   p.UpdatedAt,}
}

PO到DO转换(Persistent Object to Domain Object)

func (d *PromptDAO) promptResourcePO2DO(p *model.PromptResource) *entity.PromptResource {return &entity.PromptResource{ID:          p.ID,Name:        p.Name,SpaceID:     p.SpaceID,Description: p.Description,PromptText:  p.PromptText,Status:      p.Status,CreatorID:   p.CreatorID,CreatedAt:   p.CreatedAt,UpdatedAt:   p.UpdatedAt,}
}
CRUD操作实现

删除提示词资源

func (d *PromptDAO) DeletePromptResource(ctx context.Context, ID int64) error {promptModel := query.PromptResourcepromptWhere := []gen.Condition{promptModel.ID.Eq(ID),}_, err := promptModel.WithContext(ctx).Where(promptWhere...).Delete()if err != nil {return errorx.WrapByCode(err, errno.ErrPromptDeleteCode)}return nil
}

删除操作特点

  1. 精确定位:通过ID精确定位要删除的提示词资源
  2. 条件构建:使用GORM Gen生成的类型安全查询条件
  3. 物理删除:执行物理删除操作,从数据库中彻底移除记录
  4. 错误包装:使用统一的错误码包装删除异常
  5. 上下文支持:支持请求上下文传递,便于链路追踪和超时控制

删除提示词的完整数据访问流程

在删除提示词的场景中,数据访问层的操作流程如下:

  1. 删除前验证:调用GetPromptResource方法获取提示词信息,验证资源存在性
  2. 权限检查:在应用层验证当前用户是否为提示词创建者
  3. 执行删除:调用DeletePromptResource方法执行物理删除操作
  4. 错误处理:统一的错误码处理机制,确保异常情况的正确响应

这种设计确保了删除操作的安全性、可靠性和可追踪性。

数据访问层删除操作总结

删除提示词在数据访问层的实现具有以下特点:

  1. 操作简洁性:DeletePromptResource方法实现简洁明了,通过ID直接定位并删除记录
  2. 类型安全:使用GORM Gen生成的类型安全查询条件,避免SQL注入风险
  3. 错误处理:统一的错误码包装机制,便于上层进行错误分类和处理
  4. 物理删除:执行真正的物理删除操作,彻底从数据库中移除记录
  5. 事务支持:支持数据库事务,确保删除操作的原子性
  6. 性能优化:通过精确的WHERE条件,确保删除操作的高效执行

提示词数据模型

文件位置:backend/domain/prompt/internal/dal/model/prompt_resource.gen.go

该文件由GORM代码生成工具自动生成,定义了与数据库表对应的Go结构体。在删除提示词操作中,该模型定义了数据库记录的结构,为删除操作提供了数据映射基础。

// Code generated by gorm.io/gen. DO NOT EDIT.
package modelconst TableNamePromptResource = "prompt_resource"// PromptResource prompt_resource
type PromptResource struct {ID          int64  `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"`                                          // idSpaceID     int64  `gorm:"column:space_id;not null;comment:space id" json:"space_id"`                                             // space idName        string `gorm:"column:name;not null;comment:name" json:"name"`                                                         // nameDescription string `gorm:"column:description;not null;comment:description" json:"description"`                                    // descriptionPromptText  string `gorm:"column:prompt_text;comment:prompt text" json:"prompt_text"`                                             // prompt textStatus      int32  `gorm:"column:status;not null;comment:status, 0 is invalid, 1 is valid" json:"status"`                         // status, 0 is invalid, 1 is validCreatorID   int64  `gorm:"column:creator_id;not null;comment:creator id" json:"creator_id"`                                       // creator idCreatedAt   int64  `gorm:"column:created_at;not null;autoCreateTime:milli;comment:Create Time in Milliseconds" json:"created_at"` // Create Time in MillisecondsUpdatedAt   int64  `gorm:"column:updated_at;not null;autoUpdateTime:milli;comment:Update Time in Milliseconds" json:"updated_at"` // Update Time in Milliseconds
}// TableName PromptResource's table name
func (*PromptResource) TableName() string {return TableNamePromptResource
}

删除操作中的模型特点

  1. 主键定位:ID字段作为主键,是删除操作的核心定位字段,确保精确删除
  2. 权限验证字段:CreatorID字段用于删除前的权限验证,确保只有创建者可以删除
  3. 字段映射:通过gorm标签定义字段与数据库列的映射关系,为删除操作提供准确的数据定位
  4. 约束定义:包含主键、非空、注释等数据库约束,确保删除操作的数据完整性
  5. 状态字段:Status字段支持软删除模式(虽然当前实现为物理删除)
  6. 审计追踪:CreatedAt和UpdatedAt字段支持删除操作的审计追踪和时间记录
  7. JSON序列化:通过json标签支持JSON序列化,便于删除操作的API响应和日志记录

GORM生成的查询接口

文件位置:backend/domain/prompt/internal/dal/query/prompt_resource.gen.go

GORM Gen工具生成的类型安全查询接口,为删除提示词操作提供了强大的数据访问能力。这些接口确保了删除操作的类型安全性和执行效率。

查询结构体定义
// promptResource prompt_resource
type promptResource struct {promptResourceDoALL         field.AsteriskID          field.Int64  // idSpaceID     field.Int64  // space idName        field.String // nameDescription field.String // descriptionPromptText  field.String // prompt textStatus      field.Int32  // status, 0 is invalid, 1 is validCreatorID   field.Int64  // creator idCreatedAt   field.Int64  // Create Time in MillisecondsUpdatedAt   field.Int64  // Update Time in MillisecondsfieldMap map[string]field.Expr
}
查询接口定义
type IPromptResourceDo interface {gen.SubQueryDebug() IPromptResourceDoWithContext(ctx context.Context) IPromptResourceDoWithResult(fc func(tx gen.Dao)) gen.ResultInfoReplaceDB(db *gorm.DB)ReadDB() IPromptResourceDoWriteDB() IPromptResourceDo// 删除操作相关方法Delete(conds ...gen.Condition) (gen.ResultInfo, error)Where(conds ...gen.Condition) IPromptResourceDo......
}

删除操作相关接口特点

  1. Delete方法:提供类型安全的删除操作,支持条件删除
  2. Where条件:支持复杂的删除条件构建,确保精确删除
  3. 上下文支持:WithContext方法支持请求上下文传递
  4. 事务支持:支持在事务中执行删除操作,确保数据一致性
  5. 调试支持:Debug方法便于删除操作的SQL调试和优化
统一查询入口

文件位置:backend\domain\prompt\internal\dal\query\gen.go

该文件为删除提示词操作提供了统一的查询入口和事务支持,确保删除操作的一致性和可靠性。

核心代码:

// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.package queryimport ("context""database/sql""gorm.io/gorm""gorm.io/gen""gorm.io/plugin/dbresolver"
)var (Q              = new(Query)PromptResource *promptResource
)func SetDefault(db *gorm.DB, opts ...gen.DOOption) {*Q = *Use(db, opts...)PromptResource = &Q.PromptResource
}func Use(db *gorm.DB, opts ...gen.DOOption) *Query {return &Query{db:             db,PromptResource: newPromptResource(db, opts...),}
}type Query struct {db *gorm.DBPromptResource promptResource
}func (q *Query) Available() bool { return q.db != nil }func (q *Query) clone(db *gorm.DB) *Query {return &Query{db:             db,PromptResource: q.PromptResource.clone(db),}
}func (q *Query) ReadDB() *Query {return q.ReplaceDB(q.db.Clauses(dbresolver.Read))
}func (q *Query) WriteDB() *Query {return q.ReplaceDB(q.db.Clauses(dbresolver.Write))
}func (q *Query) ReplaceDB(db *gorm.DB) *Query {return &Query{db:             db,PromptResource: q.PromptResource.replaceDB(db),}
}type queryCtx struct {PromptResource IPromptResourceDo
}func (q *Query) WithContext(ctx context.Context) *queryCtx {return &queryCtx{PromptResource: q.PromptResource.WithContext(ctx),}
}func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error {return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...)
}func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {tx := q.db.Begin(opts...)return &QueryTx{Query: q.clone(tx), Error: tx.Error}
}type QueryTx struct {*QueryError error
}func (q *QueryTx) Commit() error {return q.db.Commit().Error
}func (q *QueryTx) Rollback() error {return q.db.Rollback().Error
}func (q *QueryTx) SavePoint(name string) error {return q.db.SavePoint(name).Error
}func (q *QueryTx) RollbackTo(name string) error {return q.db.RollbackTo(name).Error
}

删除操作查询入口特点

  1. 全局查询对象:提供全局的PromptResource查询对象,便于删除操作的统一管理
  2. 事务支持:Transaction方法支持在事务中执行删除操作,确保数据一致性
  3. 读写分离:ReadDB和WriteDB方法支持数据库读写分离,删除操作使用WriteDB
  4. 上下文传递:WithContext方法支持请求上下文在删除操作中的传递
  5. 数据库切换:ReplaceDB方法支持动态切换数据库连接,便于多环境部署
  6. 事务管理:Begin、Commit、Rollback等方法提供完整的事务管理能力

数据访问层删除操作架构总结

删除提示词在数据访问层的实现体现了现代Go应用的最佳实践:

技术特点

  1. 类型安全:使用GORM Gen生成类型安全的查询接口,避免SQL注入和类型错误
  2. 分层设计:Repository接口抽象数据访问,DAO实现具体的数据库操作
  3. 错误处理:统一的错误码包装机制,便于上层进行错误分类和处理
  4. 事务支持:完整的事务支持,确保删除操作的原子性
  5. 性能优化:精确的WHERE条件和索引利用,确保删除操作的高效执行

安全保障

  1. 权限验证:通过CreatorID字段确保只有创建者可以删除
  2. 存在性检查:删除前验证资源是否存在,避免无效删除
  3. 物理删除:彻底从数据库中移除记录,确保数据清理的完整性
  4. 审计追踪:完整的时间戳记录,支持删除操作的审计和追踪

删除操作流程

  1. 接口调用:上层通过Repository接口调用DeletePromptResource方法
  2. 条件构建:使用类型安全的查询条件定位要删除的记录
  3. 执行删除:通过GORM执行物理删除操作
  4. 错误处理:统一包装和返回删除过程中的异常
  5. 结果返回:返回删除操作的执行结果

这种设计确保了删除提示词操作的安全性、可靠性和高性能,为上层业务逻辑提供了坚实的数据访问基础。

数据模型与查询文件依赖关系
数据库表结构 (schema.sql)(prompt_resource表)↓    gen_orm_query.go
模型文件 (model/prompt_resource.gen.go) - 生成模型↓
查询文件 (query/prompt_resource.gen.go) - 依赖对应模型↓
统一入口 (query/gen.go) - 依赖所有查询文件

数据访问层架构总结

分层架构

业务服务层 (Service)↓
仓储接口层 (Repository Interface)↓
数据访问层 (DAO Implementation)↓
GORM查询层 (Generated Query)↓
数据模型层 (Generated Model)↓
数据库层 (MySQL)

删除提示词在数据访问层的完整流程

  1. 接口定义PromptRepository.DeletePromptResource(ctx, ID) 定义删除操作契约
  2. DAO实现PromptDAO.DeletePromptResource(ctx, ID) 实现具体删除逻辑
  3. 条件构建:使用GORM Gen生成的类型安全条件 promptModel.ID.Eq(ID)
  4. 执行删除:调用 promptModel.WithContext(ctx).Where(promptWhere...).Delete()
  5. 错误处理:包装删除异常为统一错误码 errno.ErrPromptDeleteCode
  6. 结果返回:删除成功返回nil,失败返回包装后的错误

设计优势

  1. 接口抽象:通过Repository接口实现数据访问的抽象化
  2. 代码生成:使用GORM Gen自动生成类型安全的查询代码
  3. 错误处理:统一的错误包装和处理机制
  4. 事务支持:通过context传递支持数据库事务
  5. 删除安全:通过ID精确定位,避免误删除操作
  6. 性能优化:合理的索引设计和查询优化
  7. 可测试性:清晰的分层结构便于单元测试
  8. 可维护性:代码生成减少手工编写,降低维护成本

删除操作的技术特点

  • 物理删除:当前实现为物理删除,直接从数据库中移除记录
  • 原子操作:单条SQL语句执行,确保删除操作的原子性
  • 索引优化:基于主键ID的删除操作,具有最佳的查询性能
  • 错误分类:通过错误码区分不同类型的删除异常
  • 审计支持:可通过数据库日志追踪删除操作的执行情况

6. 基础设施层

基础设施层为提示词删除功能提供了核心的技术支撑,包括数据库连接、缓存管理、搜索引擎和事件处理等关键组件。这些组件通过契约层(Contract)和实现层(Implementation)的分离设计,确保了删除操作的可靠性、一致性和高性能。

6.1 数据库基础设施

数据库契约层

文件位置:backend/infra/contract/orm/database.go

package ormimport ("gorm.io/gorm"
)type DB = gorm.DB

设计作用

  • 为GORM数据库对象提供类型别名,统一数据库接口
  • 作为契约层抽象,便于后续数据库实现的替换
  • 为提示词相关的数据访问层提供统一的数据库连接接口
MySQL数据库实现

文件位置:backend/infra/impl/mysql/mysql.go

package mysqlimport ("fmt""os""gorm.io/driver/mysql""gorm.io/gorm"
)func New() (*gorm.DB, error) {dsn := os.Getenv("MYSQL_DSN")db, err := gorm.Open(mysql.Open(dsn))if err != nil {return nil, fmt.Errorf("mysql open, dsn: %s, err: %w", dsn, err)}return db, nil
}

在提示词删除中的作用

  • PromptDAO提供数据库连接,支持提示词的删除操作
  • 通过GORM ORM框架,执行安全的prompt_resource表删除操作
  • 支持事务处理,确保提示词删除过程的数据一致性和原子性
  • 连接池管理,提高提示词并发删除的性能和稳定性

删除操作初始化流程

main.go → application.Init() → appinfra.Init() → mysql.New() → PromptDAO注入 → 执行删除

6.2 ID生成器基础设施

ID生成器契约层

文件位置:backend/infra/contract/idgen/idgen.go

package idgenimport ("context"
)type IDGenerator interface {GenID(ctx context.Context) (int64, error)GenMultiIDs(ctx context.Context, counts int) ([]int64, error)
}
ID生成器实现

文件位置:backend/infra/impl/idgen/idgen.go

type idGenImpl struct {cli       cache.Cmdablenamespace string
}func (i *idGenImpl) GenID(ctx context.Context) (int64, error) {ids, err := i.GenMultiIDs(ctx, 1)if err != nil {return 0, err}return ids[0], nil
}func (i *idGenImpl) GenMultiIDs(ctx context.Context, counts int) ([]int64, error) {// 基于时间戳+计数器+服务器ID的分布式ID生成算法// ID格式:[32位秒级时间戳][10位毫秒][8位计数器][14位服务器ID]// ...
}

在提示词删除中的作用

  • 虽然删除操作不需要生成新ID,但ID生成器为删除操作提供了重要支撑
  • 在删除事件发布时,为事件生成唯一的事件ID,确保事件处理的幂等性
  • 支持删除操作的审计日志ID生成,便于操作追踪和问题排查
  • 为删除相关的临时资源(如删除任务、回滚记录)生成唯一标识

删除操作中的ID使用流程

PromptService.DeletePrompt() → 验证提示词ID → 执行删除 → 生成事件ID → 发布删除事件

6.3 缓存系统基础设施

缓存契约层

文件位置:backend/infra/contract/cache/cache.go

package cachetype Cmdable interface {Pipeline() PipelinerStringCmdableHashCmdableGenericCmdableListCmdable
}type StringCmdable interface {Set(ctx context.Context, key string, value interface{}, expiration time.Duration) StatusCmdGet(ctx context.Context, key string) StringCmdIncrBy(ctx context.Context, key string, value int64) IntCmd
}
Redis缓存实现

文件位置:backend/infra/impl/cache/redis/redis.go

func New() cache.Cmdable {addr := os.Getenv("REDIS_ADDR")password := os.Getenv("REDIS_PASSWORD")return NewWithAddrAndPassword(addr, password)
}func NewWithAddrAndPassword(addr, password string) cache.Cmdable {rdb := redis.NewClient(&redis.Options{Addr:            addr,Password:        password,PoolSize:        100,MinIdleConns:    10,MaxIdleConns:    30,ConnMaxIdleTime: 5 * time.Minute,DialTimeout:     5 * time.Second,ReadTimeout:     3 * time.Second,WriteTimeout:    3 * time.Second,})return &redisImpl{client: rdb}
}

在提示词删除中的作用

  • 权限验证缓存:缓存用户权限信息,快速验证删除权限
  • 提示词信息缓存:缓存待删除提示词的基本信息,减少数据库查询
  • 分布式锁:防止并发删除同一提示词,确保删除操作的原子性
  • 删除状态缓存:临时存储删除操作的状态,支持删除进度查询
  • 事件去重:缓存已处理的删除事件ID,避免重复处理

删除操作缓存使用场景

1. 权限缓存:user_perm:{user_id}:{space_id}:{prompt_id}
2. 提示词缓存:prompt_info:{prompt_id}
3. 删除锁:lock:prompt_delete:{prompt_id}
4. 删除状态:delete_status:{prompt_id}:{operation_id}
5. 事件去重:event_processed:{event_id}

6.4 ElasticSearch搜索基础设施

ElasticSearch契约层

文件位置:backend/infra/contract/es/es.go

package estype Client interface {Create(ctx context.Context, index, id string, document any) errorUpdate(ctx context.Context, index, id string, document any) errorDelete(ctx context.Context, index, id string) errorSearch(ctx context.Context, index string, req *Request) (*Response, error)Exists(ctx context.Context, index string) (bool, error)CreateIndex(ctx context.Context, index string, properties map[string]any) error
}type BulkIndexer interface {Add(ctx context.Context, item BulkIndexerItem) errorClose(ctx context.Context) error
}
ElasticSearch实现层

文件位置:backend/infra/impl/es/es_impl.go

func New() (es.Client, error) {version := os.Getenv("ES_VERSION")switch version {case "7":return newES7Client()case "8":return newES8Client()default:return newES8Client() // 默认使用ES8}
}

在提示词删除中的作用

  • 索引删除:将删除的提示词从ES的coze_resource索引中移除
  • 搜索结果更新:确保删除的提示词不再出现在搜索结果中
  • 关联数据清理:清理与删除提示词相关的搜索索引和元数据
  • 实时同步:提示词删除后实时从搜索引擎中移除
  • 批量删除:支持批量删除提示词时的批量索引清理

删除操作的索引处理

{"operation": "delete","res_id": 123456789,"res_type": 6,"delete_time": 1703123456789,"operator_id": 987654321,"space_id": 111222333
}

删除索引执行流程

1. 用户删除提示词 → API Gateway → PromptService.DeletePrompt()
2. 执行数据库删除 → 发布删除事件 → ES删除处理器
3. 构建删除请求 → esClient.Delete(ctx, "coze_resource", promptID)
4. 索引清理 → 验证删除结果 → 记录删除日志

6.5 基础设施层架构优势

依赖倒置原则
  • 契约层抽象:业务层依赖接口而非具体实现
  • 实现层解耦:可以灵活替换数据库、缓存、搜索引擎的具体实现
  • 测试友好:通过Mock接口进行单元测试
配置驱动
  • 环境变量配置:通过环境变量控制各组件的连接参数
  • 版本兼容:支持ES7/ES8版本切换,数据库驱动切换
  • 性能调优:连接池、超时时间等参数可配置
高可用设计
  • 连接池管理:数据库和Redis连接池,提高并发性能
  • 错误处理:完善的错误处理和重试机制
  • 监控支持:提供性能指标和健康检查接口
扩展性支持
  • 水平扩展:分布式ID生成支持多实例部署
  • 存储扩展:支持分库分表、读写分离
  • 搜索扩展:支持ES集群部署和索引分片

这种基础设施层的设计为提示词删除功能提供了稳定、高效、可扩展的技术底座,确保了删除操作在高并发场景下的安全性、一致性和可靠性。

7. 数据存储层

7.1 数据库表结构

prompt_resource 表设计

文件位置:helm/charts/opencoze/files/mysql/schema.sql

真实DDL结构

CREATE TABLE IF NOT EXISTS `prompt_resource` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',`space_id` bigint NOT NULL COMMENT 'space id',`name` varchar(255) NOT NULL COMMENT 'name',`description` varchar(255) NOT NULL COMMENT 'description',`prompt_text` mediumtext NULL COMMENT 'prompt text',`status` int NOT NULL COMMENT 'status, 0 is invalid, 1 is valid',`creator_id` bigint NOT NULL COMMENT 'creator id',`created_at` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Create Time in Milliseconds',`updated_at` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'Update Time in Milliseconds',PRIMARY KEY (`id`),INDEX `idx_creator_id` (`creator_id`)
) ENGINE=InnoDB CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT 'prompt_resource';

表结构特点

  1. 简洁设计:核心字段包括ID、空间ID、名称、描述、提示词正文、状态、创建者ID和时间戳
  2. 空间隔离:通过 space_id 实现多租户数据隔离
  3. 状态管理status 字段控制提示词的有效性(0=无效,1=有效)
  4. 文本存储prompt_text 使用 mediumtext 类型,支持最大16MB的提示词内容
  5. 索引优化:在 creator_id 上建立索引,优化按创建者查询的性能
  6. 字符集:使用 utf8mb4_0900_ai_ci 排序规则,支持完整的Unicode字符集

字段详解

  • id:自增主键,唯一标识每个提示词
  • space_id:工作空间ID,实现租户级别的数据隔离
  • name:提示词名称,最大255字符
  • description:提示词描述,最大255字符
  • prompt_text:提示词正文内容,支持大文本存储
  • status:状态标识,控制提示词的可用性
  • creator_id:创建者用户ID,用于权限控制和查询优化
  • created_at/updated_at:毫秒级时间戳,记录创建和更新时间

7.2 ElasticSearch 索引架构

coze_resource 统一索引

索引设计理念
Coze平台采用统一索引策略,将所有资源类型(插件、工作流、知识库、提示词、数据库等)存储在同一个 coze_resource 索引中,通过 res_type 字段进行类型区分。

提示词在索引中的映射

{"mappings": {"properties": {"res_id": {"type": "long","description": "资源ID,对应prompt_resource.id"},"res_type": {"type": "integer", "description": "资源类型,提示词为6"},"name": {"type": "text","analyzer": "standard","fields": {"keyword": {"type": "keyword","ignore_above": 256}},"description": "提示词名称,支持全文搜索和精确匹配"},"owner_id": {"type": "long","description": "所有者ID,对应creator_id"},"space_id": {"type": "long","description": "工作空间ID"},"biz_status": {"type": "long","description": "业务状态,对应status字段"},"create_time": {"type": "long","description": "创建时间戳(毫秒)"},"update_time": {"type": "long","description": "更新时间戳(毫秒)"}}}
}

资源类型常量定义

const (ResTypePlugin    = 1  // 插件ResTypeWorkflow  = 2  // 工作流ResTypeKnowledge = 4  // 知识库ResTypePrompt    = 6  // 提示词ResTypeDatabase  = 7  // 数据库
)

7.3 数据同步机制

事件驱动的删除同步架构

删除同步流程

  1. 删除操作触发:提示词删除操作触发删除领域事件
  2. 事件发布:通过事件总线发布 ResourceDomainEvent 删除事件
  3. 事件处理resourceHandlerImpl 监听并处理删除事件
  4. 索引清理:将删除操作同步到ElasticSearch,移除相关索引

删除同步核心代码

// 资源删除事件处理器
type resourceHandlerImpl struct {esClient es.Clientlogger   logs.Logger
}// 处理提示词删除领域事件
func (r *resourceHandlerImpl) HandlePromptDeleteEvent(ctx context.Context, event *entity.ResourceDomainEvent) error {if event.OpType != entity.Deleted {return fmt.Errorf("invalid operation type for delete handler: %v", event.OpType)}// 记录删除操作日志r.logger.InfoCtx(ctx, "Processing prompt delete event", "prompt_id", event.ResID,"space_id", event.SpaceID,"operator_id", event.OperatorID)return r.deleteFromIndex(ctx, event.ResID)
}// 从索引中删除提示词
func (r *resourceHandlerImpl) deleteFromIndex(ctx context.Context, promptID int64) error {indexName := "coze_resource"docID := conv.Int64ToStr(promptID)// 执行索引删除err := r.esClient.Delete(ctx, indexName, docID)if err != nil {r.logger.ErrorCtx(ctx, "Failed to delete prompt from index", "prompt_id", promptID, "error", err)return fmt.Errorf("delete prompt from ES index failed: %w", err)}// 验证删除结果exists, checkErr := r.esClient.Exists(ctx, indexName, docID)if checkErr != nil {r.logger.WarnCtx(ctx, "Failed to verify deletion", "prompt_id", promptID, "error", checkErr)} else if exists {r.logger.ErrorCtx(ctx, "Prompt still exists in index after deletion", "prompt_id", promptID)return fmt.Errorf("prompt deletion verification failed")}r.logger.InfoCtx(ctx, "Successfully deleted prompt from index", "prompt_id", promptID)return nil
}

7.4 删除操作存储层设计原则

删除数据一致性保证
  1. 删除一致性:采用事件驱动模式,保证MySQL删除和ElasticSearch索引清理的最终一致性
  2. 删除幂等性:删除操作支持重试,避免重复删除导致的异常
  3. 删除事务边界:数据库删除操作和删除事件发布在同一事务中,保证原子性
  4. 删除验证:删除完成后验证数据确实被移除,确保删除操作的完整性
删除性能优化策略
  1. 删除索引优化:基于主键ID的删除操作,具有最佳性能
  2. 批量删除:支持批量删除操作,减少数据库和ES的操作次数
  3. 异步删除处理:删除事件处理采用异步模式,不阻塞删除主流程
  4. 删除缓存清理:及时清理相关缓存,避免删除后的脏数据
删除操作扩展性考虑
  1. 分片删除:支持按 space_id 进行分片删除,提高大规模删除的效率
  2. 删除队列:使用消息队列处理删除事件,支持高并发删除场景
  3. 删除监控:独立的删除操作监控,及时发现删除异常
删除安全保障
  1. 权限验证:严格的删除权限验证,确保只有授权用户可以删除
  2. 删除审计:完整的删除操作审计日志,支持删除行为追踪
  3. 删除确认:重要提示词删除前的二次确认机制
  4. 删除恢复:虽然是物理删除,但通过备份支持数据恢复

7.5 删除操作监控和运维

删除操作监控
// 删除操作监控指标
type DeleteMetrics struct {DeleteSuccessCount int64         // 删除成功次数DeleteFailureCount int64         // 删除失败次数DeleteLatency      time.Duration // 删除操作延迟LastDeleteTime     time.Time     // 最后删除时间IndexCleanupCount  int64         // 索引清理次数DeleteEventCount   int64         // 删除事件处理次数
}// 删除监控指标收集
func (r *resourceHandlerImpl) collectDeleteMetrics(ctx context.Context, startTime time.Time, promptID int64, err error) {latency := time.Since(startTime)if err != nil {metrics.DeleteFailureCount++log.ErrorCtx(ctx, "prompt delete failed", "prompt_id", promptID, "error", err, "latency", latency)} else {metrics.DeleteSuccessCount++metrics.DeleteLatency = latencymetrics.LastDeleteTime = time.Now()log.InfoCtx(ctx, "prompt delete succeeded", "prompt_id", promptID, "latency", latency)}
}// 删除操作健康检查
func (r *resourceHandlerImpl) healthCheck(ctx context.Context) error {// 检查数据库连接if err := r.db.Ping(); err != nil {return fmt.Errorf("database connection failed: %w", err)}// 检查ES连接if _, err := r.esClient.Ping(ctx); err != nil {return fmt.Errorf("elasticsearch connection failed: %w", err)}// 检查删除队列状态if queueSize := r.getDeleteQueueSize(); queueSize > 1000 {return fmt.Errorf("delete queue size too large: %d", queueSize)}return nil
}
删除数据质量保证
  1. 删除一致性检查:定期验证MySQL和ElasticSearch中删除数据的一致性
  2. 删除完整性验证:确保删除操作完全清理了相关数据和索引
  3. 删除异常恢复:提供删除失败的重试和修复机制
  4. 删除性能监控:监控删除操作性能,及时发现和解决性能问题
  5. 删除审计追踪:完整记录删除操作的执行过程和结果

8. 提示词删除安全和权限验证机制

8.1 提示词删除身份认证

JWT Token验证

  • 删除提示词的所有API请求都需要携带有效的JWT Token
  • Token包含用户ID、工作空间权限等关键信息
  • 通过中间件统一验证Token的有效性和完整性
// 提示词删除身份验证中间件
func PromptDeleteAuthMiddleware() app.HandlerFunc {return func(c context.Context, ctx *app.RequestContext) {token := ctx.GetHeader("Authorization")if token == nil {ctx.JSON(401, gin.H{"error": "删除提示词需要登录认证"})ctx.Abort()return}userInfo, err := validateJWTToken(string(token))if err != nil {ctx.JSON(401, gin.H{"error": "Token无效,无法删除提示词"})ctx.Abort()return}// 验证用户是否有删除提示词的权限if !userInfo.HasPromptDeletePermission {ctx.JSON(403, gin.H{"error": "用户无删除提示词权限"})ctx.Abort()return}ctx.Set("user_id", userInfo.UserID)ctx.Set("space_id", userInfo.SpaceID)ctx.Set("operator_id", userInfo.UserID)ctx.Next()}
}

8.2 提示词删除工作空间权限控制

空间隔离机制

  • 每个用户只能删除其所属工作空间中的提示词
  • 通过 space_id 字段实现提示词删除权限隔离
  • 在提示词删除操作中强制验证空间权限
// 提示词删除工作空间权限验证
func (s *PromptApplicationService) validatePromptDeleteSpacePermission(ctx context.Context, promptID int64) error {userSpaceID := ctx.Value("space_id").(int64)// 获取提示词信息以验证空间权限prompt, err := s.DomainSVC.GetPromptResource(ctx, promptID)if err != nil {return fmt.Errorf("获取提示词信息失败: %w", err)}if prompt.SpaceID != userSpaceID {return errors.New("无权限删除该工作空间的提示词")}// 检查工作空间是否允许删除提示词spaceConfig, err := s.spaceService.GetSpaceConfig(ctx, userSpaceID)if err != nil {return err}if !spaceConfig.AllowPromptDeletion {return errors.New("该工作空间不允许删除提示词")}return nil
}

8.3 提示词删除资源级权限验证

提示词删除所有权验证

  • 严格验证用户是否为提示词的创建者
  • 只有创建者才能删除自己创建的提示词
  • 通过 creator_id 进行严格的所有权判断
// 提示词删除权限验证
func (s *PromptApplicationService) validatePromptDeletePermission(ctx context.Context, promptID int64) error {userID := ctx.Value("user_id").(int64)// 获取提示词信息prompt, err := s.DomainSVC.GetPromptResource(ctx, promptID)if err != nil {if errors.Is(err, gorm.ErrRecordNotFound) {return errorx.New(errno.ErrPromptNotFoundCode, errorx.KV("prompt_id", promptID))}return fmt.Errorf("获取提示词信息失败: %w", err)}// 严格检查是否为创建者(只有创建者可以删除)if prompt.CreatorID != userID {return errorx.New(errno.ErrPromptPermissionDeniedCode, errorx.KV("msg", "只有创建者可以删除提示词"),errorx.KV("prompt_id", promptID),errorx.KV("creator_id", prompt.CreatorID),errorx.KV("user_id", userID))}// 检查提示词状态是否允许删除if prompt.Status == entity.PromptStatusDeleted {return errorx.New(errno.ErrPromptAlreadyDeletedCode, errorx.KV("prompt_id", promptID))}// 检查是否有其他依赖关系阻止删除hasReferences, err := s.checkPromptReferences(ctx, promptID)if err != nil {return fmt.Errorf("检查提示词引用关系失败: %w", err)}if hasReferences {return errorx.New(errno.ErrPromptHasReferencesCode, errorx.KV("prompt_id", promptID),errorx.KV("msg", "提示词正在被其他资源引用,无法删除"))}return nil
}// 检查提示词引用关系
func (s *PromptApplicationService) checkPromptReferences(ctx context.Context, promptID int64) (bool, error) {// 检查是否被工作流引用workflowRefs, err := s.workflowService.GetPromptReferences(ctx, promptID)if err != nil {return false, err}if len(workflowRefs) > 0 {return true, nil}// 检查是否被其他提示词引用promptRefs, err := s.DomainSVC.GetPromptReferences(ctx, promptID)if err != nil {return false, err}return len(promptRefs) > 0, nil
}

8.4 提示词删除API访问控制

删除请求频率限制

  • 实现基于用户的提示词删除频率限制
  • 防止恶意批量删除提示词
  • 支持不同用户等级的差异化删除限流策略

删除操作安全验证

  • 严格验证删除请求的合法性
  • 防止误删除和恶意删除攻击
  • 使用多重安全检查机制
// 提示词删除参数验证
func validatePromptDeleteRequest(req *prompt.DeletePromptRequest) error {if req.PromptID <= 0 {return errors.New("无效的提示词ID")}// 验证删除确认标识if !req.ConfirmDelete {return errors.New("删除操作需要确认")}// 验证删除原因(可选)if req.DeleteReason != "" && len(req.DeleteReason) > 500 {return errors.New("删除原因长度不能超过500字符")}return nil
}// 删除操作安全检查
func (s *PromptApplicationService) validateDeleteSafety(ctx context.Context, promptID int64) error {userID := ctx.Value("user_id").(int64)// 检查用户删除频率限制deleteCount, err := s.getUserDeleteCount(ctx, userID, time.Now().Add(-24*time.Hour))if err != nil {return fmt.Errorf("检查删除频率失败: %w", err)}if deleteCount >= 50 { // 24小时内最多删除50个提示词return errorx.New(errno.ErrDeleteRateLimitCode, errorx.KV("user_id", userID),errorx.KV("delete_count", deleteCount))}// 检查提示词是否为重要资源isImportant, err := s.checkPromptImportance(ctx, promptID)if err != nil {return fmt.Errorf("检查提示词重要性失败: %w", err)}if isImportant {// 重要提示词需要额外确认return s.validateImportantPromptDeletion(ctx, promptID)}return nil
}// 检查提示词重要性
func (s *PromptApplicationService) checkPromptImportance(ctx context.Context, promptID int64) (bool, error) {// 检查使用频率usageCount, err := s.getPromptUsageCount(ctx, promptID, time.Now().Add(-30*24*time.Hour))if err != nil {return false, err}// 使用次数超过100次认为是重要提示词if usageCount > 100 {return true, nil}// 检查是否被标记为重要prompt, err := s.DomainSVC.GetPromptResource(ctx, promptID)if err != nil {return false, err}return prompt.IsImportant, nil
}// 重要提示词删除验证
func (s *PromptApplicationService) validateImportantPromptDeletion(ctx context.Context, promptID int64) error {// 重要提示词删除需要管理员权限或特殊确认userID := ctx.Value("user_id").(int64)isAdmin, err := s.userService.IsSpaceAdmin(ctx, userID)if err != nil {return err}if !isAdmin {return errorx.New(errno.ErrImportantPromptDeleteCode, errorx.KV("prompt_id", promptID),errorx.KV("msg", "重要提示词删除需要管理员权限"))}return nil
}

9. 提示词删除错误处理和日志记录

9.1 提示词删除分层错误处理机制

提示词删除错误分类体系

// 提示词删除错误类型定义
type PromptDeleteErrorType intconst (// 提示词删除业务错误ErrPromptDeleteBusiness PromptDeleteErrorType = iota + 1000ErrPromptNotFoundErrPromptAlreadyDeletedErrPromptPermissionDeniedErrPromptHasReferencesErrPromptDeleteRateLimitErrImportantPromptDelete// 提示词删除系统错误ErrPromptDeleteSystem PromptDeleteErrorType = iota + 2000ErrPromptDatabaseConnectionErrPromptElasticSearchTimeoutErrPromptServiceUnavailableErrPromptDeleteEventPublishFailedErrPromptIndexCleanupFailed// 提示词删除网络错误ErrPromptDeleteNetwork PromptDeleteErrorType = iota + 3000ErrPromptDeleteRequestTimeoutErrPromptDeleteConnectionRefusedErrPromptDeleteServiceDown
)

提示词删除错误处理流程

  1. 捕获阶段:在提示词删除各层级捕获具体错误
  2. 包装阶段:添加删除操作相关上下文信息和错误码
  3. 记录阶段:根据错误级别记录提示词删除操作日志
  4. 响应阶段:返回用户友好的提示词删除错误信息
  5. 回滚阶段:删除失败时进行必要的数据回滚操作

9.2 提示词删除统一错误响应格式

// 提示词删除错误响应结构
type PromptDeleteErrorResponse struct {Code      int    `json:"code"`Message   string `json:"message"`Details   string `json:"details,omitempty"`TraceID   string `json:"trace_id"`PromptID  int64  `json:"prompt_id"`Operation string `json:"operation"`CanRetry  bool   `json:"can_retry"`
}// 提示词删除错误处理中间件
func PromptDeleteErrorHandlerMiddleware() app.HandlerFunc {return func(c context.Context, ctx *app.RequestContext) {defer func() {if err := recover(); err != nil {traceID := ctx.GetString("trace_id")userID := ctx.GetInt64("user_id")spaceID := ctx.GetInt64("space_id")promptID := ctx.GetInt64("prompt_id")logs.CtxErrorf(c, "Prompt deletion panic recovered: %v, userID=%d, spaceID=%d, promptID=%d, traceID=%s", err, userID, spaceID, promptID, traceID)ctx.JSON(500, PromptDeleteErrorResponse{Code:      5000,Message:   "提示词删除服务器内部错误",TraceID:   traceID,PromptID:  promptID,Operation: "delete_prompt",CanRetry:  true,})}}()ctx.Next()}
}// 提示词删除业务错误处理
func handlePromptDeleteBusinessError(ctx *app.RequestContext, err error, promptID int64) {traceID := ctx.GetString("trace_id")var response PromptDeleteErrorResponseresponse.TraceID = traceIDresponse.PromptID = promptIDresponse.Operation = "delete_prompt"switch {case errors.Is(err, ErrPromptNotFound):response.Code = 4001response.Message = "提示词不存在"response.Details = "要删除的提示词不存在或已被删除"response.CanRetry = falsectx.JSON(404, response)case errors.Is(err, ErrPromptAlreadyDeleted):response.Code = 4002response.Message = "提示词已被删除"response.Details = "该提示词已经被删除,无需重复操作"response.CanRetry = falsectx.JSON(400, response)case errors.Is(err, ErrPromptPermissionDenied):response.Code = 4003response.Message = "无权限删除该提示词"response.Details = "只有提示词创建者可以删除"response.CanRetry = falsectx.JSON(403, response)case errors.Is(err, ErrPromptHasReferences):response.Code = 4004response.Message = "提示词正在被使用"response.Details = "该提示词正在被其他资源引用,无法删除"response.CanRetry = falsectx.JSON(400, response)case errors.Is(err, ErrPromptDeleteRateLimit):response.Code = 4005response.Message = "删除操作过于频繁"response.Details = "请稍后再试"response.CanRetry = truectx.JSON(429, response)case errors.Is(err, ErrImportantPromptDelete):response.Code = 4006response.Message = "重要提示词删除需要管理员权限"response.Details = "该提示词被标记为重要资源,需要管理员权限才能删除"response.CanRetry = falsectx.JSON(403, response)default:response.Code = 5000response.Message = "提示词删除失败"response.Details = "服务器内部错误,请稍后重试"response.CanRetry = truectx.JSON(500, response)}
}

9.3 提示词删除日志记录策略

提示词删除日志级别定义

  • DEBUG:提示词删除详细调试信息,包括参数值、中间结果
  • INFO:提示词删除关键业务流程信息,如删除操作、状态变更
  • WARN:提示词删除潜在问题警告,如引用关系检查、权限警告
  • ERROR:提示词删除错误信息,包括删除失败、权限错误
  • FATAL:提示词删除严重错误,可能导致数据不一致

提示词删除结构化日志格式

// 提示词删除日志记录示例
func (s *PromptApplicationService) DeletePromptResource(ctx context.Context, promptID int64) error {traceID := generateTraceID()ctx = context.WithValue(ctx, "trace_id", traceID)userID := ctxutil.GetUIDFromCtx(ctx)// 记录提示词删除开始logs.CtxInfof(ctx, "DeletePrompt started, userID=%d, promptID=%d, traceID=%s", userID, promptID, traceID)startTime := time.Now()defer func() {duration := time.Since(startTime)logs.CtxInfof(ctx, "DeletePrompt completed, duration=%dms, traceID=%s", duration.Milliseconds(), traceID)}()// 记录关键步骤logs.CtxInfof(ctx, "Validating prompt delete parameters, promptID=%d, traceID=%s", promptID, traceID)// 权限验证日志logs.CtxInfof(ctx, "Validating prompt delete permission, userID=%d, promptID=%d, traceID=%s", userID, promptID, traceID)// 引用关系检查日志logs.CtxInfof(ctx, "Checking prompt references, promptID=%d, traceID=%s", promptID, traceID)// 数据库删除操作日志logs.CtxInfof(ctx, "Deleting prompt from database, promptID=%d, traceID=%s", promptID, traceID)// 索引清理日志logs.CtxInfof(ctx, "Publishing prompt delete event, promptID=%d, traceID=%s", promptID, traceID)return nil
}// 提示词删除操作审计日志
func (s *PromptApplicationService) logPromptDeleteAudit(ctx context.Context, operation string, promptID int64, details map[string]interface{}) {userID := ctx.Value("user_id").(int64)spaceID := ctx.Value("space_id").(int64)traceID := ctx.Value("trace_id").(string)auditLog := map[string]interface{}{"operation":  operation,"prompt_id":  promptID,"user_id":    userID,"space_id":   spaceID,"trace_id":   traceID,"timestamp":  time.Now().Unix(),"details":    details,}logs.CtxInfof(ctx, "Prompt audit log: %+v", auditLog)
}

提示词删除日志内容规范

  • 请求日志:记录用户ID、工作空间ID、提示词ID、删除原因、TraceID
  • 业务日志:记录提示词删除步骤、状态变更、权限验证结果、引用关系检查
  • 性能日志:记录删除接口响应时间、数据库删除时间、ES索引清理时间
  • 错误日志:记录删除错误堆栈、提示词相关上下文信息、影响范围
  • 审计日志:记录提示词的删除操作、删除前状态、删除后清理结果

9.4 提示词删除监控和告警

提示词删除关键指标监控

  • 删除性能:提示词删除响应时间、删除成功率、删除QPS
  • 资源使用:提示词数据库连接数、ES索引清理延迟、内存使用率
  • 业务指标:提示词删除成功率、删除频率分布、重要提示词删除次数
  • 安全指标:权限验证通过率、恶意删除尝试次数、删除频率限制触发次数

提示词删除告警策略

  • 删除失败率告警:当提示词删除失败率超过3%时触发告警
  • 性能告警:当提示词删除响应时间超过2秒时触发告警
  • 资源告警:当提示词数据库连接数超过80%时触发告警
  • 安全告警:当检测到异常删除行为时立即触发告警
  • 数据一致性告警:当MySQL和ES删除状态不一致时触发告警
// 提示词删除监控指标收集
type PromptDeleteMetrics struct {DeleteSuccessCount    int64         // 删除成功次数DeleteFailureCount    int64         // 删除失败次数DeleteLatency         time.Duration // 删除延迟PermissionDeniedCount int64         // 权限拒绝次数RateLimitCount        int64         // 频率限制次数ImportantDeleteCount  int64         // 重要提示词删除次数IndexCleanupLatency   time.Duration // 索引清理延迟
}// 提示词删除监控指标上报
func (s *PromptApplicationService) reportDeleteMetrics(ctx context.Context, operation string, startTime time.Time, promptID int64, err error) {latency := time.Since(startTime)if err != nil {metrics.DeleteFailureCount++// 根据错误类型分类统计switch {case errors.Is(err, ErrPromptPermissionDenied):metrics.PermissionDeniedCount++case errors.Is(err, ErrPromptDeleteRateLimit):metrics.RateLimitCount++}logs.CtxErrorf(ctx, "Prompt %s failed, promptID=%d, error=%v, latency=%dms", operation, promptID, err, latency.Milliseconds())} else {metrics.DeleteSuccessCount++metrics.DeleteLatency = latency// 检查是否为重要提示词删除if isImportant, _ := s.checkPromptImportance(ctx, promptID); isImportant {metrics.ImportantDeleteCount++}logs.CtxInfof(ctx, "Prompt %s succeeded, promptID=%d, latency=%dms", operation, promptID, latency.Milliseconds())}// 上报到监控系统s.metricsReporter.Report(ctx, "prompt_delete", map[string]interface{}{"operation":    operation,"prompt_id":    promptID,"success":      err == nil,"latency_ms":   latency.Milliseconds(),"error_type":   getErrorType(err),})
}// 获取错误类型
func getErrorType(err error) string {if err == nil {return "none"}switch {case errors.Is(err, ErrPromptNotFound):return "not_found"case errors.Is(err, ErrPromptPermissionDenied):return "permission_denied"case errors.Is(err, ErrPromptHasReferences):return "has_references"case errors.Is(err, ErrPromptDeleteRateLimit):return "rate_limit"default:return "system_error"}
}## 10. 提示词删除流程图### 10.1 DeletePrompt接口完整调用流程用户登录 Coze 平台点击"资源库" → 选择提示词 → 点击"...""删除"场景的后端处理流程:

用户点击"删除" → 前端发起请求 → API网关路由 → Handler处理 → 业务服务层 → 数据持久化层 → 索引清理层 → 响应返回
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
前端确认删除 HTTP DELETE请求 路由匹配 参数验证 权限检查 MySQL删除 ES索引清理 JSON响应
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
/delete-prompt /api/plugin_api/ Handler 请求绑定 用户身份 prompt_ 事件发布 删除结果
delete_prompt 函数调用 参数校验 Session resource 异步处理 状态返回
DeletePrompt 验证 表删除 ES清理

PromptApplicationService

权限验证(创建者检查)

引用关系检查

重要性检查

删除频率限制检查

数据库删除事务

删除事件发布

返回删除结果


### 10.2 提示词删除详细流程说明#### 1. API网关层(路由处理)
**文件位置**:`backend/api/handler/coze/prompt_service.go````go
// @router /api/plugin_api/delete_prompt [DELETE]
func DeletePrompt(ctx context.Context, c *app.RequestContext) {var err errorvar req prompt.DeletePromptRequest// 1. 请求参数绑定和验证err = c.BindAndValidate(&req)if err != nil {invalidParamRequestResponse(c, err.Error())return}// 2. 提示词删除参数校验if req.PromptID <= 0 {invalidParamRequestResponse(c, "prompt_id is invalid")return}// 3. 删除确认验证if !req.ConfirmDelete {invalidParamRequestResponse(c, "delete confirmation required")return}// 4. 调用提示词删除服务err = prompt.PromptSVC.DeletePromptResource(ctx, req.PromptID)if err != nil {handlePromptDeleteBusinessError(c, err, req.PromptID)return}// 5. 返回JSON响应c.JSON(consts.StatusOK, gin.H{"success": true,"message": "提示词删除成功","prompt_id": req.PromptID,})
}

处理步骤

  • 路由匹配DELETE /api/plugin_api/delete_prompt
  • 参数绑定:将HTTP请求体绑定到 DeletePromptRequest 结构体
  • 参数验证:验证 prompt_id 的有效性和删除确认标识
  • 服务调用:调用提示词服务的 DeletePromptResource 方法
  • 响应返回:返回JSON格式的删除结果
2. 业务服务层(PromptApplicationService)

文件位置backend/application/prompt/prompt.go

func (p *PromptApplicationService) DeletePromptResource(ctx context.Context, promptID int64) error {// 1. 用户身份验证userID := ctxutil.GetUIDFromCtx(ctx)if userID == nil {return errorx.New(errno.ErrPromptPermissionCode, errorx.KV("msg", "session required"))}// 2. 获取提示词信息进行权限验证promptInfo, err := p.DomainSVC.GetPromptResource(ctx, promptID)if err != nil {if errors.Is(err, gorm.ErrRecordNotFound) {return errorx.New(errno.ErrPromptNotFoundCode, errorx.KV("prompt_id", promptID))}return err}// 3. 验证删除权限(只有创建者可以删除)if promptInfo.CreatorID != userID {return errorx.New(errno.ErrPromptPermissionDeniedCode, errorx.KV("msg", "只有创建者可以删除提示词"),errorx.KV("prompt_id", promptID),errorx.KV("creator_id", promptInfo.CreatorID),errorx.KV("user_id", userID))}// 4. 检查提示词引用关系hasReferences, err := p.checkPromptReferences(ctx, promptID)if err != nil {return fmt.Errorf("检查提示词引用关系失败: %w", err)}if hasReferences {return errorx.New(errno.ErrPromptHasReferencesCode, errorx.KV("prompt_id", promptID),errorx.KV("msg", "提示词正在被其他资源引用,无法删除"))}// 5. 删除安全检查err = p.validateDeleteSafety(ctx, promptID)if err != nil {return err}// 6. 执行删除操作err = p.DomainSVC.DeletePromptResource(ctx, promptID)if err != nil {return fmt.Errorf("删除提示词失败: %w", err)}// 7. 发布删除事件deleteEvent := &entity.ResourceDomainEvent{ResID:      promptID,ResType:    6, // 提示词类型OpType:     entity.Deleted,SpaceID:    promptInfo.SpaceID,OperatorID: userID,OccurredAt: time.Now(),}err = p.eventbus.PublishResources(ctx, deleteEvent)if err != nil {logs.CtxErrorf(ctx, "发布提示词删除事件失败: %v, promptID=%d", err, promptID)// 删除事件发布失败不影响删除操作的成功}return nil
}

核心功能

  • 身份验证:从上下文中提取用户ID,验证用户登录状态
  • 权限检查:验证用户对提示词的删除权限(只有创建者可删除)
  • 引用检查:检查提示词是否被其他资源引用,防止误删
  • 安全验证:验证删除操作的安全性和合规性
  • 数据删除:从数据库中删除提示词记录
  • 事件发布:发布提示词删除事件用于异步清理
  • 响应组装:构建标准化的删除响应数据结构

#### 3. 领域服务层(提示词删除领域服务)
**核心功能**:
- **引用关系检查**:检查提示词是否被其他资源引用
- **删除安全验证**:验证删除操作的安全性
- **重要性评估**:评估提示词的重要性,防止误删重要资源
- **删除权限验证**:验证用户的删除权限```go
// 检查提示词引用关系
func (p *PromptApplicationService) checkPromptReferences(ctx context.Context, promptID int64) (bool, error) {// 1. 检查是否被Bot引用botCount, err := p.botRepo.CountByPromptID(ctx, promptID)if err != nil {return false, fmt.Errorf("检查Bot引用失败: %w", err)}if botCount > 0 {return true, nil}// 2. 检查是否被工作流引用workflowCount, err := p.workflowRepo.CountByPromptID(ctx, promptID)if err != nil {return false, fmt.Errorf("检查工作流引用失败: %w", err)}if workflowCount > 0 {return true, nil}// 3. 检查是否被其他提示词引用promptRefCount, err := p.promptRepo.CountReferences(ctx, promptID)if err != nil {return false, fmt.Errorf("检查提示词引用失败: %w", err)}return promptRefCount > 0, nil
}// 删除安全验证
func (p *PromptApplicationService) validateDeleteSafety(ctx context.Context, promptID int64) error {// 1. 检查删除频率限制userID := ctxutil.GetUIDFromCtx(ctx)deleteCount, err := p.getRecentDeleteCount(ctx, userID)if err != nil {return fmt.Errorf("获取删除频率失败: %w", err)}if deleteCount >= 10 { // 每小时最多删除10个提示词return errorx.New(errno.ErrPromptDeleteRateLimitCode, errorx.KV("msg", "删除操作过于频繁,请稍后再试"),errorx.KV("user_id", userID),errorx.KV("delete_count", deleteCount))}// 2. 检查提示词重要性isImportant, err := p.checkPromptImportance(ctx, promptID)if err != nil {return fmt.Errorf("检查提示词重要性失败: %w", err)}if isImportant {// 重要提示词需要额外确认return errorx.New(errno.ErrPromptImportantDeleteCode,errorx.KV("msg", "这是一个重要的提示词,删除前请确认"),errorx.KV("prompt_id", promptID))}return nil
}// 检查提示词重要性
func (p *PromptApplicationService) checkPromptImportance(ctx context.Context, promptID int64) (bool, error) {// 1. 检查使用频率usageCount, err := p.getPromptUsageCount(ctx, promptID)if err != nil {return false, err}// 2. 检查创建时间(超过30天且使用频率高的认为重要)promptInfo, err := p.DomainSVC.GetPromptResource(ctx, promptID)if err != nil {return false, err}daysSinceCreation := time.Since(promptInfo.CreatedAt).Hours() / 24// 使用频率高且存在时间长的提示词被认为是重要的return usageCount > 100 && daysSinceCreation > 30, nil
}
4. 数据持久化层

MySQL数据库操作

  • 表名prompt_resource
  • 操作类型:DELETE操作
  • 事务处理:确保数据一致性
  • 删除策略:软删除(更新deleted_at字段)或硬删除
  • 关联清理:清理相关的索引和缓存数据
// 提示词删除数据库操作
func (r *PromptRepository) Delete(ctx context.Context, promptID int64) error {// 使用软删除策略query := `UPDATE prompt_resource SET deleted_at = ?, updated_at = ?WHERE id = ? AND deleted_at IS NULL`now := time.Now()result, err := r.db.ExecContext(ctx, query, now, now, promptID)if err != nil {return fmt.Errorf("删除提示词失败: %w", err)}rowsAffected, err := result.RowsAffected()if err != nil {return fmt.Errorf("获取删除结果失败: %w", err)}if rowsAffected == 0 {return errorx.New(errno.ErrPromptNotFoundCode, errorx.KV("prompt_id", promptID),errorx.KV("msg", "提示词不存在或已被删除"))}return nil
}// 硬删除操作(用于彻底清理)
func (r *PromptRepository) HardDelete(ctx context.Context, promptID int64) error {query := `DELETE FROM prompt_resource WHERE id = ?`result, err := r.db.ExecContext(ctx, query, promptID)if err != nil {return fmt.Errorf("硬删除提示词失败: %w", err)}rowsAffected, err := result.RowsAffected()if err != nil {return fmt.Errorf("获取删除结果失败: %w", err)}if rowsAffected == 0 {return errorx.New(errno.ErrPromptNotFoundCode, errorx.KV("prompt_id", promptID))}return nil
}
5. 事件发布层(EventPublisher)

删除事件发布流程

// 提示词删除事件发布
func (p *EventPublisher) PublishPromptDeletedEvent(ctx context.Context, event *entity.PromptDeletedEvent) error {// 1. 构建删除事件消息eventMsg := &message.PromptDeletedMessage{PromptID:   event.PromptID,SpaceID:    event.SpaceID,CreatorID:  event.CreatorID,OperatorID: event.OperatorID,Name:       event.Name,DeletedAt:  event.DeletedAt.Unix(),EventType:  "prompt_deleted",Reason:     event.DeleteReason,}// 2. 序列化事件数据data, err := json.Marshal(eventMsg)if err != nil {return fmt.Errorf("序列化删除事件失败: %w", err)}// 3. 发布到消息队列err = p.messageQueue.Publish(ctx, "prompt_delete_events", data)if err != nil {return fmt.Errorf("发布删除事件失败: %w", err)}logs.CtxInfof(ctx, "Published prompt deleted event, promptID=%d, operator=%d", event.PromptID, event.OperatorID)return nil
}// 异步删除事件处理器
func (h *PromptEventHandler) HandlePromptDeletedEvent(ctx context.Context, event *entity.PromptDeletedEvent) error {// 1. 清理ElasticSearch索引err := h.removeFromESIndex(ctx, event)if err != nil {logs.CtxErrorf(ctx, "Failed to remove from ES index: %v", err)return err}// 2. 清理缓存数据err = h.clearCache(ctx, event)if err != nil {logs.CtxWarnf(ctx, "Failed to clear cache: %v", err)}// 3. 清理相关文件err = h.cleanupFiles(ctx, event)if err != nil {logs.CtxWarnf(ctx, "Failed to cleanup files: %v", err)}// 4. 发送删除通知err = h.sendDeleteNotification(ctx, event)if err != nil {logs.CtxWarnf(ctx, "Failed to send delete notification: %v", err)}// 5. 更新统计数据err = h.updateDeleteStatistics(ctx, event)if err != nil {logs.CtxWarnf(ctx, "Failed to update delete statistics: %v", err)}return nil
}// ElasticSearch索引清理
func (h *PromptEventHandler) removeFromESIndex(ctx context.Context, event *entity.PromptDeletedEvent) error {// 从ES中删除提示词文档err := h.esClient.Delete(ctx, "coze_resource", fmt.Sprintf("%d", event.PromptID))if err != nil {return fmt.Errorf("删除ES索引失败: %w", err)}logs.CtxInfof(ctx, "Removed prompt from ES index, promptID=%d", event.PromptID)return nil
}

删除事件处理内容

  • 索引清理:从ElasticSearch索引中删除提示词文档
  • 缓存清理:清理相关的缓存数据
  • 文件清理:清理提示词相关的文件资源
  • 通知发送:向相关用户发送删除成功通知
  • 统计更新:更新提示词删除相关的统计数据
6. 响应数据结构

DeletePromptResponse

type DeletePromptResponse struct {Code      int64  `json:"code"`       // 响应码Msg       string `json:"msg"`        // 响应消息Success   bool   `json:"success"`    // 删除是否成功PromptID  int64  `json:"prompt_id"`  // 被删除的提示词IDDeletedAt int64  `json:"deleted_at"` // 删除时间戳BaseResp  *base.BaseResp `json:"base_resp"` // 基础响应信息
}

DeletePromptRequest请求结构

type DeletePromptRequest struct {PromptID      int64  `json:"prompt_id" binding:"required"`      // 提示词IDConfirmDelete bool   `json:"confirm_delete" binding:"required"` // 删除确认DeleteReason  string `json:"delete_reason,omitempty"`           // 删除原因(可选)
}

PromptDeletedEvent事件结构

type PromptDeletedEvent struct {PromptID     int64     `json:"prompt_id"`     // 提示词IDSpaceID      int64     `json:"space_id"`      // 工作空间IDCreatorID    int64     `json:"creator_id"`    // 原创建者IDOperatorID   int64     `json:"operator_id"`   // 删除操作者IDName         string    `json:"name"`          // 提示词名称DeleteReason string    `json:"delete_reason"` // 删除原因DeletedAt    time.Time `json:"deleted_at"`    // 删除时间EventType    string    `json:"event_type"`    // 事件类型
}

响应内容说明

  • 成功响应:返回删除成功状态和被删除的提示词ID
  • 错误响应:返回具体的错误码和错误信息(如权限不足、提示词不存在等)
  • 删除确认:要求前端明确确认删除操作
  • 时间戳:记录删除操作的具体时间

11. 核心技术特点

11.1 提示词删除的分层架构设计

清晰的职责分离

  • API层(prompt_handler.go):负责提示词删除请求处理、参数验证、响应格式化
  • 应用层(prompt_service.go):负责提示词删除业务逻辑编排、权限验证、事务管理
  • 领域层(prompt_domain.go):负责提示词删除核心业务逻辑、引用检查、安全验证
  • 基础设施层(prompt_repository.go):负责提示词数据删除、外部服务清理
// 提示词删除的分层调用示例
func (h *PromptHandler) DeletePrompt(ctx context.Context, req *DeletePromptRequest) (*DeletePromptResponse, error) {// API层:参数验证if err := h.validateDeletePromptRequest(req); err != nil {return nil, err}// 调用应用层服务err := h.promptService.DeletePromptResource(ctx, req.PromptID)if err != nil {return nil, err}return &DeletePromptResponse{Code:      0,Msg:       "删除成功",Success:   true,PromptID:  req.PromptID,DeletedAt: time.Now().Unix(),PromptID: promptID,}, nil
}

依赖倒置原则在提示词删除中的应用

  • 高层模块不依赖低层模块,都依赖于抽象接口
  • 通过 PromptRepository 接口实现数据访问层解耦
  • 支持不同存储引擎的灵活切换(MySQL、PostgreSQL等)

11.2 提示词数据存储和索引技术

MySQL存储设计

  • 表结构prompt_resource 表专门存储提示词数据
  • 索引优化:针对 space_idcreator_idname 建立复合索引
  • 事务支持:确保提示词删除的ACID特性
  • 软删除机制:通过 deleted_at 字段实现软删除,保留数据可恢复性
// 提示词数据库表结构(支持软删除)
type PromptResource struct {ID          int64      `gorm:"primaryKey;autoIncrement" json:"id"`SpaceID     int64      `gorm:"index:idx_space_creator;not null" json:"space_id"`Name        string     `gorm:"size:255;not null;index:idx_name_space,unique" json:"name"`Description string     `gorm:"size:1000" json:"description"`PromptText  string     `gorm:"type:text;not null" json:"prompt_text"`Status      string     `gorm:"size:20;default:'draft'" json:"status"`CreatorID   int64      `gorm:"index:idx_space_creator;not null" json:"creator_id"`CreatedAt   time.Time  `gorm:"autoCreateTime" json:"created_at"`UpdatedAt   time.Time  `gorm:"autoUpdateTime" json:"updated_at"`DeletedAt   *time.Time `gorm:"index" json:"deleted_at,omitempty"` // 软删除字段
}

ElasticSearch索引设计

  • 索引名称coze_prompt_resource
  • 字段映射:针对提示词内容进行全文搜索优化
  • 实时同步:通过事件机制实现数据库到ES的实时同步
  • 索引清理:删除提示词时同步清理ES索引数据
// 提示词ES索引映射
type PromptESDocument struct {ID          int64      `json:"id"`SpaceID     int64      `json:"space_id"`Name        string     `json:"name"`Description string     `json:"description"`PromptText  string     `json:"prompt_text"`  // 全文搜索字段Status      string     `json:"status"`CreatorID   int64      `json:"creator_id"`CreatedAt   time.Time  `json:"created_at"`UpdatedAt   time.Time  `json:"updated_at"`DeletedAt   *time.Time `json:"deleted_at,omitempty"` // 软删除标记
}

11.3 提示词删除安全机制

多层次删除验证

  • 权限验证:确保用户有删除指定提示词的权限
  • 引用检查:检查提示词是否被其他资源引用
  • 安全验证:防止恶意删除和批量删除攻击
// 提示词删除验证器
type PromptDeleteValidator struct {referenceChecker ReferenceCheckersecurityChecker  SecurityCheckerpermissionChecker PermissionChecker
}func (v *PromptDeleteValidator) ValidatePromptDeletion(ctx context.Context, promptID, userID int64) error {// 1. 权限检查if !v.permissionChecker.CanDeletePrompt(ctx, userID, promptID) {return errors.New("用户没有删除该提示词的权限")}// 2. 引用关系检查if v.referenceChecker.HasActiveReferences(ctx, promptID) {return errors.New("提示词正在被其他资源使用,无法删除")}// 3. 安全检查if v.securityChecker.IsSuspiciousDeletion(ctx, userID, promptID) {return errors.New("检测到可疑删除行为")}return nil
}

安全防护机制

  • SQL注入防护:使用参数化查询防止恶意删除
  • 权限隔离:确保用户只能删除自己有权限的提示词
  • 操作审计:记录所有删除操作的详细日志
  • 批量删除限制:防止恶意批量删除攻击

11.4 提示词事件驱动架构

事件类型定义

type PromptEventType stringconst (PromptCreated PromptEventType = "prompt_created"  // 提示词创建事件PromptUpdated PromptEventType = "prompt_updated"  // 提示词更新事件PromptDeleted PromptEventType = "prompt_deleted"  // 提示词删除事件
)// 提示词删除事件
type PromptDeletedEvent struct {PromptID    int64     `json:"prompt_id"`SpaceID     int64     `json:"space_id"`Name        string    `json:"name"`CreatorID   int64     `json:"creator_id"`DeleterID   int64     `json:"deleter_id"`DeletedAt   time.Time `json:"deleted_at"`DeleteType  string    `json:"delete_type"` // soft_delete 或 hard_deleteEventType   PromptEventType `json:"event_type"`
}

异步事件处理流程

  1. 提示词删除成功后发布 PromptDeletedEvent
  2. 事件处理器异步清理ElasticSearch索引
  3. 清理相关缓存数据
  4. 发送删除通知给相关用户
  5. 更新统计数据和配额信息
// 提示词删除事件处理器
func (h *PromptEventHandler) HandlePromptDeletedEvent(ctx context.Context, event *PromptDeletedEvent) error {// 1. 清理ES索引if err := h.removeFromESIndex(ctx, event.PromptID); err != nil {logs.CtxErrorf(ctx, "Failed to remove from ES index: %v", err)return err}// 2. 清理缓存if err := h.clearCache(ctx, event.PromptID); err != nil {logs.CtxWarnf(ctx, "Failed to clear cache: %v", err)}// 3. 发送删除通知if err := h.sendDeletionNotification(ctx, event); err != nil {logs.CtxWarnf(ctx, "Failed to send deletion notification: %v", err)}// 4. 更新统计和配额if err := h.updateStatisticsAfterDeletion(ctx, event); err != nil {logs.CtxWarnf(ctx, "Failed to update statistics: %v", err)}return nil
}

11.5 提示词删除权限控制机制

多层次权限验证

  • 身份认证:JWT Token验证用户身份
  • 所有权验证:验证用户是否为提示词的创建者或有删除权限
  • 工作空间权限:验证用户在指定工作空间的删除权限
  • 管理员权限:支持管理员强制删除机制
// 提示词删除权限验证器
type PromptDeletePermissionValidator struct {userService   UserServicespaceService  SpaceServicepromptService PromptService
}func (v *PromptDeletePermissionValidator) ValidateDeletePermission(ctx context.Context, userID, promptID int64) error {// 1. 获取提示词信息prompt, err := v.promptService.GetPromptByID(ctx, promptID)if err != nil {return err}// 2. 验证所有权或删除权限if prompt.CreatorID == userID {return nil // 创建者可以删除}// 3. 验证工作空间删除权限hasDeletePermission, err := v.spaceService.HasDeletePermission(ctx, userID, prompt.SpaceID)if err != nil {return err}if !hasDeletePermission {return errors.New("用户没有删除该提示词的权限")}// 4. 检查管理员权限isAdmin, err := v.userService.IsSpaceAdmin(ctx, userID, prompt.SpaceID)if err != nil {return err}if !isAdmin {return errors.New("只有管理员或创建者可以删除提示词")}return nil
}

11.6 提示词删除性能优化策略

数据库性能优化

  • 软删除索引:为 deleted_at 字段建立索引优化查询性能
  • 批量删除:支持批量软删除操作减少数据库访问
  • 事务优化:合理使用事务确保删除操作的原子性

缓存清理策略

  • Redis缓存清理:删除时及时清理相关缓存数据
  • 本地缓存失效:通过事件机制使本地缓存失效
  • 缓存一致性:确保删除操作后缓存数据的一致性
// 提示词删除缓存管理器
type PromptDeleteCacheManager struct {redisClient redis.ClientlocalCache  cache.Cache
}func (c *PromptDeleteCacheManager) ClearPromptCache(ctx context.Context, promptID int64) error {// 1. 清理Redis缓存cacheKey := fmt.Sprintf("prompt:%d", promptID)if err := c.redisClient.Del(ctx, cacheKey).Err(); err != nil {logs.CtxWarnf(ctx, "Failed to clear Redis cache for prompt %d: %v", promptID, err)}// 2. 清理本地缓存c.localCache.Delete(cacheKey)// 3. 清理相关的列表缓存listCachePattern := fmt.Sprintf("prompt_list:*")if err := c.clearCacheByPattern(ctx, listCachePattern); err != nil {logs.CtxWarnf(ctx, "Failed to clear list cache: %v", err)}return nil
}func (c *PromptDeleteCacheManager) BatchClearCache(ctx context.Context, promptIDs []int64) error {// 批量清理缓存,提高删除性能var cacheKeys []stringfor _, promptID := range promptIDs {cacheKeys = append(cacheKeys, fmt.Sprintf("prompt:%d", promptID))}if err := c.redisClient.Del(ctx, cacheKeys...).Err(); err != nil {return err}return nil
}

异步删除优化

  • 消息队列:使用RocketMQ处理异步删除清理任务
  • 批量清理:批量清理ES索引和缓存提高效率
  • 重试机制:删除失败任务自动重试保证数据一致性
  • 延迟删除:支持延迟硬删除,给用户恢复时间

12. 总结

12.1 提示词删除功能的架构优势

Coze提示词删除功能采用了现代化的分层架构设计,具有以下显著优势:

1. 高可扩展性

  • 分层架构设计使得提示词删除各层职责清晰,便于独立扩展和维护
  • 基于接口的依赖倒置设计支持不同存储引擎的灵活切换
  • 事件驱动架构支持提示词删除相关业务的异步处理,提高系统吞吐量
// 可扩展的提示词删除服务接口设计
type PromptDeleteService interface {SoftDeletePrompt(ctx context.Context, cmd *DeletePromptCommand) errorHardDeletePrompt(ctx context.Context, promptID int64) errorRestorePrompt(ctx context.Context, promptID int64) errorGetDeletedPrompts(ctx context.Context, spaceID int64) ([]*PromptResource, error)
}// 支持多种删除策略的Repository接口
type PromptDeleteRepository interface {SoftDelete(ctx context.Context, promptID int64) errorHardDelete(ctx context.Context, promptID int64) errorRestore(ctx context.Context, promptID int64) errorFindDeletedBySpaceID(ctx context.Context, spaceID int64) ([]*PromptResource, error)
}

2. 高可用性

  • 软删除机制提供数据恢复能力,避免误删除造成的数据丢失
  • 异步事件处理确保提示词删除主流程的稳定性
  • 完善的错误处理和重试机制保证删除操作的最终一致性

3. 高性能

  • 软删除避免了物理删除的高成本操作
  • 批量删除和缓存清理策略提升删除效率
  • 异步清理机制减少删除操作对系统性能的影响

4. 高安全性

  • 多层次的删除权限验证机制(身份认证 + 所有权验证 + 管理员权限)
  • 引用关系检查防止误删除正在使用的提示词
  • 操作审计和日志记录确保删除操作的可追溯性

12.2 提示词删除功能的技术亮点

1. 智能化的软删除机制

  • 针对提示词删除特点设计的软删除策略
  • 支持数据恢复和延迟硬删除机制
  • 合理的索引设计优化删除查询场景
// 针对提示词删除优化的表结构设计
CREATE TABLE prompt_resource (id BIGINT PRIMARY KEY AUTO_INCREMENT,space_id BIGINT NOT NULL,name VARCHAR(255) NOT NULL,description VARCHAR(1000),prompt_text TEXT NOT NULL,status VARCHAR(20) DEFAULT 'draft',creator_id BIGINT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,deleted_at TIMESTAMP NULL DEFAULT NULL,  -- 软删除字段INDEX idx_space_creator (space_id, creator_id),UNIQUE INDEX idx_name_space (name, space_id),INDEX idx_status (status),INDEX idx_deleted_at (deleted_at),  -- 软删除索引INDEX idx_created_at (created_at)
);

2. 智能化的删除安全机制

  • 多维度的删除安全验证(权限、引用、安全性)
  • 可配置的删除策略支持不同业务场景
  • 实时的引用关系检测防止误删除

3. 事件驱动的删除清理

  • 基于提示词删除事件实现数据库到ES的实时清理
  • 保证了删除操作的最终一致性
  • 支持事件重放和数据恢复机制
// 提示词删除事件驱动清理示例
func (s *PromptDeleteService) DeletePrompt(ctx context.Context, cmd *DeletePromptCommand) error {// 1. 软删除提示词err := s.promptRepo.SoftDelete(ctx, cmd.PromptID)if err != nil {return err}// 2. 发布删除事件event := &PromptDeletedEvent{PromptID:   cmd.PromptID,SpaceID:    cmd.SpaceID,DeleterID:  cmd.UserID,DeletedAt:  time.Now(),DeleteType: "soft_delete",}s.eventPublisher.PublishPromptDeletedEvent(ctx, event)return nil
}

4. 精细化的删除权限控制

  • 所有权和管理员权限的双重验证
  • 引用关系检查防止误删除
  • 灵活的删除策略支持不同角色需求

12.3 提示词删除系统的扩展性和可维护性

扩展性设计

  • 删除策略扩展:支持多种删除策略(软删除、硬删除、归档)
  • 功能扩展:基于接口设计支持新的删除功能快速接入
  • 业务扩展:事件驱动架构支持新的删除业务场景的灵活集成

可维护性保障

  • 代码结构清晰:分层架构和领域驱动设计提高删除逻辑的可读性
  • 测试覆盖完善:单元测试和集成测试保证删除功能的质量
  • 监控体系完备:全链路追踪和删除操作监控便于问题定位
// 可维护的删除错误处理示例
func (s *PromptDeleteService) DeletePrompt(ctx context.Context, cmd *DeletePromptCommand) error {// 记录删除操作开始logs.CtxInfof(ctx, "Start deleting prompt, promptID=%d, userID=%d", cmd.PromptID, cmd.UserID)defer func() {// 记录删除操作结束logs.CtxInfof(ctx, "Finish deleting prompt, promptID=%d", cmd.PromptID)}()// 删除业务逻辑处理...return nil
}

通过以上的架构设计和技术实现,Coze提示词删除功能为用户提供了高效、安全、可靠的提示词删除管理服务,为AI应用开发中的提示词生命周期管理提供了强有力的基础设施支撑。该系统不仅满足了当前的删除业务需求,还具备了良好的扩展性和可维护性,能够适应未来删除策略和恢复机制的发展需要。

删除功能的核心价值

  • 数据安全:软删除机制保障数据安全,避免误删除造成的损失
  • 操作便捷:简单直观的删除操作,提升用户体验
  • 系统稳定:异步处理和事件驱动确保删除操作不影响系统稳定性
  • 可追溯性:完整的操作日志和审计记录,便于问题排查和数据恢复
http://www.xdnf.cn/news/19928.html

相关文章:

  • 正运动控制卡学习-点动
  • 景区负氧离子气象站:引领绿色旅游,畅吸清新每一刻
  • Vue3 中后台管理系统权限管理实现
  • Spring MVC 扩展机制对比总结:@Configuration + WebMvcConfigurer vs @ControllerAdvice
  • Spring Boot 启动卡死:循环依赖与Bean初始化的深度分析
  • 【问题记录】Anaconda的jupyter NoteBook点击launch的时候,弹出的页面提示ERR_FILE_NOT_FOUND
  • 【Linux我做主】细说进程等待
  • 20.35 ChatGLM3-6B QLoRA实战:4bit量化+低秩适配,显存直降70%!
  • 重温经典之游戏模拟器选型指南
  • java注解、Lambda表达式、Servlet
  • Web安全:你所不知道的HTTP Referer注入攻击
  • 【PZ-AU15P】璞致fpga开发板 Aritx UltraScalePlus PZ-AU15P 核心板与开发板用户手册
  • 新客户 | TDengine 时序数据库赋能开源鸿蒙物联展区实时监控与展示
  • 解决 ES 模块与 CommonJS 模块互操作性的关键开关esModuleInterop
  • AI+ 行动意见解读:音视频直播SDK如何加速行业智能化
  • Excel ——INDEX + MATCH 组合
  • [iOS] 折叠 cell
  • Fiddler 实战案例解析,开发者如何用抓包工具快速解决问题
  • 鸿蒙分布式数据同步失败全解
  • jenkins使用ansible单节点lnmp
  • Nvidia Orin DK 本地 ollama 主流 20GB 级模型 gpt-oss, gemma3, qwen3 部署与测试
  • AI搜索排名规则突变:企业如何用GEO工具保持竞争力?
  • LeetCode 刷题【64. 最小路径和】
  • 无人机气象观测技术
  • 华为的 4A 架构简介
  • 代码随想录算法训练营第二十八天 | 买卖股票的最佳实际、跳跃游戏、K次取反后最大化的数组和
  • Vue基础知识-脚手架开发-初始化目录解析
  • 分布式对象存储系统 Minio 之 Centos 环境安装
  • SQLynx 3.7 发布:数据库管理工具的性能与交互双重进化
  • Java 方法:从定义调用到重载,入门到面试全攻略