Token导航 LogoToken导航

Agent Skill · 研究检索

database-layer(数据库层)

用于辅助数据库表结构、查询语句、迁移脚本和数据维护任务。它适合让 Agent 分析 schema、编写 SQL、排查查询问题、整理索引或生成迁移建议。使用时需要明确数据库类型、连接环境和目标表,区分只读分析与写入变更;涉及删除、更新、迁移和批量导入时,应优先 dry-run、备份或事务保护,避免误操作。

database-layer 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 41,189。

总安装 1,211周安装 52GitHub Stars 6下载 424核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:database-layer(数据库层)
来源仓库:https://github.com/mgd34msu/goodvibes-plugin
仓库路径:skills/database-layer
安装命令:
npx skills add https://github.com/mgd34msu/goodvibes-plugin --skill database-layer
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/mgd34msu/goodvibes-plugin --skill database-layer

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

引导应用程序中数据库层的完整实现流程从设计到上线。结合 GoodVibes 工具链提供类型安全的查询构造与关联处理。覆盖连接配置、ORM 选择、迁移编写与缓存策略制定。内置检查脚本确保符合项目约定的编码规范。database-layer 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/database-layer

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/mgd34msu/goodvibes-plugin --skill database-lay…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

database-layer 怎么安装?

在终端执行 npx skills add https://github.com/mgd34msu/goodvibes-plugin --skill database-layer。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

database-layer 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

database-layer 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

database-layer 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

database-layer 用的人多吗?

公开数据是累计安装 1,211 次,近一周安装 52 次,下载 424 次,GitHub 6 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

database-layer 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
database-layer

数据库层 · 本页

1,2116接触敏感数据未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Resources

scripts/
  database-checklist.sh
references/
  orm-comparison.md

Database Layer Implementation

This skill guides you through implementing database layers in applications, from initial schema design to query optimization. It leverages GoodVibes precision tools and project analysis tools for type-safe, production-ready database implementations.

When to Use This Skill

Use this skill when you need to:

  • Set up a new database connection and ORM
  • Design and implement database schemas
  • Create and run migrations
  • Generate type-safe database clients
  • Write queries and handle relationships
  • Optimize database performance
  • Integrate with existing database infrastructure

Workflow

Follow this sequence for database layer implementation:

1. Discover Existing Database Infrastructure

Before implementing any database changes, understand the current state using the detect_stack analysis tool:

detect_stack:
  project_root: "."
  categories: ["database", "orm"]

This identifies:

  • Existing database technology (PostgreSQL, MySQL, MongoDB, SQLite)
  • ORM/query builder in use (Prisma, Drizzle, Kysely, Mongoose)
  • Schema definition files
  • Migration tooling
  • Connection management patterns

Check project memory for database decisions:

precision_read:
  files:
    - path: ".goodvibes/memory/decisions.json"
    - path: ".goodvibes/memory/patterns.json"
  verbosity: minimal

Look for:

  • Previous database technology choices ("Use Prisma for type safety")
  • Migration strategies ("Always use reversible migrations")
  • Performance patterns ("Add indexes for foreign keys")
  • Known issues ("Avoid N+1 queries in user endpoints")

If database already exists, map the current schema:

get_database_schema:
  project_root: "."
  include_relations: true
  include_indexes: true

This returns:

  • Table/collection definitions
  • Column types and constraints
  • Relationships (foreign keys, references)
  • Indexes and unique constraints
  • Enums and custom types

2. Choose Database Technology

If starting fresh, consult the ORM comparison reference to select the appropriate technology stack.

See: references/orm-comparison.md for decision trees.

Key decision factors:

FactorRecommendation
Type safety priorityPrisma or Drizzle
Maximum SQL controlKysely or Drizzle
Document databaseMongoose (MongoDB)
Serverless/edgeDrizzle with libSQL/Turso
Existing PostgreSQLPrisma or Drizzle
Learning curvePrisma (best DX)

Record your decision in memory:

After choosing, document the decision in .goodvibes/memory/decisions.json for future reference.

3. Design Schema

Identify entities and relationships first:

Entities: User, Post, Comment, Category

Relationships:
- User 1:N Post (author)
- Post N:M Category (through PostCategory)
- Post 1:N Comment
- User 1:N Comment (author)

Create schema files using precision_write:

For Prisma:

