/designing-data-model
Designing the physical data model as a real stack-native schema (schema.sql with CREATE TABLE DDL, indexes, and constraints for Postgres/Go; schema.prisma for Prisma/TS; Postgres schema.sql as fallback) from the Gate 4 OpenAPI spec and TRD. Gate 5 of
$ npx -y skills add LerianStudio/ring --skill designing-data-model --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
/designing-data-model
Context preview
The summary Claude sees to decide when to auto-load this skill.
Designing the physical data model as a real stack-native schema (schema.sql with CREATE TABLE DDL, indexes, and constraints for Postgres/Go; schema.prisma for Prisma/TS; Postgres schema.sql as fallback) from the Gate 4 OpenAPI spec and TRD. Gate 5 of
SKILL.md
designing-data-model.SKILL.mdname: ring:designing-data-model
description: "Designing the physical data model as a real stack-native schema (schema.sql with CREATE TABLE DDL, indexes, and constraints for Postgres/Go; schema.prisma for Prisma/TS; Postgres schema.sql as fallback) from the Gate 4 OpenAPI spec and TRD. Gate 5 of ring:planning-large-features; runs after ring:designing-api-contracts, before ring:pinning-dependency-versions. Use when the system stores persistent data. Skip for Small Track, no persistent data, or an unvalidated API contract."
Data Modeling — Producing the Stack-Native Schema
When to use
- OpenAPI spec passed Gate 4 validation (or Gate 4 SKIPPED for features with no API surface)
- System stores persistent data
- Large Track workflow (2+ day features)
Skip when
- Small Track workflow → skip to ring:writing-plans
- No persistent data → skip to Dependency Map
- OpenAPI spec not validated (and Gate 4 not SKIPPED) → complete Gate 4 first
Sequence
**Runs before:** ring:pinning-dependency-versions **Runs after:** ring:designing-api-contracts
The deliverable is a REAL, stack-native schema file — DDL that becomes migrations, not markdown tables. The DDL **IS** the deliverable: `CREATE TABLE`, indexes, and constraints are required, not forbidden.
Phase 0: Database Field Naming Strategy (MANDATORY)
See [shared-patterns/standards-discovery.md](../shared-patterns/standards-discovery.md) for the complete workflow.
Step 1: Check for Gate 4 API standards
If `docs/pre-dev/{feature}/api-standards-ref.md` exists, auto-detect naming convention.
Step 2: Ask user
**If api-standards-ref.md EXISTS:** AskUserQuestion: "How should database fields be named?"
- "Convert to snake_case (Recommended)" — API: userId → DB: user_id
- "Keep same as API (camelCase)" — API: userId → DB: userId
- "Different standards — provide DB dictionary"
- "Define manually"
**If api-standards-ref.md DOES NOT EXIST:** AskUserQuestion: "How should database fields be named?"
- "Use snake_case (Recommended)" — standard for PostgreSQL/MySQL
- "Use camelCase" — standard for MongoDB/document DBs
- "Load from standards document"
- "Define manually"
Step 3: Generate `db-standards-ref.md`
**Option: Convert to snake_case** — apply automatic rules:
- userId → user_id, createdAt → created_at, isActive → is_active, phoneNumber → phone_number, userID → user_id
**Option: Keep same** — copy field names without modification.
**Option: Load from doc** — WebFetch or read, extract field definitions, save to `db-standards-ref.md`.
Phase 1: Stack Detection (MANDATORY)
Determine the schema format from the TopologyConfig (research.md frontmatter) plus repo manifests:
| Evidence | Format | Output File | |----------|--------|-------------| | `language: golang` in TopologyConfig, `go.mod` present, Postgres in TRD/stack | PostgreSQL DDL | `docs/pre-dev/{feature}/schema.sql` | | `prisma/` directory or `@prisma/client` in package.json | Prisma schema | `docs/pre-dev/{feature}/schema.prisma` | | Other stack with a native schema format (e.g., Drizzle, SQLAlchemy) | That stack's native format | `docs/pre-dev/{feature}/schema.{ext}` | | Undetectable / greenfield | PostgreSQL DDL (Lerian default) | `docs/pre-dev/{feature}/schema.sql` |
Postgres is the Lerian default. When in doubt, write `schema.sql`.
Mandatory Workflow
| Phase | Activities | |-------|------------| | **2. Entity Identification** | From OpenAPI spec (Gate 4 schemas) and TRD (Gate 3): identify all persisted entities; determine aggregate boundaries; map ownership per service | | **3. Schema Authoring** | Write the schema file: tables/models with typed columns, PK/FK constraints, NOT NULL, CHECK/enum constraints, indexes for known query patterns; apply naming from Phase 0 | | **4. Validation** | Run the Gate 5 checklist; verify the file parses (e.g., `psql --dry-run`-style review or `npx prisma validate`) |
Schema Requirements
The schema file MUST be migration-ready:
- Every table/model: explicit PK (`uuid` default at Lerian), `created_at`/`updated_at` timestamps (UTC, `timestamptz`)
- Foreign keys with explicit `ON DELETE` behavior — no implicit cascade decisions
- Lifecycle states as `CHECK` constraints or native enums (`ACTIVE`, `INACTIVE`, ...)
- Indexes for every query pattern implied by the OpenAPI list/filter operations
- Soft-delete (`deleted_at`) only where the TRD requires retention
- **Entity ownership** documented as comment headers per table/model: `-- owner: {service-name}` (or `/// owner:` in Prisma). Multi-service writes to one table are a design smell — flag them.
ER diagram, if useful, goes in a comment header at the top of the schema file or in the TRD — there is no separate `data-model.md` appendix.
schema.sql sketch
-- owner: accounts-service
CREATE TABLE accounts (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name varchar(255) NOT NULL,
status varchar(16) NOT NULL CHECK (status IN ('ACTIVE','INACTIVE','BLOCKED')),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX idx_accounts_status ON accounts (status);Gate 5 Validation Checklist
| Category | Requirements | |----------|--------------| | **Valid schema** | File parses in its native tooling; format matches detected stack; migration-ready (no pseudo-DDL) | | **Entity Completeness** | Every persisted OpenAPI schema has a table/model; ownership comment per entity; lifecycle states constrained | | **Schema Quality** | Precise column types; NOT NULL/CHECK/unique constraints explicit; naming consistent with db-standards-ref.md | | **Relationships** | All FKs declared with explicit ON DELETE behavior; cardinality matches the TRD; join/lookup indexes present | | **API Alignment** | Every column maps to an OpenAPI schema field per the naming strategy (or is documented as internal-only) |
**Gate Result:** ✅ PASS → Dependency Map | ⚠️ CONDITIONAL (fix naming/
Read more
name: ring:designing-data-model description: "Designing the physical data model as a real stack-native schema (schema.sql with CREATE TABLE DDL, indexes, and constraints for Postgres/Go; schema.prisma for Prisma/TS; Postgres schema.sql as fallback) from the Gate 4 OpenAPI spec and TRD. Gate 5 of ring:planning-large-features; runs after ring:designing-api-contracts, before ring:pinning-dependency-versions. Use when the system stores persistent data. Skip for Small Track, no persistent data, or an unvalidated API contract."
Data Modeling — Producing the Stack-Native Schema
When to use
- OpenAPI spec passed Gate 4 validation (or Gate 4 SKIPPED for features with no API surface)
- System stores persistent data
- Large Track workflow (2+ day features)
Skip when
- Small Track workflow → skip to ring:writing-plans
- No persistent data → skip to Dependency Map
- OpenAPI spec not validated (and Gate 4 not SKIPPED) → complete Gate 4 first
Sequence
**Runs before:** ring:pinning-dependency-versions **Runs after:** ring:designing-api-contracts
The deliverable is a REAL, stack-native schema file — DDL that becomes migrations, not markdown tables. The DDL **IS** the deliverable: `CREATE TABLE`, indexes, and constraints are required, not forbidden.
Phase 0: Database Field Naming Strategy (MANDATORY)
See [shared-patterns/standards-discovery.md](../shared-patterns/standards-discovery.md) for the complete workflow.
Step 1: Check for Gate 4 API standards
If `docs/pre-dev/{feature}/api-standards-ref.md` exists, auto-detect naming convention.
Step 2: Ask user
**If api-standards-ref.md EXISTS:** AskUserQuestion: "How should database fields be named?"
- "Convert to snake_case (Recommended)" — API: userId → DB: user_id
- "Keep same as API (camelCase)" — API: userId → DB: userId
- "Different standards — provide DB dictionary"
- "Define manually"
**If api-standards-ref.md DOES NOT EXIST:** AskUserQuestion: "How should database fields be named?"
- "Use snake_case (Recommended)" — standard for PostgreSQL/MySQL
- "Use camelCase" — standard for MongoDB/document DBs
- "Load from standards document"
- "Define manually"
Step 3: Generate `db-standards-ref.md`
**Option: Convert to snake_case** — apply automatic rules:
- userId → user_id, createdAt → created_at, isActive → is_active, phoneNumber → phone_number, userID → user_id
**Option: Keep same** — copy field names without modification.
**Option: Load from doc** — WebFetch or read, extract field definitions, save to `db-standards-ref.md`.
Phase 1: Stack Detection (MANDATORY)
Determine the schema format from the TopologyConfig (research.md frontmatter) plus repo manifests:
| Evidence | Format | Output File | |----------|--------|-------------| | `language: golang` in TopologyConfig, `go.mod` present, Postgres in TRD/stack | PostgreSQL DDL | `docs/pre-dev/{feature}/schema.sql` | | `prisma/` directory or `@prisma/client` in package.json | Prisma schema | `docs/pre-dev/{feature}/schema.prisma` | | Other stack with a native schema format (e.g., Drizzle, SQLAlchemy) | That stack's native format | `docs/pre-dev/{feature}/schema.{ext}` | | Undetectable / greenfield | PostgreSQL DDL (Lerian default) | `docs/pre-dev/{feature}/schema.sql` |
Postgres is the Lerian default. When in doubt, write `schema.sql`.
Mandatory Workflow
| Phase | Activities | |-------|------------| | **2. Entity Identification** | From OpenAPI spec (Gate 4 schemas) and TRD (Gate 3): identify all persisted entities; determine aggregate boundaries; map ownership per service | | **3. Schema Authoring** | Write the schema file: tables/models with typed columns, PK/FK constraints, NOT NULL, CHECK/enum constraints, indexes for known query patterns; apply naming from Phase 0 | | **4. Validation** | Run the Gate 5 checklist; verify the file parses (e.g., `psql --dry-run`-style review or `npx prisma validate`) |
Schema Requirements
The schema file MUST be migration-ready:
- Every table/model: explicit PK (`uuid` default at Lerian), `created_at`/`updated_at` timestamps (UTC, `timestamptz`)
- Foreign keys with explicit `ON DELETE` behavior — no implicit cascade decisions
- Lifecycle states as `CHECK` constraints or native enums (`ACTIVE`, `INACTIVE`, ...)
- Indexes for every query pattern implied by the OpenAPI list/filter operations
- Soft-delete (`deleted_at`) only where the TRD requires retention
- **Entity ownership** documented as comment headers per table/model: `-- owner: {service-name}` (or `/// owner:` in Prisma). Multi-service writes to one table are a design smell — flag them.
ER diagram, if useful, goes in a comment header at the top of the schema file or in the TRD — there is no separate `data-model.md` appendix.
schema.sql sketch
-- owner: accounts-service
CREATE TABLE accounts (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name varchar(255) NOT NULL,
status varchar(16) NOT NULL CHECK (status IN ('ACTIVE','INACTIVE','BLOCKED')),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX idx_accounts_status ON accounts (status);Gate 5 Validation Checklist
| Category | Requirements | |----------|--------------| | **Valid schema** | File parses in its native tooling; format matches detected stack; migration-ready (no pseudo-DDL) | | **Entity Completeness** | Every persisted OpenAPI schema has a table/model; ownership comment per entity; lifecycle states constrained | | **Schema Quality** | Precise column types; NOT NULL/CHECK/unique constraints explicit; naming consistent with db-standards-ref.md | | **Relationships** | All FKs declared with explicit ON DELETE behavior; cardinality matches the TRD; join/lookup indexes present | | **API Alignment** | Every column maps to an OpenAPI schema field per the naming strategy (or is documented as internal-only) |
**Gate Result:** ✅ PASS → Dependency Map | ⚠️ CONDITIONAL (fix naming/
Proven engineering practices, enforced through skills. Ring is a comprehensive skills library and workflow system for AI agents that transforms how AI assistants approach software development.
Repo: LerianStudio/ring
Other skills on ring.
- /analyzing-options
Analyzing different approaches for a task or problem with structured comparisons, effort estimates, and recommendations. Use when facing strategic decisions, architecture choices, or multiple viable approaches. Skip when there's an obvious single approach or the decision is
Open skill - /auditing-production-readiness
Auditing a service's production readiness against Ring engineering standards across base dimensions plus a conditional multi-tenant dimension, then emitting a scored report and an HTML dashboard. Use before production deploy, periodic review, onboarding, or a major release. Skip
Open skill - /cleaning-comments
Cleaning redundant and obvious comments following clean code principles while preserving meaningful documentation. Supports git scope filtering (staged, unstaged, branch, commit-range). Use when code has excessive comments, during code review, or post-refactor cleanup. Skip when
Open skill - /committing-changes
Commit changes with scope allowlist enforcement, atomic grouping, GPG-signed conventional commits, and trailer management. Detects the repo's PR-validation scope policy before proposing any message. Use when the user asks to commit or has changes ready to record. Skip when the
Open skill - /creating-handoffs
Creating a handoff document that captures session state (completed work, decisions, open items, next steps) and delivering it via Plan Mode so the user gets the native 'clear context and continue implementing' resume option. Use when ending a session, when context grows large,
Open skill - /creating-worktrees
Creating an isolated git worktree for parallel branch work: selects the directory by priority order, verifies/adds .gitignore safety, auto-installs the detected toolchain's dependencies, runs a baseline test, and reports readiness. Use before a feature that needs isolation from
Open skill

