/database-schema
Schema awareness - read before coding, type generation, prevent column errors
$ npx -y skills add alinaqi/maggy --skill database-schema --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/database-schema
Context preview
The summary Claude sees to decide when to auto-load this skill.
Schema awareness - read before coding, type generation, prevent column errors
SKILL.md
database-schema.SKILL.mdname: database-schema
description: Schema awareness - read before coding, type generation, prevent column errors
when-to-use: Before writing any database queries or modifying data models
user-invocable: false
paths: ["**/schema.*", "**/migrations/**", "**/models/**", "**/*.prisma", "**/drizzle/**"]
effort: medium
Database Schema Awareness Skill
**Problem:** Claude forgets schema details mid-session - wrong column names, missing fields, incorrect types. TDD catches this at runtime, but we can prevent it earlier.
---
Core Rule: Read Schema Before Writing Database Code
**MANDATORY: Before writing ANY code that touches the database:**
┌─────────────────────────────────────────────────────────────┐
│ 1. READ the schema file (see locations below) │
│ 2. VERIFY columns/types you're about to use exist │
│ 3. REFERENCE schema in your response when writing queries │
│ 4. TYPE-CHECK using generated types (Drizzle/Prisma/etc) │
└─────────────────────────────────────────────────────────────┘
**If schema file doesn't exist → CREATE IT before proceeding.**
---
Schema File Locations (By Stack)
| Stack | Schema Location | Type Generation | |-------|-----------------|-----------------| | **Drizzle** | `src/db/schema.ts` or `drizzle/schema.ts` | Built-in TypeScript | | **Prisma** | `prisma/schema.prisma` | `npx prisma generate` | | **Supabase** | `supabase/migrations/*.sql` + types | `supabase gen types typescript` | | **SQLAlchemy** | `app/models/*.py` or `src/models.py` | Pydantic models | | **TypeORM** | `src/entities/*.ts` | Decorators = types | | **Raw SQL** | `schema.sql` or `migrations/` | Manual types required |
Schema Reference File (Recommended)
Create `_project_specs/schema-reference.md` for quick lookup:
# Database Schema Reference
*Auto-generated or manually maintained. Claude: READ THIS before database work.*
## Tables
### users
| Column | Type | Nullable | Default | Notes |
|--------|------|----------|---------|-------|
| id | uuid | NO | gen_random_uuid() | PK |
| email | text | NO | - | Unique |
| name | text | YES | - | Display name |
| created_at | timestamptz | NO | now() | - |
| updated_at | timestamptz | NO | now() | - |
### orders
| Column | Type | Nullable | Default | Notes |
|--------|------|----------|---------|-------|
| id | uuid | NO | gen_random_uuid() | PK |
| user_id | uuid | NO | - | FK → users.id |
| status | text | NO | 'pending' | enum: pending/paid/shipped/delivered |
| total_cents | integer | NO | - | Amount in cents |
| created_at | timestamptz | NO | now() | - |
## Relationships
- users 1:N orders (user_id)
## Enums
- order_status: pending, paid, shipped, delivered
---
Pre-Code Checklist (Database Work)
Before writing any database code, Claude MUST:
### Schema Verification Checklist
- [ ] Read schema file: `[path to schema]`
- [ ] Columns I'm using exist: [list columns]
- [ ] Types match my code: [list type mappings]
- [ ] Relationships are correct: [list FKs]
- [ ] Nullable fields handled: [list nullable columns]
**Example in practice:**
### Schema Verification for TODO-042 (Add order history endpoint)
- [x] Read schema: `src/db/schema.ts`
- [x] Columns exist: orders.id, orders.user_id, orders.status, orders.total_cents, orders.created_at
- [x] Types: id=uuid→string, total_cents=integer→number, status=text→OrderStatus enum
- [x] Relationships: orders.user_id → users.id (many-to-one)
- [x] Nullable: none of these columns are nullable
---
Type Generation Commands
Drizzle (TypeScript)
// Schema defines types automatically
// src/db/schema.ts
import { pgTable, uuid, text, integer, timestamp } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
email: text('email').notNull().unique(),
name: text('name'),
createdAt: timestamp('created_at').notNull().defaultNow(),
});
export const orders = pgTable('orders', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').notNull().references(() => users.id),
status: text('status').notNull().default('pending'),
totalCents: integer('total_cents').notNull(),
createdAt: timestamp('created_at').notNull().defaultNow(),
});
// Inferred types - USE THESE
export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
export type Order = typeof orders.$inferSelect;
export type NewOrder = typeof orders.$inferInsert;Prisma
// prisma/schema.prisma
model User {
id String @id @default(uuid())
email String @unique
name String?
orders Order[]
createdAt DateTime @default(now()) @map("created_at")
@@map("users")
}
model Order {
id String @id @default(uuid())
userId String @map("user_id")
user User @relation(fields: [userId], references: [id])
status String @default("pending")
totalCents Int @map("total_cents")
createdAt DateTime @default(now()) @map("created_at")
@@map("orders")
}# Generate types after schema changes
npx prisma generate
Supabase
# Generate TypeScript types from live database
supabase gen types typescript --local > src/types/database.ts
# Or from remote
supabase gen types typescript --project-id your-project-id > src/types/database.ts
// Use generated types
import { Database } from '@/types/database';
type User = Database['public']['Tables']['users']['Row'];
type NewUser = Database['public']['Tables']['users']['Insert'];
type Order = Database['public']['Tables']['orders']['Row'];SQLAlchemy (Python)
# app/models/user.py
from sqlalchemy import Column, String, DateTime
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from app.db import Base
import uuid
class User(Base):
__tablename__ = "users"
id = Column(UUID(as_uuid=True), primaryRead more
name: database-schema description: Schema awareness - read before coding, type generation, prevent column errors when-to-use: Before writing any database queries or modifying data models user-invocable: false paths: ["**/schema.*", "**/migrations/**", "**/models/**", "**/*.prisma", "**/drizzle/**"] effort: medium
Database Schema Awareness Skill
**Problem:** Claude forgets schema details mid-session - wrong column names, missing fields, incorrect types. TDD catches this at runtime, but we can prevent it earlier.
---
Core Rule: Read Schema Before Writing Database Code
**MANDATORY: Before writing ANY code that touches the database:**
┌─────────────────────────────────────────────────────────────┐ │ 1. READ the schema file (see locations below) │ │ 2. VERIFY columns/types you're about to use exist │ │ 3. REFERENCE schema in your response when writing queries │ │ 4. TYPE-CHECK using generated types (Drizzle/Prisma/etc) │ └─────────────────────────────────────────────────────────────┘
**If schema file doesn't exist → CREATE IT before proceeding.**
---
Schema File Locations (By Stack)
| Stack | Schema Location | Type Generation | |-------|-----------------|-----------------| | **Drizzle** | `src/db/schema.ts` or `drizzle/schema.ts` | Built-in TypeScript | | **Prisma** | `prisma/schema.prisma` | `npx prisma generate` | | **Supabase** | `supabase/migrations/*.sql` + types | `supabase gen types typescript` | | **SQLAlchemy** | `app/models/*.py` or `src/models.py` | Pydantic models | | **TypeORM** | `src/entities/*.ts` | Decorators = types | | **Raw SQL** | `schema.sql` or `migrations/` | Manual types required |
Schema Reference File (Recommended)
Create `_project_specs/schema-reference.md` for quick lookup:
# Database Schema Reference *Auto-generated or manually maintained. Claude: READ THIS before database work.* ## Tables ### users | Column | Type | Nullable | Default | Notes | |--------|------|----------|---------|-------| | id | uuid | NO | gen_random_uuid() | PK | | email | text | NO | - | Unique | | name | text | YES | - | Display name | | created_at | timestamptz | NO | now() | - | | updated_at | timestamptz | NO | now() | - | ### orders | Column | Type | Nullable | Default | Notes | |--------|------|----------|---------|-------| | id | uuid | NO | gen_random_uuid() | PK | | user_id | uuid | NO | - | FK → users.id | | status | text | NO | 'pending' | enum: pending/paid/shipped/delivered | | total_cents | integer | NO | - | Amount in cents | | created_at | timestamptz | NO | now() | - | ## Relationships - users 1:N orders (user_id) ## Enums - order_status: pending, paid, shipped, delivered
---
Pre-Code Checklist (Database Work)
Before writing any database code, Claude MUST:
### Schema Verification Checklist - [ ] Read schema file: `[path to schema]` - [ ] Columns I'm using exist: [list columns] - [ ] Types match my code: [list type mappings] - [ ] Relationships are correct: [list FKs] - [ ] Nullable fields handled: [list nullable columns]
**Example in practice:**
### Schema Verification for TODO-042 (Add order history endpoint) - [x] Read schema: `src/db/schema.ts` - [x] Columns exist: orders.id, orders.user_id, orders.status, orders.total_cents, orders.created_at - [x] Types: id=uuid→string, total_cents=integer→number, status=text→OrderStatus enum - [x] Relationships: orders.user_id → users.id (many-to-one) - [x] Nullable: none of these columns are nullable
---
Type Generation Commands
Drizzle (TypeScript)
// Schema defines types automatically
// src/db/schema.ts
import { pgTable, uuid, text, integer, timestamp } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
email: text('email').notNull().unique(),
name: text('name'),
createdAt: timestamp('created_at').notNull().defaultNow(),
});
export const orders = pgTable('orders', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').notNull().references(() => users.id),
status: text('status').notNull().default('pending'),
totalCents: integer('total_cents').notNull(),
createdAt: timestamp('created_at').notNull().defaultNow(),
});
// Inferred types - USE THESE
export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
export type Order = typeof orders.$inferSelect;
export type NewOrder = typeof orders.$inferInsert;Prisma
// prisma/schema.prisma
model User {
id String @id @default(uuid())
email String @unique
name String?
orders Order[]
createdAt DateTime @default(now()) @map("created_at")
@@map("users")
}
model Order {
id String @id @default(uuid())
userId String @map("user_id")
user User @relation(fields: [userId], references: [id])
status String @default("pending")
totalCents Int @map("total_cents")
createdAt DateTime @default(now()) @map("created_at")
@@map("orders")
}# Generate types after schema changes npx prisma generate
Supabase
# Generate TypeScript types from live database supabase gen types typescript --local > src/types/database.ts # Or from remote supabase gen types typescript --project-id your-project-id > src/types/database.ts
// Use generated types
import { Database } from '@/types/database';
type User = Database['public']['Tables']['users']['Row'];
type NewUser = Database['public']['Tables']['users']['Insert'];
type Order = Database['public']['Tables']['orders']['Row'];SQLAlchemy (Python)
# app/models/user.py
from sqlalchemy import Column, String, DateTime
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from app.db import Base
import uuid
class User(Base):
__tablename__ = "users"
id = Column(UUID(as_uuid=True), primaryTurn Claude Code into a self-reviewing, test-enforced engineering system that remembers context across sessions — then route work across 13 models from a single dashboard.
Repo: alinaqi/maggy
Other skills on maggy.
- /aeo-optimization
AI Engine Optimization - semantic triples, page templates, content clusters for AI citations
Open skill - /agent-teams
Claude Code Agent Teams - default team-based development with strict TDD pipeline enforcement
Open skill - /agentic-development
Build AI agents with Pydantic AI (Python) and Claude SDK (Node.js)
Open skill - /ai-models
Latest AI models reference - Claude, OpenAI, Gemini, Eleven Labs, Replicate
Open skill - /android-java
Android Java development with MVVM, ViewBinding, and Espresso testing
Open skill - /android-kotlin
Android Kotlin development with Coroutines, Jetpack Compose, Hilt, and MockK testing
Open skill