precision_write:
  files:
    - path: "prisma/schema.prisma"
      content: |
        generator client {
          provider = "prisma-client-js"
        }

        datasource db {
          provider = "postgresql"
          url      = env("DATABASE_URL")
        }

        model User {
          id        String   @id @default(cuid())
          email     String   @unique
          name      String?
          posts     Post[]
          comments  Comment[]
          createdAt DateTime @default(now())
          updatedAt DateTime @updatedAt
        }

        model Post {
          id         String     @id @default(cuid())
          title      String
          content    String
          published  Boolean    @default(false)
          author     User       @relation(fields: [authorId], references: [id])
          authorId   String
          categories Category[]
          comments   Comment[]
          createdAt  DateTime   @default(now())
          updatedAt  DateTime   @updatedAt

          @@index([authorId])
          @@index([published, createdAt])
        }

        model Category {
          id    String @id @default(cuid())
          name  String @unique
          posts Post[]
        }

        model Comment {
          id        String   @id @default(cuid())
          content   String
          post      Post     @relation(fields: [postId], references: [id])
          postId    String
          author    User     @relation(fields: [authorId], references: [id])
          authorId  String
          createdAt DateTime @default(now())

          @@index([postId])
          @@index([authorId])
        }
  verbosity: minimal

For Drizzle:

precision_write:
  files:
    - path: "src/db/schema.ts"
      content: |
        import { pgTable, text, timestamp, boolean, index } from 'drizzle-orm/pg-core';
        import { relations } from 'drizzle-orm';

        export const users = pgTable('users', {
          id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
          email: text('email').notNull().unique(),
          name: text('name'),
          createdAt: timestamp('created_at').defaultNow().notNull(),
          updatedAt: timestamp('updated_at').defaultNow().notNull(),
        });

        export const posts = pgTable('posts', {
          id: text('id').primaryKey().$defaultFn(() => crypto.randomUUID()),
          title: text('title').notNull(),
          content: text('content').notNull(),
          published: boolean('published').default(false).notNull(),
          authorId: text('author_id').notNull().references(() => users.id),
          createdAt: timestamp('created_at').defaultNow().notNull(),
          updatedAt: timestamp('updated_at').defaultNow().notNull(),
        }, (table) => ({
          authorIdx: index('author_idx').on(table.authorId),
          publishedCreatedIdx: index('published_created_idx').on(table.published, table.createdAt),
        }));

        export const usersRelations = relations(users, ({ many }) => ({
          posts: many(posts),
        }));

        export const postsRelations = relations(posts, ({ one }) => ({
          author: one(users, {
            fields: [posts.authorId],
            references: [users.id],
          }),
        }));
  verbosity: minimal

Schema best practices:

  1. Use appropriate ID strategy:

- CUID/UUID for distributed systems - Auto-increment for simple apps - Composite keys for join tables

  1. Add timestamps:

- Always include createdAt - Include updatedAt for mutable entities - Consider deletedAt for soft deletes

  1. Index strategically:

- Foreign keys (for joins) - Frequently queried fields - Composite indexes for multi-column filters - Unique constraints where applicable

  1. Plan for scale:

- Text vs VARCHAR limits - JSONB for flexible data (PostgreSQL) - Separate tables for large text/blobs

4. Configure Database Connection

Create environment configuration:

precision_write:
  files:
    - path: ".env.example"
      content: |
        # Database
        DATABASE_URL="postgresql://user:password@localhost:5432/dbname"
        # For Prisma with connection pooling
        # DATABASE_URL="postgresql://user:password@localhost:5432/dbname?pgbouncer=true"
        # DIRECT_URL="postgresql://user:password@localhost:5432/dbname"
      mode: overwrite
  verbosity: minimal

Create database client module:

For Prisma:

precision_write:
  files:
    - path: "src/lib/db.ts"
      content: |
        import { PrismaClient } from '@prisma/client';

        const globalForPrisma = globalThis as unknown as {
          prisma: PrismaClient | undefined;
        };

        export const db =
          globalForPrisma.prisma ??
          new PrismaClient({
            log:
              process.env.NODE_ENV === 'development'
                ? ['query', 'error', 'warn']
                : ['error'],
          });

        if (process.env.NODE_ENV !== 'production') {
          globalForPrisma.prisma = db;
        }
  verbosity: minimal

For Drizzle:

precision_write:
  files:
    - path: "src/lib/db.ts"
      content: |
        import { drizzle } from 'drizzle-orm/postgres-js';
        import postgres from 'postgres';
        import * as schema from '@/db/schema';

        const connectionString = process.env.DATABASE_URL!;

        const client = postgres(connectionString, {
          max: process.env.NODE_ENV === 'production' ? 10 : 1,
        });

        export const db = drizzle(client, { schema });
  verbosity: minimal

