From unwind
Analyzes database layer including ORM models, SQL DDL, migrations, and data access patterns. Outputs structured documentation with entity diagrams and schema contracts.
How this skill is triggered — by the user, by Claude, or both
Slash command
/unwind:uw-analyze-databaseThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Output:** `docs/unwind/layers/database/` (folder with index.md + section files)
Output: docs/unwind/layers/database/ (folder with index.md + section files)
Principles: See analysis-principles.md - completeness, machine-readable, link to source, no commentary, incremental writes.
For a rebuild in a different stack, the canonical data model is the code-side representation — the ORM models/entities (Drizzle, Prisma, TypeORM, SQLAlchemy, Mongoose, Sequelize, JPA, EF Core). That is where the field names, types, relations, defaults, and business rules live, and it is what the rebuild reproduces.
Raw SQL DDL (CREATE TABLE, migrations) is a contract, not the model. When
the deterministic scan finds a code-side model, it makes that the canonical table
candidate and reconciles matching SQL DDL onto it (demoting the migration's
CREATE TABLE to a db-ddl contract linked via dataModelLinks). So:
table:<code-path>:<Name>). Describe fields, types, relations, and the
invariants/business rules they encode.CREATE TABLE; reconciliation already folded those into the entity,
and coverage no longer counts them.table candidates — document them from the
DDL as before.Graceful fallback: if @unwind/core / seeds are unavailable (no
docs/unwind/.cache/seeds/database.json), fall back to the legacy SQL-first flow —
extract tables from migrations/DDL directly — and say so in index.md.
docs/unwind/layers/database/
├── index.md # Overview, entity count, ER diagram, links to sections
├── data-model.md # CANONICAL: code-side entities (fields, types, relations, rules)
├── schema.md # Physical SQL DDL contract per entity (the on-disk schema)
├── repositories.md # Data access patterns, queries
└── jsonb-schemas.md # Complex field type definitions (if any JSONB/JSON columns)
For large codebases (20+ entities), split data-model.md by domain:
docs/unwind/layers/database/
├── index.md
├── users-domain.md # User, UserSettings, UserRole entities (+ their DDL)
├── orders-domain.md # Order, OrderItem, Shipment entities (+ their DDL)
└── ...
Step 1: Setup
mkdir -p docs/unwind/layers/database/
Write initial index.md:
# Database Layer
## Sections
- [Data Model](data-model.md) - _pending_
- [Physical Schema](schema.md) - _pending_
- [Repositories](repositories.md) - _pending_
- [JSONB Schemas](jsonb-schemas.md) - _pending_
## Summary
_Analysis in progress..._
Step 2: Analyze and write data-model.md (the canonical model)
docs/unwind/.cache/seeds/database.json — the seeded table candidates are
the code-side entities (their anchor ids are table:<code-path>:<Name>).data-model.md immediately; update index.md.Step 3: Analyze and write schema.md (the physical contract)
dataModelLinks
connects the entity's table: id to a db-ddl: migration) or generate it from the
ORM model when there are no migrations.schema.md immediately; update index.md.Step 4: Analyze and write repositories.md
repositories.md immediately; update index.mdStep 5: Analyze and write jsonb-schemas.md (if applicable)
jsonb-schemas.md immediately; update index.mdStep 6: Finalize index.md Update with final counts and summary
# Database Layer
## Sections
- [Data Model](data-model.md) - 12 entities (code-side, canonical)
- [Physical Schema](schema.md) - DDL contract for 12 entities, 4 indexes
- [Repositories](repositories.md) - 8 repository classes
- [JSONB Schemas](jsonb-schemas.md) - 3 complex field types
## Migrations
**Location:** `src/db/migrations/`
Current schema state (result of all migrations) is documented in [schema.md](schema.md).
## Entity Relationships
```mermaid
erDiagram
users ||--o{ orders : places
orders ||--|{ order_items : contains
order_items }|--|| products : references
### data-model.md (canonical)
The anchor-id heading for each `table:` candidate lives **here** — this is the
canonical model. Use the code anchor id from `seeds/database.json`.
```markdown
# Data Model
## Entities (12 total)
### User [MUST] <!-- id: table:src/db/schema.ts:users -->
Source: [schema.ts](https://github.com/owner/repo/blob/main/src/db/schema.ts#L12-L34)
ORM: Drizzle (`pgTable`). Physical table: `users`.
| Field | Type | Nullable | Default | Notes / Rule |
|-------|------|----------|---------|--------------|
| id | serial | NO | auto | PK |
| email | text | NO | - | UNIQUE; lowercased on write (see UserService) |
| organisationId | integer | NO | - | belongs-to Organisation (FK, ON DELETE CASCADE) |
**Relations:** has-many Post. **Invariants:** email unique per organisation.
[Continue for ALL entities...]
The on-disk schema each entity maps to — the contract the rebuild must preserve.
Group DDL under its entity with a plain ## heading (no anchor id — the entity
is already documented in data-model.md; reconciliation folded the migration's
CREATE TABLE into a db-ddl contract, so it is not a separate coverage target).
# Physical Schema
## users (→ User)
```sql
CREATE TABLE "users" (
"id" serial PRIMARY KEY,
"email" text NOT NULL UNIQUE,
"organisation_id" integer NOT NULL REFERENCES organisation(id) ON DELETE CASCADE
);
CREATE INDEX idx_users_email ON users(email);
[Continue for ALL entities. For SQL-first projects with no code model, document the
table from the DDL directly, using the table: anchor id here instead.]
### repositories.md
```markdown
# Repositories
## UserRepository
[UserRepository.java](https://github.com/owner/repo/blob/main/src/repository/UserRepository.java)
```java
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
@Query("SELECT u FROM User u WHERE u.status = :status")
List<User> findByStatus(@Param("status") UserStatus status);
}
[Continue for ALL repositories...]
## Additional Requirements
### Field-Level Documentation [MUST]
For EVERY table, document ALL of the following:
- Column name and database type (VARCHAR, INTEGER, JSONB, etc.)
- NOT NULL constraints
- DEFAULT values
- UNIQUE constraints
- Foreign key relationships with ON DELETE behavior (CASCADE, SET NULL, RESTRICT)
**Example:**
```markdown
### users table [MUST]
| Column | Type | Nullable | Default | Constraints |
|--------|------|----------|---------|-------------|
| id | SERIAL | NO | auto | PRIMARY KEY |
| email | VARCHAR(255) | NO | - | UNIQUE |
| organisation | INTEGER | NO | - | FK → organisation.id ON DELETE CASCADE |
| created_at | TIMESTAMP | NO | NOW() | - |
For every JSONB/JSON column:
Example:
### calculationData (JSONB) [MUST]
**Source:** Inferred from `snapshot-operations.ts:180-195`
```typescript
{
periodIntervals: number;
intervalType: 'hour' | 'day' | 'week' | 'month';
total: number;
capexPercentage: number; // 0-100
totalCapex: number;
totalOpex: number;
}
### Index Documentation [SHOULD]
Document ALL indexes with:
- Index name
- Columns covered
- Type (btree, gin, partial)
- Rationale (if apparent from naming or usage)
## Mandatory Tagging
**Every table, function, and schema must have a [MUST], [SHOULD], or [DON'T] tag in its heading.**
Default categorizations for database layer:
- **[MUST]**: All tables, core repository functions, JSONB schemas
- **[SHOULD]**: Audit/logging tables, test utilities, performance indexes
- **[DON'T]**: ORM-specific query patterns, migration-specific syntax
Example:
```markdown
### users [MUST]
### audit_logs [SHOULD]
### FindUserByEmail [MUST]
### GetTestDBPath [SHOULD]
See analysis-principles.md section 9 for full tagging rules.
If docs/unwind/layers/database/ exists, compare current state and add ## Changes Since Last Review section to index.md.
npx claudepluginhub cliftonc/unwind --plugin unwindFetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Applies a firm's KYC/AML rules grid to parsed onboarding records: assigns risk rating, checks required documents, outputs rule outcomes with citations, and routes for escalation.
Generates daily or weekly digests of activity from connected sources (chat, email, docs, tasks, CRM), highlighting action items, decisions, mentions, and project updates.