Files
geo/docs/superpowers/specs/2026-04-16-kol-feature-design.md
T
root 3ef0807456 fix: Enhance Kol Variable Rendering and Management
- Updated the regex for placeholder matching to support more flexible key formats.
- Refactored variable storage to allow both ID and key lookups in rendering.
- Improved schema validation to check for duplicate keys and enforce non-empty keys.
- Added new utility functions for variable value lookup and display name generation.
- Enhanced tests to cover new key-based variable scenarios.
- Refactored KolPrompt repository to simplify prompt storage and management, including the removal of obsolete revision handling.
- Introduced new API endpoints for saving, activating, and archiving prompts.
- Added new utility functions for handling Kol placeholders and platform options in the admin web.
- Implemented database migrations to simplify prompt storage structure and ensure data integrity.
2026-04-18 00:47:57 +08:00

26 KiB
Raw Blame History

KOL 功能设计文档(v3 — 第一方 KOL 方案,不依赖 share codes

本文档替代此前所有基于 prompt_share_profiles / prompt_share_codes 的 KOL 方案描述。 share_code_id 仍然保留在 article_templates 现有表结构中作为历史遗留字段,但 KOL 功能不再依赖它

概述

为 GEO 平台新增第一方 KOL 功能模块。KOL 是一种面向租户端产品能力的创作者身份:KOL 在自己的租户内编写、发布和运营精调 prompt 包,其他租户可以在市场中浏览并申请订阅;订阅成功后,订阅租户获得对对应 KOL prompt 的使用权,并通过专用 KOL 生成链路产出文章。

本方案的核心目标:

  • 去旧方案依赖:不再复用 prompt_share_profilesprompt_share_codesshare_code_id
  • 生成链路独立KOL 文章走独立的 source_type='kol' / task_type='kol'
  • 权限边界清晰:KOL 工作台属于租户端产品能力,审批与风控属于平台端能力
  • 历史可追溯Prompt 发布版本、变量 schema、使用快照、任务和文章链路完整可追踪

核心概念

  • KOL ProfileKOL 创作者身份,绑定一个 user_id + tenant_id
  • KOL PackageKOL 发布的一组 prompt 的业务包
  • KOL Prompt:包内单个 prompt 的逻辑实体
  • KOL Prompt Revisionprompt 的不可变发布/草稿修订
  • KOL Subscription:订阅租户对某个 package 的订阅关系
  • KOL Subscription Prompt Access:订阅生效后,租户对包内某个 prompt 的访问授权
  • KOL Usage Log:每次生成请求的审计与结算基础记录

设计原则

  1. KOL 是第一方模型,不是旧分享模型的变体
  2. KOL 原始 prompt 不写入 article_templates
  3. KOL 生成只走专用 API 与专用 worker 分支
  4. V1 不接入通用模板选择器,避免绕过订阅鉴权
  5. 租户端能力留在 tenant-api,平台审批留在 platform-api

1. 架构定位

1.1 边界划分

能力 归属 说明
市场浏览、包详情、申请订阅 tenant-api 面向租户端用户的产品能力
KOL 工作台、Prompt 编辑、KOL 看板 tenant-api KOL 在自己租户内使用
订阅审批、KOL Profile 开通/冻结 platform-api 平台运营能力
文章生成执行 worker-generate 复用既有队列、额度、任务状态框架

1.2 与现有系统的关系

现有模块 复用方式
articles 复用,新增 source_type='kol'kol_prompt_id
generation_tasks 复用,新增 task_type='kol'
article_versions 复用,生成成功后正常写入
quota_reservations / tenant_quota_ledgers 复用,遵守既有事务边界
task_records + SSE 复用,前端感知生成进度
template_assist_tasks 不复用,新建 kol_assist_tasks
article_templates 不作为 KOL 原始 prompt 存储;share_code_id 对 KOL 无意义

1.3 V1 显式不做

  • 不复活旧的 share code 导入/物化方案
  • 不把 KOL prompt 接入通用 /articles/template 生成链路
  • 不把 KOL prompt 存成订阅方的 article_templates
  • 不做在线支付、分账、提现
  • 不做 KOL 多租户归属切换

2. 数据模型

2.1 新增表

kol_profiles — KOL 创作者身份

CREATE TABLE kol_profiles (
    id              BIGSERIAL PRIMARY KEY,
    tenant_id       BIGINT NOT NULL REFERENCES tenants(id),
    user_id         BIGINT NOT NULL REFERENCES users(id),
    display_name    VARCHAR(100) NOT NULL,
    bio             TEXT,
    avatar_url      TEXT,
    market_enabled  BOOLEAN NOT NULL DEFAULT FALSE,
    status          VARCHAR(20) NOT NULL DEFAULT 'active', -- active / suspended / closed
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at      TIMESTAMPTZ
);
CREATE UNIQUE INDEX uk_kol_profile_user_active
    ON kol_profiles(user_id)
    WHERE deleted_at IS NULL;
CREATE INDEX idx_kol_profile_tenant
    ON kol_profiles(tenant_id)
    WHERE deleted_at IS NULL;

设计要点:

  • 一个用户在 V1 仅允许有一个 active KOL Profile
  • tenant_id 是 KOL 的归属租户,也是 AI 辅助费用归属租户
  • KOL Profile 不是 platform_role,也不是 tenant_role,而是第一方业务身份

kol_packages — KOL 订阅包

CREATE TABLE kol_packages (
    id              BIGSERIAL PRIMARY KEY,
    tenant_id       BIGINT NOT NULL REFERENCES tenants(id),
    kol_profile_id  BIGINT NOT NULL REFERENCES kol_profiles(id),
    name            VARCHAR(200) NOT NULL,
    description     TEXT,
    cover_url       TEXT,
    industry        VARCHAR(100),
    tags            JSONB NOT NULL DEFAULT '[]',
    price_note      VARCHAR(200),
    status          VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft / published / archived
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at      TIMESTAMPTZ
);
CREATE INDEX idx_kol_package_profile
    ON kol_packages(kol_profile_id, created_at DESC)
    WHERE deleted_at IS NULL;
CREATE INDEX idx_kol_package_status
    ON kol_packages(status, created_at DESC)
    WHERE deleted_at IS NULL;

设计要点:

  • tenant_id 是创作者租户,不是订阅租户
  • 包可以是全局可见资源,但 ownership 仍然属于创作者租户
  • 市场只展示 status='published'kol_profiles.market_enabled=true
  • 市场列表/详情是跨租户查询/api/tenant/kol/marketplace/* 是已知 tenant-scope 豁免点,实施时不能复用默认“按当前 tenant_id 过滤”的仓储查询
  • 实施建议:优先在 service 层做跨租户聚合查询;若落在 tenant 仓储 SQL,则需为该查询显式标注 tenant-scope exemption,并同步调整 check_tenant_scope.sh 的豁免策略

kol_prompts — KOL Prompt 逻辑主表

CREATE TABLE kol_prompts (
    id                    BIGSERIAL PRIMARY KEY,
    tenant_id             BIGINT NOT NULL REFERENCES tenants(id),
    package_id            BIGINT NOT NULL REFERENCES kol_packages(id),
    name                  VARCHAR(200) NOT NULL,
    platform_hint         VARCHAR(100),
    status                VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft / active / archived
    sort_order            INT NOT NULL DEFAULT 0,
    published_revision_no INT,
    draft_revision_no     INT,
    created_by            BIGINT NOT NULL REFERENCES users(id),
    updated_by            BIGINT NOT NULL REFERENCES users(id),
    created_at            TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at            TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    deleted_at            TIMESTAMPTZ
);
CREATE INDEX idx_kol_prompt_package
    ON kol_prompts(package_id, sort_order, created_at)
    WHERE deleted_at IS NULL;
CREATE INDEX idx_kol_prompt_tenant_status
    ON kol_prompts(tenant_id, status, created_at DESC)
    WHERE deleted_at IS NULL;

设计要点:

  • kol_prompts 是逻辑实体,不直接存放 prompt 原文
  • 当前可用版本通过 published_revision_no 指向
  • KOL 编辑时创建新 revision;发布时切换 published_revision_no

kol_prompt_revisions — KOL Prompt 不可变修订

CREATE TABLE kol_prompt_revisions (
    id                 BIGSERIAL PRIMARY KEY,
    tenant_id          BIGINT NOT NULL REFERENCES tenants(id),
    prompt_id          BIGINT NOT NULL REFERENCES kol_prompts(id),
    revision_no        INT NOT NULL,
    prompt_asset_key   TEXT NOT NULL,         -- 受保护资产 key
    schema_json        JSONB NOT NULL DEFAULT '{}',
    card_config_json   JSONB NOT NULL DEFAULT '{}',
    created_by         BIGINT NOT NULL REFERENCES users(id),
    created_at         TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE (prompt_id, revision_no)
);
CREATE INDEX idx_kol_prompt_revision_prompt
    ON kol_prompt_revisions(prompt_id, revision_no DESC);

设计要点:

  • 原始 prompt 正文只存受保护资产,不回传前端
  • schema_jsoncard_config_json 与 prompt 正文一起冻结在 revision 中
  • 历史生成任务通过 prompt_id + revision_no 可精确回放

kol_subscriptions — 租户级订阅关系

CREATE TABLE kol_subscriptions (
    id              BIGSERIAL PRIMARY KEY,
    tenant_id       BIGINT NOT NULL REFERENCES tenants(id),   -- 订阅方租户
    package_id      BIGINT NOT NULL REFERENCES kol_packages(id),
    status          VARCHAR(20) NOT NULL DEFAULT 'pending',   -- pending / active / expired / revoked
    approved_by     BIGINT REFERENCES users(id),
    start_at        TIMESTAMPTZ,
    end_at          TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX uk_kol_subscription_active
    ON kol_subscriptions(tenant_id, package_id)
    WHERE status IN ('pending', 'active');
CREATE INDEX idx_kol_subscription_package
    ON kol_subscriptions(package_id, status, created_at DESC);

设计要点:

  • 订阅主体是 tenant,不是单个 user
  • 审批与撤销都以 tenant 为单位
  • 结算、看板、风控也以 tenant 为统计口径

kol_subscription_prompts — 订阅生效后的 prompt 访问授权

CREATE TABLE kol_subscription_prompts (
    id               BIGSERIAL PRIMARY KEY,
    tenant_id        BIGINT NOT NULL REFERENCES tenants(id),
    subscription_id  BIGINT NOT NULL REFERENCES kol_subscriptions(id),
    package_id       BIGINT NOT NULL REFERENCES kol_packages(id),
    prompt_id        BIGINT NOT NULL REFERENCES kol_prompts(id),
    status           VARCHAR(20) NOT NULL DEFAULT 'active', -- active / revoked
    granted_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    revoked_at       TIMESTAMPTZ,
    created_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at       TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX uk_kol_subscription_prompt
    ON kol_subscription_prompts(subscription_id, prompt_id);
CREATE INDEX idx_kol_subscription_prompt_tenant
    ON kol_subscription_prompts(tenant_id, status, created_at DESC);

设计要点:

  • 这是新的“订阅后可用 prompt”映射表,用来替代旧的 share code / 物化模板模型
  • 订阅审批通过时,为当前包内所有 active prompt 创建 access row
  • 包后续新增 prompt 时,为所有 active 订阅补齐 access row
  • 撤订或 prompt 下架时,access row 置为 revoked

kol_usage_logs — 使用与审计记录

CREATE TABLE kol_usage_logs (
    id                     BIGSERIAL PRIMARY KEY,
    tenant_id              BIGINT NOT NULL REFERENCES tenants(id),
    subscription_id        BIGINT REFERENCES kol_subscriptions(id),
    subscription_prompt_id BIGINT REFERENCES kol_subscription_prompts(id),
    package_id             BIGINT NOT NULL REFERENCES kol_packages(id),
    prompt_id              BIGINT NOT NULL REFERENCES kol_prompts(id),
    prompt_revision_no     INT NOT NULL,
    article_id             BIGINT REFERENCES articles(id),
    generation_task_id     BIGINT REFERENCES generation_tasks(id),
    status                 VARCHAR(20) NOT NULL DEFAULT 'pending', -- pending / completed / failed
    variables_snapshot     JSONB,
    schema_snapshot        JSONB,
    rendered_prompt_hash   VARCHAR(64),
    error_message          TEXT,
    created_at             TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    finished_at            TIMESTAMPTZ
);
CREATE INDEX idx_kol_usage_package
    ON kol_usage_logs(package_id, created_at DESC);
CREATE INDEX idx_kol_usage_tenant
    ON kol_usage_logs(tenant_id, created_at DESC);
CREATE INDEX idx_kol_usage_prompt
    ON kol_usage_logs(prompt_id, created_at DESC);

设计要点:

  • status 明确进入表结构,解决 pending/completed/failed 口径不一致问题
  • prompt_revision_no + schema_snapshot + variables_snapshot + rendered_prompt_hash 组成完整审计快照
  • generation_task_idarticle_id 关联后可闭合结算与故障追踪链

kol_assist_tasks — KOL AI 辅助任务

CREATE TABLE kol_assist_tasks (
    id              VARCHAR(64) PRIMARY KEY,
    tenant_id       BIGINT NOT NULL REFERENCES tenants(id),
    kol_profile_id  BIGINT NOT NULL REFERENCES kol_profiles(id),
    prompt_id       BIGINT REFERENCES kol_prompts(id),
    operator_id     BIGINT NOT NULL REFERENCES users(id),
    task_type       VARCHAR(50) NOT NULL, -- ai_generate / ai_optimize
    status          VARCHAR(20) NOT NULL DEFAULT 'queued',
    request_json    JSONB NOT NULL DEFAULT '{}'::jsonb,
    result_json     JSONB,
    error_message   TEXT,
    started_at      TIMESTAMPTZ,
    completed_at    TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_kol_assist_tenant_profile
    ON kol_assist_tasks(tenant_id, kol_profile_id, created_at DESC);
CREATE INDEX idx_kol_assist_status
    ON kol_assist_tasks(status, created_at DESC);

设计要点:

  • kol_assist_tasks.tenant_id计费租户,必须始终写入 kol_profiles.tenant_id
  • 实施时禁止直接使用当前请求的 actor.TenantID 作为兜底来源;即使 V1 中两者相同,也要先解析 profile 后再写任务记录
  • 这样后续即使支持 KOL 多租户归属切换,历史费用归属也不会歧义

2.2 现有表变更

articles 表

新增字段:

  • kol_prompt_id BIGINT REFERENCES kol_prompts(id)

新增 source_type 值:

  • kol

说明:

  • KOL 文章不依赖 template_id
  • template_id 对 KOL 文章保持 NULL

generation_tasks 表

新增 task_type 值:

  • kol

input_params_json 示例:

{
  "subscription_prompt_id": 901,
  "prompt_id": 42,
  "prompt_revision_no": 7,
  "variables": {
    "var_a1b2c3": "宜家家居",
    "var_d4e5f6": "家具"
  },
  "schema_snapshot": {
    "variables": []
  },
  "rendered_prompt_hash": "a1b2c3d4..."
}

article_templates 表

无 KOL 专属新增值。

说明:

  • KOL 原始 prompt 不写入 article_templates
  • 旧字段 share_code_id 继续保留,但 KOL 不使用

3. Prompt 变量与版本模型

3.1 schema_json 格式

{
  "variables": [
    {
      "id": "var_a1b2c3",
      "key": "公司名称",
      "label": "公司名称",
      "type": "input",
      "required": true,
      "placeholder": "请输入您的公司名"
    },
    {
      "id": "var_d4e5f6",
      "key": "行业",
      "label": "行业",
      "type": "select",
      "options": ["家具", "建材", "家电"],
      "required": true
    }
  ]
}

设计要点:

  • 每个变量有不可变 id
  • Prompt 正文内部只引用 {{id}}
  • 前端展示 label,提交时按 id -> value 映射
  • 修改 key/label 不会破坏既有 prompt 引用

3.2 修订规则

  • 每次保存草稿,创建新的 kol_prompt_revisions.revision_no
  • kol_prompts.draft_revision_no 指向最新草稿
  • 点击发布时,把 published_revision_no 切到当前草稿修订
  • status='active' 的 prompt 必须有 published_revision_no

3.3 历史复现

历史生成记录依赖以下字段重建:

  • prompt_id
  • prompt_revision_no
  • schema_snapshot
  • variables_snapshot
  • rendered_prompt_hash

因此即使 KOL 后续继续编辑 prompt,历史记录仍可审计、对账和回放。


4. 页面结构与路由

4.1 侧边栏导航

现有导航:
  Workspace
  文章创作: 模版生成 | 自定义生成 | 自由创作 | 发布管理
  品牌管理: 品牌库
  品牌追踪: 追踪详情
  内容管理: 知识库 | 图片库

新增:
  KOL 市场: 模版市场                  ← 所有用户可见
  KOL 工作台: 提示词管理 | 数据看板    ← 仅 active kol_profile 可见

4.2 新增路由

路由 组件 角色 说明
/kol/marketplace KolMarketplaceView 所有用户 浏览 KOL 包
/kol/packages/:id KolPackageDetailView 所有用户 包详情与订阅
/kol/generate/:subscriptionPromptId KolGenerateView 已订阅租户 动态表单生成
/kol/manage KolManageView 仅 KOL 包与 prompt 管理
/kol/dashboard KolDashboardView 仅 KOL KOL 数据看板

4.3 用户入口

  1. 侧边栏「模版市场」进入市场浏览与订阅
  2. Workspace 新增「KOL Prompt 卡片区」,展示当前租户可用的 kol_subscription_prompts
  3. V1 不把 KOL prompt 放入通用模板选择器

5. API 设计

5.1 市场与订阅(tenant API

GET    /api/tenant/kol/marketplace/packages
GET    /api/tenant/kol/marketplace/packages/:id
POST   /api/tenant/kol/marketplace/packages/:id/subscribe
GET    /api/tenant/kol/subscriptions
GET    /api/tenant/kol/subscription-prompts
GET    /api/tenant/kol/subscription-prompts/:id

说明:

  • /marketplace/* 返回全局已发布包
  • /subscriptions/subscription-prompts 只返回当前租户数据
  • /api/tenant/kol/marketplace/* 属于 tenant-api 中少数跨租户读场景;实施时需显式声明 tenant-scope exemption

5.2 KOL 生成(tenant API

GET    /api/tenant/kol/subscription-prompts/:id/schema
POST   /api/tenant/kol/subscription-prompts/:id/generate

说明:

  • :idkol_subscription_prompts.id
  • 后端根据 access row 反查 package、prompt、published revision
  • 生成请求只接受变量值,不接受 prompt 原文

5.3 KOL 工作台(tenant API

GET    /api/tenant/kol/manage/profile

GET    /api/tenant/kol/manage/packages
POST   /api/tenant/kol/manage/packages
PUT    /api/tenant/kol/manage/packages/:id
DELETE /api/tenant/kol/manage/packages/:id
PUT    /api/tenant/kol/manage/packages/:id/publish
PUT    /api/tenant/kol/manage/packages/:id/archive

GET    /api/tenant/kol/manage/packages/:id/prompts
POST   /api/tenant/kol/manage/packages/:id/prompts
PUT    /api/tenant/kol/manage/prompts/:id
DELETE /api/tenant/kol/manage/prompts/:id
POST   /api/tenant/kol/manage/prompts/:id/publish

POST   /api/tenant/kol/manage/assist/generate
POST   /api/tenant/kol/manage/assist/optimize

说明:

  • 工作台不走 /api/platform/kol/*
  • 只有 kol_profiles.tenant_id = actor.TenantID AND user_id = actor.UserID 的用户可操作

5.4 KOL 看板(tenant API

GET    /api/tenant/kol/dashboard/overview
GET    /api/tenant/kol/dashboard/packages
GET    /api/tenant/kol/dashboard/trend

5.5 平台管理员操作(platform API

POST   /api/platform/admin/kol/profiles
PUT    /api/platform/admin/kol/profiles/:id/suspend
PUT    /api/platform/admin/kol/profiles/:id/activate

PUT    /api/platform/admin/kol/subscriptions/:id/approve
POST   /api/platform/admin/kol/subscriptions
PUT    /api/platform/admin/kol/subscriptions/:id/revoke

6. 订阅与授权生命周期

6.1 申请订阅

  1. 用户在市场页点击「申请订阅」
  2. 创建 kol_subscriptions(status='pending')
  3. 等待平台管理员审批

6.2 审批通过

  1. 平台管理员把订阅改为 active
  2. 在同一事务或紧随其后的授权任务中,为该 package 当前所有 active prompt 创建 kol_subscription_prompts
  3. Workspace 的 KOL 卡片区开始展示这些 prompt

6.3 包后续新增 prompt

  1. KOL 在已发布包下新建并发布 prompt
  2. 系统为所有 active 订阅补写 kol_subscription_prompts
  3. 新 prompt 自动出现在订阅租户的 KOL 卡片区

实现建议:

  • 订阅审批时可同步插入 access rows
  • “已发布包新增 prompt” 建议走异步任务,避免大批量订阅阻塞发布请求
  • 异步分发复用现有 task_records 可观测能力

6.4 订阅过期处理

V1 口径:

  • 不做自动过期任务
  • kol_subscriptions.end_at 仅在读时与生成鉴权时实时校验
  • end_at < now() 时,即使 status 仍为 active,生成接口也必须拒绝访问
  • 列表页、看板统计口径应把“status='active' 且当前时间仍在有效期内”视为有效订阅
  • 后续如需引入 scheduler,再补“批量把过期订阅改为 expired + 回收 access rows”的异步清理任务

6.5 撤销订阅

  1. 平台管理员把订阅改为 revoked
  2. 把该订阅下所有 kol_subscription_prompts 置为 revoked
  3. Workspace KOL 卡片区不再展示
  4. 生成接口返回 403

6.6 Prompt 下架

  1. KOL 把 prompt 标记为 archived
  2. 对应的 kol_subscription_prompts 置为 revoked
  3. 已生成文章保留,后续新生成禁止

7. 生成链路

严格遵循现有架构中的事务、额度、幂等和 worker 回写规则。

7.1 提交前校验

生成前必须逐项校验:

  1. kol_subscription_prompts.id 存在且 status='active'
  2. access row 的 tenant_id = 当前租户
  3. 对应 kol_subscriptions.status='active'
  4. 订阅在有效期内
  5. kol_packages.status='published'
  6. kol_prompts.status='active'
  7. kol_prompts.published_revision_no IS NOT NULL

7.2 提交路径(单 PostgreSQL 事务)

  1. 读取 kol_prompts.published_revision_no
  2. 读取对应 kol_prompt_revisions
  3. 渲染变量并计算 rendered_prompt_hash
  4. 单事务内执行:
    • 额度预扣与 reservation 创建
    • 创建 articles(source_type='kol', kol_prompt_id=...)
    • 创建 generation_tasks(task_type='kol', request_hash=rendered_prompt_hash)
    • 创建 kol_usage_logs(status='pending')
    • 创建 task_records
  5. 事务提交后发送队列消息

7.3 Worker 执行路径

Worker 处理 task_type='kol' 时:

  1. generation_tasks.input_params_json 读取 prompt_id + prompt_revision_no
  2. 加载对应 revision 的受保护 prompt 资产
  3. 组装模型请求
  4. 生成文章内容

7.4 成功路径(单 PostgreSQL 事务)

  • 写入 article_versions
  • 更新 articles.generate_status='completed'
  • 确认额度消耗
  • 更新 kol_usage_logs.status='completed'
  • 回写 article_idfinished_at

7.5 失败路径(单 PostgreSQL 事务)

  • 更新 generation_tasks.status='failed'
  • 释放或退还额度
  • 更新 kol_usage_logs.status='failed'
  • 写入 error_messagefinished_at

7.6 幂等键

幂等规则:

  • tenant_id + source_type('kol') + request_hash(rendered_prompt_hash) + schedule_slot(null)

说明:

  • 与现有生成体系一致
  • KOL 不做定时调度,因此 schedule_slot = null

8. KOL Prompt 编辑器

8.1 包管理

  • 仅展示当前 KOL 在当前租户下创建的包
  • 支持创建、编辑、发布、归档
  • 已发布包允许继续新增 prompt

8.2 Prompt 编辑器

三栏布局:

  • 左栏:变量组件面板
  • 中栏:Prompt 编辑区 + AI 辅助
  • 右栏:变量配置面板

8.3 编辑规则

  1. 拖拽变量组件到编辑区
  2. 系统生成不可变 var_xxx 变量 ID
  3. 编辑器显示 {{公司名称}}
  4. 底层正文始终写成 {{var_xxx}}
  5. 保存草稿时创建新 revision
  6. 发布时切换 published_revision_no

8.4 AI 辅助

  • AI 生成:根据场景描述生成 prompt 草稿
  • AI 优化:对当前草稿 revision 进行优化建议
  • 异步任务写入 kol_assist_tasks
  • 费用记到 kol_profiles.tenant_id

8.5 Prompt 内容保护

  • 正文存入受保护资产,前端不回传
  • 普通用户只获取 schema_json
  • 订阅租户无法查看原始 prompt 正文

9. 数据看板

9.1 指标

  • 总订阅租户数
  • 本月新增订阅
  • 总使用次数
  • 本月使用次数
  • 失败次数与失败率

9.2 维度

  • 按包:订阅租户数、使用次数、失败率
  • 按 prompt:使用排行、失败排行
  • 按时间:订阅趋势、使用趋势

9.3 数据来源

  • 订阅:kol_subscriptions
  • 授权:kol_subscription_prompts
  • 使用:kol_usage_logs

10. Workspace 与文章集成

10.1 Workspace

新增接口:

GET /api/tenant/workspace/kol-cards

返回当前租户可用的 KOL prompt 卡片:

  • 包名
  • Prompt 名称
  • KOL 显示名
  • 平台标识
  • subscription_prompt_id

10.2 文章列表

文章列表对 source_type='kol' 展示:

  • 来源标签:KOL 生成
  • 关联 prompt 名称
  • 关联 package 名称

10.3 明确不做的集成

  • V1 不把 KOL prompt 混入 template-cards
  • V1 不接入 /api/tenant/templates/*
  • V1 不接入通用模板向导页面

这样可以避免普通模板链路绕过 KOL 的订阅鉴权和 usage 埋点。


11. 权限与鉴权

11.1 KOL 身份

满足以下条件才视为 KOL

  • kol_profiles.user_id = actor.UserID
  • kol_profiles.tenant_id = actor.TenantID
  • kol_profiles.status = 'active'

说明:

  • status='active' 决定能否进入 KOL 工作台
  • market_enabled=true 只决定是否能在市场中对外展示

11.2 接口鉴权

路径前缀 鉴权方式 说明
/api/tenant/kol/marketplace/* 标准 tenant 身份 市场浏览与订阅
/api/tenant/kol/subscription-prompts/* tenant + access row 生成
/api/tenant/kol/manage/* tenant + active kol_profile 工作台
/api/tenant/kol/dashboard/* tenant + active kol_profile 看板
/api/platform/admin/kol/* platform_role 平台运营

11.3 审计

高风险操作必须写审计日志:

  • KOL Profile 开通、冻结、恢复
  • 订阅审批、撤销
  • Prompt 发布、归档
  • KOL 包发布、归档

12. i18n

新增 kol 命名空间:

kol.marketplace.title
kol.marketplace.filter.*
kol.package.subscribe
kol.package.pending
kol.package.subscribed
kol.generate.title
kol.generate.submit
kol.manage.title
kol.manage.createPackage
kol.manage.editor.*
kol.dashboard.title
kol.dashboard.totalSubs
kol.dashboard.monthSubs
kol.dashboard.totalUsage
kol.dashboard.monthUsage
kol.dashboard.failRate
nav.kolMarketplace
nav.kolManage
nav.kolDashboard
status.sourceType.kol

13. 第一版范围

第一版做

  • kol_profiles
  • kol_packages
  • kol_prompts + kol_prompt_revisions
  • kol_subscriptions + kol_subscription_prompts
  • KOL 市场浏览与申请订阅
  • KOL 工作台与三栏编辑器
  • AI 辅助生成/优化
  • KOL 专用生成链路
  • kol_usage_logs 审计与看板
  • Workspace KOL 卡片区

第一版不做

  • 旧 share code 兼容层
  • 通用模板选择器集成
  • 在线支付
  • 收益分账/提现
  • KOL 自助入驻
  • KOL 多租户迁移
  • Prompt A/B 测试
  • 订阅评价/评分系统

14. 关键决策总结

  1. KOL 改为新的第一方模型,不再挂在旧分享能力上
  2. KOL 原始 prompt 不写入 article_templates
  3. 订阅后不再物化模板,改为 kol_subscription_prompts 授权映射
  4. KOL 生成走独立 source_type='kol' / task_type='kol'
  5. V1 不进入通用模板链路,先确保权限、审计、结算口径闭合