5. Run Migrations

Use precision_exec to run migration commands with expectations:

For Prisma:

precision_exec:
  commands:
    - cmd: "npx prisma migrate dev --name init"
      timeout_ms: 60000
      expect:
        exit_code: 0
      # Note: Prisma outputs progress to stderr; this is expected behavior
    - cmd: "npx prisma generate"
      expect:
        exit_code: 0
  verbosity: standard

For Drizzle:

precision_exec:
  commands:
    - cmd: "npx drizzle-kit generate"
      expect:
        exit_code: 0
    - cmd: "npx drizzle-kit push"
      timeout_ms: 60000
      expect:
        exit_code: 0
  verbosity: standard

Migration best practices:

  1. Always review generated migrations before applying
  2. Use reversible migrations (include both up and down)
  3. Test migrations on dev database before production
  4. Backup production data before running migrations
  5. Use transactions for multi-step migrations

6. Generate Type-Safe Client

Use the generate_types project tool to generate TypeScript types from your schema:

generate_types:
  project_root: "."
  source: "database"
  output_path: "src/types/db.ts"

This creates type definitions for:

  • Table/collection types
  • Insert types (omitting auto-generated fields)
  • Update types (all fields optional)
  • Select types (with relations)

Verify type generation:

precision_exec:
  commands:
    - cmd: "npm run typecheck"
      expect:
        exit_code: 0
  verbosity: minimal

7. Implement Queries

Start with basic CRUD operations:

precision_write:
  files:
    - path: "src/db/queries/users.ts"
      content: |
        import { db } from '@/lib/db';

        export async function createUser(data: { email: string; name?: string }) {
          return db.user.create({
            data,
          });
        }

        export async function getUserById(id: string) {
          return db.user.findUnique({
            where: { id },
            include: {
              posts: true,
            },
          });
        }

        export async function updateUser(
          id: string,
          data: { email?: string; name?: string }
        ) {
          return db.user.update({
            where: { id },
            data,
          });
        }

        export async function deleteUser(id: string) {
          return db.user.delete({
            where: { id },
          });
        }
  verbosity: minimal

Check for N+1 query patterns using project tools:

get_prisma_operations:
  project_root: "."
  analyze_performance: true

This identifies:

  • N+1 query opportunities (missing include or select)
  • Missing indexes on frequently queried fields
  • Inefficient relationship loading

