[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6MX9CXA93HT37BXPR5CJMMF":3,"skill-same:01M6MX9CXA93HT37BXPR5CJMMF":46},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":21,"linkOnly":22,"markdownContent":23,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":6,"ownerHtmlUrl":30,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":31,"install":32,"resources":45},"01M6MX9CXA93HT37BXPR5CJMMF","db-designer",null,"miniidealab\u002Fopenlogos","miniidealab","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F4251156?v=4","01M6MX6BM454XESZCRPBQQHKRT","FredHuang","01M6MX6BR4417H4QA658D4GW9X",581,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fexamples\u002Fmoney-log\u002Flogos\u002Fskills\u002Fdb-designer\u002FSKILL.md",[],[18,19,20],"designer","db","db designer","2026-11-10 10:12:30",false,"# Skill: DB Designer\n\n> 从 API 规格推导数据库表结构，生成对应方言的 SQL DDL。数据库类型由 Phase 3 Step 0 技术选型确定，确保字段类型、约束、索引和安全策略与 API 端点完全对齐。\n\n## 触发条件\n\n- 用户要求设计数据库或编写 SQL\n- 用户提到 \"Phase 3 Step 2\"、\"DB 设计\"、\"表结构\"\n- 已有 API YAML 规格，需要推导数据库设计\n- 用户提供了数据模型需要转化为 DDL\n\n## 核心能力\n\n1. 从 API 请求\u002F响应结构推导表结构\n2. 读取 `logos-project.yaml` 的 `tech_stack.database` 确定数据库类型\n3. 生成对应数据库方言的 SQL DDL\n4. 设计索引并说明设计理由\n5. 设计安全策略（RLS \u002F 应用层权限）\n6. 为每张表、每个字段添加注释\n\n## 前置依赖\n\n- `logos\u002Fresources\u002Fapi\u002F` 中包含 API YAML 规格（api-designer 产出）\n- `logos-project.yaml` 的 `tech_stack.database` 已填写\n\n如果 API 目录为空，提示用户先完成 Phase 3 Step 2 的 API 设计（api-designer）。如果 `tech_stack.database` 未填写，提示用户先完成 Phase 3 Step 0（architecture-designer）。\n\n## 执行步骤\n\n### Step 1: 确认数据库类型\n\n读取 `logos\u002Flogos-project.yaml` 的 `tech_stack` 字段，确定数据库类型和方言：\n\n- PostgreSQL → 使用 UUID、TIMESTAMPTZ、RLS、JSONB 等特性\n- MySQL → 使用 InnoDB、utf8mb4、TIMESTAMP 等特性\n- SQLite → 使用 INTEGER PRIMARY KEY、TEXT 等简化类型\n- 其他 → 与用户确认后选择最接近的方言\n\n### Step 2: 提取数据实体\n\n从 API YAML 中提取所有需要持久化的数据实体：\n\n1. 扫描所有端点的 `requestBody` 和 `responses`，识别核心数据对象\n2. 区分\"需要持久化\"与\"仅传输用\"的数据：\n   - 有 CRUD 操作的对象 → 需要建表（如 `users`、`projects`）\n   - 只出现在请求\u002F响应中但不直接存储的 → 不建表（如 `loginRequest`）\n3. 为每个对象标注来源 API 端点\n\n输出实体清单供用户确认：\n\n```markdown\n从 API 规格中识别到 N 个需要持久化的数据实体：\n\n| # | 实体 | 来源端点 | 核心字段 |\n|---|------|---------|---------|\n| 1 | users | auth.yaml → register, login | email, password, status |\n| 2 | projects | projects.yaml → create, list, get | name, description, owner_id |\n| 3 | subscriptions | billing.yaml → subscribe | plan, status, expires_at |\n```\n\n### Step 3: 设计表结构\n\n为每个实体设计完整的表结构，遵循当前数据库方言：\n\n**每张表必须包含**：\n- 主键（UUID 或自增 ID，视方言决定）\n- 业务字段（从 API schema 映射，类型转换为数据库类型）\n- 审计字段：`created_at`、`updated_at`\n- 软删除字段：`deleted_at`（按需）\n- 字段约束：`NOT NULL`、`UNIQUE`、`CHECK`、`DEFAULT`\n\n**类型映射原则**：\n- API `string + format: email` → `TEXT NOT NULL`（配合 CHECK 约束或应用层校验）\n- API `string + format: uuid` → `UUID`（PostgreSQL）\u002F `CHAR(36)`（MySQL）\n- API `integer` → `INTEGER` \u002F `BIGINT`\n- API `boolean` → `BOOLEAN`（PostgreSQL）\u002F `TINYINT(1)`（MySQL）\n- API `string + enum` → `TEXT + CHECK` 约束（列出枚举值）\n- 金额字段 → `INTEGER`（存分值），**禁止 DECIMAL\u002FFLOAT**\n\n**示例（PostgreSQL）**：\n\n```sql\n-- 用户表（来源：auth.yaml → register, login）\nCREATE TABLE users (\n  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  email       TEXT NOT NULL UNIQUE,\n  password    TEXT NOT NULL,\n  status      TEXT NOT NULL DEFAULT 'pending'\n                CHECK (status IN ('pending', 'active', 'disabled')),\n  created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),\n  updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()\n);\n```\n\n**示例（SQLite — 使用 `@comment` 结构化注释）**：\n\n```sql\n-- 用户表（来源：auth.yaml → register, login）\nCREATE TABLE users (\n  -- @comment 用户唯一标识，UUID v4 字符串\n  id TEXT PRIMARY KEY NOT NULL,\n  -- @comment 用户邮箱，已归一化为小写\n  email TEXT NOT NULL UNIQUE,\n  -- @comment Argon2id 密码哈希，仅存哈希\n  password_hash TEXT NOT NULL,\n  -- @comment 创建时间，ISO 8601 格式\n  created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),\n  -- @comment 最后更新时间\n  updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))\n);\n-- @table-comment users 用户表，存储注册用户的核心信息\n```\n\n> **SQLite 注释约定**：SQLite 不支持 `COMMENT ON` 语法，必须使用 `-- @comment` 前置注释（字段）和 `-- @table-comment \u003C表名> \u003C描述>` 后置注释（表）。规则详见 `logos\u002Fspec\u002Fsql-comment-convention.md`。\n\n### Step 4: 设计表间关联\n\n根据 API 中的实体关系设计外键：\n\n1. 从 API 端点的嵌套路径和引用字段推导关联（如 `\u002Fapi\u002Fprojects\u002F:projectId\u002Fmembers` → `project_members` 表关联 `projects` 和 `users`）\n2. 确定关联类型（一对多、多对多）\n3. 设计外键约束和级联策略：\n   - `ON DELETE CASCADE`：父记录删除时子记录跟随删除（如用户删除 → 项目删除）\n   - `ON DELETE SET NULL`：父记录删除时子记录保留但外键置空\n   - `ON DELETE RESTRICT`：父记录有子记录时禁止删除\n\n### Step 5: 设计安全策略\n\n根据数据库类型设计对应的安全机制：\n\n**PostgreSQL — 行级安全（RLS）**：\n\n```sql\nALTER TABLE projects ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY projects_owner_policy ON projects\n  USING (owner_id = auth.uid());\n```\n\n- 所有包含用户数据的表启用 RLS\n- 为每张表设计至少一条 Policy（owner \u002F admin \u002F public）\n- 注明 RLS 策略与 API 认证方案的对应关系\n\n**MySQL — 应用层权限**：\n\n- 在表注释中标注数据访问权限（owner-only \u002F admin \u002F public）\n- 不在 DDL 中实现权限控制，交由应用层处理\n\n### Step 6: 设计索引\n\n为常见查询模式设计索引，每个索引附设计理由：\n\n```sql\n-- 用户按邮箱查找（登录场景，来源 S02）\nCREATE UNIQUE INDEX idx_users_email ON users(email);\n\n-- 项目按 owner 查找（项目列表，来源 S04 Step 1）\nCREATE INDEX idx_projects_owner ON projects(owner_id);\n```\n\n索引设计原则：\n- 外键列：必须建索引（避免 JOIN 全表扫描）\n- 唯一约束列：自动创建唯一索引\n- 高频查询列：根据 API 的查询参数判断\n- 复合索引：多条件查询时考虑（最左前缀原则）\n- 不过度索引：写多读少的表控制索引数量\n\n### Step 7: 输出完整 DDL\n\n按以下顺序组织 DDL 文件：\n\n1. 文件头注释（来源、数据库类型、生成时间）\n2. 基础表（无外键依赖的表先建）\n3. 关联表（有外键依赖的表后建）\n4. 索引\n5. 安全策略（RLS \u002F Policy）\n6. 表和字段注释：\n   - PostgreSQL：使用 `COMMENT ON TABLE` \u002F `COMMENT ON COLUMN`\n   - MySQL：使用内联 `COMMENT`\n   - SQLite：使用 `-- @comment`（字段）+ `-- @table-comment`（表），详见下方 SQLite 注释规则\n\n每段 DDL 上方用注释标注来源 API 端点。\n\n**SQLite 注释规则（MUST Follow）**：\n\n当 `tech_stack.database` 为 SQLite 时，必须使用以下结构化注释格式：\n\n1. **字段注释**：在字段定义行的**紧邻上方**写 `-- @comment \u003C描述>`\n   - 与字段之间**不允许空行**（空行会断开关联）\n   - 多行注释：连续多个 `-- @comment` 行自动拼接\n2. **表注释**：在 `CREATE TABLE ... ();` 语句**紧邻下方**写 `-- @table-comment \u003C表名> \u003C描述>`\n3. 约束行（`FOREIGN KEY`、独立 `CHECK`、`UNIQUE`）**不需要** `-- @comment`\n\n## 输出规范\n\n- 文件格式：SQL（方言由 `tech_stack.database` 决定）\n- 存放位置：`logos\u002Fresources\u002Fdatabase\u002F`\n- 单文件输出：`schema.sql`（简单项目）；或按领域分文件：`auth.sql`、`billing.sql`（复杂项目）\n- 每张表必须有注释（PostgreSQL: `COMMENT ON TABLE`；MySQL: `COMMENT = '...'`；SQLite: `-- @table-comment`）\n- 每个字段必须有注释（PostgreSQL: `COMMENT ON COLUMN`；MySQL: 字段定义后 `COMMENT '...'`；SQLite: `-- @comment`）\n- 每段 DDL 上方用 SQL 注释标注来源 API 端点\n\n## 数据库方言差异速查\n\n| 特性 | PostgreSQL | MySQL | SQLite |\n|------|-----------|-------|--------|\n| UUID 主键 | `UUID DEFAULT gen_random_uuid()` | `CHAR(36) DEFAULT (UUID())` 或 `BINARY(16)` | `TEXT PRIMARY KEY NOT NULL`（应用层生成 UUID） |\n| 时间类型 | `TIMESTAMPTZ` | `DATETIME` \u002F `TIMESTAMP`（注意时区处理） | `TEXT`（ISO 8601 字符串） |\n| JSON 支持 | `JSONB`（可索引） | `JSON`（功能受限） | `TEXT`（应用层 JSON 序列化） |\n| 行级安全 | RLS (`ENABLE ROW LEVEL SECURITY`) | 不支持，需在应用层实现 | 不支持，需在应用层实现 |\n| 表注释 | `COMMENT ON TABLE t IS '...'` | `CREATE TABLE t (...) COMMENT = '...'` | `-- @table-comment t 描述` |\n| 字段注释 | `COMMENT ON COLUMN t.c IS '...'` | `col_name TYPE COMMENT '...'` | `-- @comment 描述`（紧邻字段上方） |\n\n## 实践经验\n\n### 通用（所有数据库）\n\n- **金额一律 INTEGER 存分值**：禁止 DECIMAL\u002FFLOAT，避免浮点精度问题\n- **软删除**：优先使用 `deleted_at` 时间字段而非物理删除\n- **审计字段**：每张表包含 `created_at` 和 `updated_at`\n- **时间字段带时区**：避免时区陷阱\n- **字段名与 API 一致**：DB 列名尽量与 API YAML 中的字段名对齐（如 API 用 `userId` → DB 用 `user_id`，映射规则明确即可），减少代码层的无谓转换\n- **先出核心表再补辅助表**：不要试图一次设计所有表——先输出核心业务表让用户 review，再补充辅助表\n\n### PostgreSQL 特有\n\n- **主键**：`id UUID DEFAULT gen_random_uuid() PRIMARY KEY`\n- **时间类型**：使用 `TIMESTAMPTZ`\n- **RLS**：所有表启用 `ALTER TABLE ... ENABLE ROW LEVEL SECURITY;`\n- **JSONB**：需要非结构化存储时优先使用 JSONB 并建 GIN 索引\n\n### MySQL 特有\n\n- **主键**：`id CHAR(36) DEFAULT (UUID()) PRIMARY KEY` 或自增 BIGINT\n- **时间类型**：使用 `TIMESTAMP`（自动时区转换）或 `DATETIME`（原样存储）\n- **字符集**：建表时指定 `CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`\n- **引擎**：一律使用 `ENGINE=InnoDB`\n\n### SQLite 特有\n\n- **主键**：`TEXT PRIMARY KEY NOT NULL`（应用层生成 UUID v4）或 `INTEGER PRIMARY KEY AUTOINCREMENT`\n- **时间类型**：使用 `TEXT` 存储 ISO 8601 字符串，默认值 `DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))`\n- **外键**：须在连接时执行 `PRAGMA foreign_keys = ON;`\n- **注释**：必须使用 `-- @comment` \u002F `-- @table-comment` 结构化注释（见 `logos\u002Fspec\u002Fsql-comment-convention.md`）\n- **无触发器**：`updated_at` 须在应用层刷新，不依赖 `ON UPDATE` 触发器\n\n## 推荐提示词\n\n以下提示词可以直接复制给 AI 使用：\n\n- `帮我设计数据库`\n- `基于 API 规格帮我推导数据库 DDL`\n- `帮我设计 S01 涉及的数据库表`\n- `帮我给现有表结构补充索引和 RLS 策略`\n",{},"master","abf55fdedadaeb660f928aa7258b9ec35d4ab003","examples\u002Fmoney-log\u002Flogos\u002Fskills\u002Fdb-designer",9,"https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos","https:\u002F\u002Fgithub.com\u002Fminiidealab","2026-10-18 11:36:11",{"source":7,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add miniidealab\u002Fopenlogos --skill db-designer",{"tool":38,"command":39},"bunx","bunx skills add miniidealab\u002Fopenlogos --skill db-designer",{"tool":41,"command":42},"pnpm","pnpm dlx skills add miniidealab\u002Fopenlogos --skill db-designer","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fexamples\u002Fmoney-log\u002Flogos\u002Fskills\u002Fdb-designer\u002FSKILL.md",true,[],[47,93,105,114,122,131],{"skillNo":48,"name":49,"nameZh":6,"description":50,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":51,"categories":52,"keywords":72,"publishedAt":21},"01M6MXX45142DGRFD9ZYPT5YC9","ui-ux-pro-max","UI\u002FUX design intelligence. 67 styles, 96 palettes, 57 font pairings, 25 charts, 13 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn\u002Fui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI\u002FUX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn\u002Fui MCP for component search and examples.","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fui-ux-pro-max\u002FSKILL.md",[53,58,61,64,69],{"categoryNo":54,"categoryName":55,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":59,"categoryName":60,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":62,"categoryName":63,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":65,"categoryName":66,"taxonomyType":67,"taxonomyTypeDesc":68},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",{"categoryNo":70,"categoryName":71,"taxonomyType":67,"taxonomyTypeDesc":68},"01JBSEEDCAT000000000000033","数据分析师",[73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92],"ui ux","pro","max","ui ux pro max","ui","ux","projects","mode","card","app","tsx","fix","improve","Tailwind","Charts","Animation","design","actions","MCP","search",{"skillNo":94,"name":95,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":101,"publishedAt":21},"01M6MXWY8HJV93BBR8FPNJXAMV","test-writer","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Ftest-writer\u002FSKILL.md",[98],{"categoryNo":99,"categoryName":100,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000008","测试与质量",[102,103,104],"writer","test writer","test",{"skillNo":106,"name":107,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":111,"publishedAt":21},"01M6MXWSAMN9AD3T8F6N099ZGY","test-orchestrator","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Ftest-orchestrator\u002FSKILL.md",[110],{"categoryNo":99,"categoryName":100,"taxonomyType":56,"taxonomyTypeDesc":57},[112,113,104],"orchestrator","test orchestrator",{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":21},"01M6MXWN29FY7K9ASMFRSPWQCN","slice-planner","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fslice-planner\u002FSKILL.md",[],[120,121],"slice planner","planner",{"skillNo":123,"name":124,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":127,"publishedAt":21},"01M6MXWFR1C1V66NSRTAM1FZPR","scenario-architect","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fscenario-architect\u002FSKILL.md",[],[128,129,130],"architect","scenario","scenario architect",{"skillNo":132,"name":133,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":136,"publishedAt":21},"01M6MXWD6ZCGPT4FDT580S8K96","project-init","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fproject-init\u002FSKILL.md",[],[137,138,139],"project init","init","project"]