Phase 1b: Rename all ~94 commands across 12 plugins to /<noun> <action> sub-command pattern. Git-flow consolidated from 8→5 commands (commit variants absorbed into --push/--merge/--sync flags). Dispatch files, name: frontmatter, and cross-reference updates for all plugins. Phase 2: Design documents for 8 new plugins in docs/designs/. Phase 3: Scaffold 8 new plugins — saas-api-platform, saas-db-migrate, saas-react-platform, saas-test-pilot, data-seed, ops-release-manager, ops-deploy-pipeline, debug-mcp. Each with plugin.json, commands, agents, skills, README, and claude-md-integration. Marketplace grows from 12→20. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
82 lines
3.4 KiB
Markdown
82 lines
3.4 KiB
Markdown
---
|
|
name: schema-inference
|
|
description: Infer data types, constraints, and relationships from ORM models or raw SQL DDL
|
|
---
|
|
|
|
# Schema Inference
|
|
|
|
## Purpose
|
|
|
|
Parse and normalize schema definitions from multiple ORM dialects into a unified internal representation. This skill enables data generation and validation commands to work across SQLAlchemy, Prisma, Django ORM, and raw SQL DDL without dialect-specific logic in every command.
|
|
|
|
---
|
|
|
|
## Supported Schema Sources
|
|
|
|
| Source | Detection | File Patterns |
|
|
|--------|-----------|---------------|
|
|
| SQLAlchemy | `from sqlalchemy import`, `Column(`, `mapped_column(` | `models.py`, `models/*.py` |
|
|
| Prisma | `model` blocks with `@id`, `@relation` | `prisma/schema.prisma` |
|
|
| Django ORM | `from django.db import models`, `models.CharField` | `models.py` with Django imports |
|
|
| Raw SQL DDL | `CREATE TABLE` statements | `*.sql`, `schema.sql`, `migrations/*.sql` |
|
|
| JSON Schema | `"type": "object"`, `"properties":` | `*.schema.json` |
|
|
|
|
## Type Normalization
|
|
|
|
Map dialect-specific types to a canonical set:
|
|
|
|
| Canonical Type | SQLAlchemy | Prisma | Django | SQL |
|
|
|----------------|------------|--------|--------|-----|
|
|
| `string` | `String(N)`, `Text` | `String` | `CharField`, `TextField` | `VARCHAR(N)`, `TEXT` |
|
|
| `integer` | `Integer`, `BigInteger`, `SmallInteger` | `Int`, `BigInt` | `IntegerField`, `BigIntegerField` | `INT`, `BIGINT`, `SMALLINT` |
|
|
| `float` | `Float`, `Numeric` | `Float` | `FloatField` | `FLOAT`, `REAL`, `DOUBLE` |
|
|
| `decimal` | `Numeric(P,S)` | `Decimal` | `DecimalField` | `DECIMAL(P,S)`, `NUMERIC(P,S)` |
|
|
| `boolean` | `Boolean` | `Boolean` | `BooleanField` | `BOOLEAN`, `BIT` |
|
|
| `datetime` | `DateTime` | `DateTime` | `DateTimeField` | `TIMESTAMP`, `DATETIME` |
|
|
| `date` | `Date` | `DateTime` | `DateField` | `DATE` |
|
|
| `uuid` | `UUID` | `String @default(uuid())` | `UUIDField` | `UUID` |
|
|
| `json` | `JSON` | `Json` | `JSONField` | `JSON`, `JSONB` |
|
|
| `enum` | `Enum(...)` | `enum` block | `choices=` | `ENUM(...)`, `CHECK IN (...)` |
|
|
|
|
## Constraint Extraction
|
|
|
|
For each column, extract:
|
|
- **nullable**: Whether NULL values are allowed (default: true unless PK or explicit NOT NULL)
|
|
- **unique**: Whether values must be unique
|
|
- **max_length**: For string types, the maximum character length
|
|
- **precision/scale**: For decimal types
|
|
- **default**: Default value expression
|
|
- **check**: CHECK constraint expressions (e.g., `age >= 0`)
|
|
- **primary_key**: Whether this column is part of the primary key
|
|
|
|
## Relationship Extraction
|
|
|
|
Identify foreign key relationships:
|
|
- **parent_table**: The referenced table
|
|
- **parent_column**: The referenced column (usually PK)
|
|
- **on_delete**: CASCADE, SET NULL, RESTRICT, NO ACTION
|
|
- **self_referential**: True if FK references same table
|
|
- **many_to_many**: Detected from junction/through tables with two FKs and no additional non-FK columns
|
|
|
|
## Output Format
|
|
|
|
Internal representation used by other skills:
|
|
|
|
```json
|
|
{
|
|
"tables": {
|
|
"users": {
|
|
"columns": {
|
|
"id": {"type": "integer", "primary_key": true, "nullable": false},
|
|
"email": {"type": "string", "max_length": 255, "unique": true, "nullable": false},
|
|
"name": {"type": "string", "max_length": 100, "nullable": false},
|
|
"manager_id": {"type": "integer", "nullable": true, "foreign_key": {"table": "users", "column": "id"}}
|
|
},
|
|
"relationships": [
|
|
{"type": "self_referential", "column": "manager_id", "references": "users.id"}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|