Optimize queries:

  1. Use select to limit fields: db.user.findMany({select: {id: true, email: true}, // Don't fetch unused fields});
  2. Eager load relationships: db.post.findMany({include: {author: true}, // Prevents N+1});
  3. Use pagination: db.post.findMany({take: 20, skip: (page - 1) * 20,});
  4. Add database-level constraints: @@index([userId, createdAt(sort: Desc)])

8. Implement Transactions

For multi-step operations, use transactions:

Prisma:

export async function createPostWithCategories(
  postData: { title: string; content: string; authorId: string },
  categoryIds: string[]
) {
  return db.$transaction(async (tx) => {
    const post = await tx.post.create({
      data: {
        ...postData,
        categories: {
          connect: categoryIds.map((id) => ({ id })),
        },
      },
    });

    await tx.user.update({
      where: { id: postData.authorId },
      data: { updatedAt: new Date() },
    });

    return post;
  });
}

Drizzle:

export async function createPostWithCategories(
  postData: { title: string; content: string; authorId: string },
  categoryIds: string[]
) {
  return db.transaction(async (tx) => {
    const [post] = await tx.insert(posts).values(postData).returning();

    await tx.insert(postCategories).values(
      categoryIds.map((categoryId) => ({
        postId: post.id,
        categoryId,
      }))
    );

    return post;
  });
}

9. Seed Development Data

Create seed script for local development:

precision_write:
  files:
    - path: "prisma/seed.ts"
      content: |
        import { PrismaClient } from '@prisma/client';

        const prisma = new PrismaClient();

        async function main() {
          // Clear existing data
          await prisma.comment.deleteMany();
          await prisma.post.deleteMany();
          await prisma.user.deleteMany();
          await prisma.category.deleteMany();

          // Create users
          const alice = await prisma.user.create({
            data: {
              email: 'alice@example.com',
              name: 'Alice',
            },
          });

          const bob = await prisma.user.create({
            data: {
              email: 'bob@example.com',
              name: 'Bob',
            },
          });

          // Create categories
          const tech = await prisma.category.create({
            data: { name: 'Technology' },
          });

          const news = await prisma.category.create({
            data: { name: 'News' },
          });

          // Create posts
          await prisma.post.create({
            data: {
              title: 'First Post',
              content: 'This is the first post',
              published: true,
              authorId: alice.id,
              categories: {
                connect: [{ id: tech.id }],
              },
            },
          });

          console.log('Database seeded successfully');
        }

        main()
          .catch((e) => {
            console.error(e);
            process.exit(1);
          })
          .finally(async () => {
            await prisma.$disconnect();
          });
  verbosity: minimal

Update package.json:

precision_edit:
  edits:
    - path: "package.json"
      find: '"scripts": {'
      hints:
        near_line: 2
      replace: |
        "prisma": {
          "seed": "tsx prisma/seed.ts"
        },
        "scripts": {
  verbosity: minimal

10. Validate Implementation

Run the database checklist script:

./plugins/goodvibes/skills/outcome/database-layer/scripts/database-checklist.sh .

This validates:

  • Schema file exists and is valid
  • Migration directory present
  • Database URL documented in.env.example
  • Type generation configured
  • No SQL injection vulnerabilities (string concatenation)
  • Connection pooling configured
  • Indexes on foreign keys

Run type checking and tests:

precision_exec:
  commands:
    - cmd: "npm run typecheck"
      expect:
        exit_code: 0
    - cmd: "npm run test -- db"
      expect:
        exit_code: 0
  verbosity: minimal

Use query_database to verify data integrity:

query_database:
  project_root: "."
  query: "SELECT COUNT(*) FROM users;"

Common Patterns

Soft Deletes

Add deletedAt field and filter in queries:

model Post {
  id        String    @id
  deletedAt DateTime?
}
// Soft delete
await db.post.update({
  where: { id },
  data: { deletedAt: new Date() },
});

// Query only active records
await db.post.findMany({
  where: { deletedAt: null },
});

Optimistic Locking

Use version field to prevent concurrent updates:

model Post {
  id      String @id
  version Int    @default(0)
}
await db.post.update({
  where: {
    id: postId,
    version: currentVersion,
  },
  data: {
    title: newTitle,
    version: { increment: 1 },
  },
});

Connection Pooling

For serverless environments, use connection pooling:

# PgBouncer
DATABASE_URL="postgresql://user:password@localhost:6543/db?pgbouncer=true"
DIRECT_URL="postgresql://user:password@localhost:5432/db"
datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}

Full-Text Search

PostgreSQL:

@@index([content(ops: raw("gin_trgm_ops"))], type: Gin)
await db.$queryRaw`
  SELECT * FROM posts
  WHERE to_tsvector('english', content) @@ to_tsquery('search terms')
`;

Security Checklist

  • Database credentials in environment variables (not committed)
  • Input validation on all user-provided data
  • Parameterized queries (no string concatenation)
  • Row-level security for multi-tenant apps
  • Rate limiting on expensive queries
  • Audit logging for sensitive operations
  • Least privilege database user permissions
  • SSL/TLS for database connections in production

Performance Checklist

  • Indexes on foreign keys
  • Composite indexes for multi-column filters
  • Connection pooling configured
  • Query result pagination
  • Eager loading to prevent N+1 queries
  • Database query logging in development
  • Explain/analyze for slow queries
  • Caching for frequently accessed data

Troubleshooting

Migration fails with constraint violation

  1. Check existing data conflicts with new constraints
  2. Add data migration before schema migration
  3. Use multi-step migrations (add column nullable, populate, make required)

N+1 query detected

  1. Use get_prisma_operations to identify location
  2. Add include or select with relations
  3. Consider using dataloader for complex cases

Connection pool exhausted

  1. Increase pool size in connection string (?pool_timeout=10)
  2. Check for missing await (connections not released)
  3. Use connection pooler (PgBouncer, Prisma Accelerate)

Type generation fails

  1. Verify schema syntax with npx prisma validate
  2. Clear generated files and regenerate
  3. Check for circular dependencies in relations

Next Steps

After implementing the database layer:

  1. Add caching - Use Redis for frequently accessed data
  2. Implement search - Add full-text search or Elasticsearch
  3. Add monitoring - Track query performance and slow queries
  4. Write tests - Unit tests for queries, integration tests for transactions
  5. Document schema - Add comments to schema for team reference
  6. Plan backups - Set up automated database backups

For additional reference material and decision trees, see:

平台分布

Codex

35.84%
按下载量换算152

Claude

30.08%
按下载量换算128

Cursor

19.51%
按下载量换算83

Gemini CLI

9.38%
按下载量换算40

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills