一键导入
db-migration
Create or update database schema and generate migrations. Use when modifying ent schema, adding database fields/tables, or generating migration files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create or update database schema and generate migrations. Use when modifying ent schema, adding database fields/tables, or generating migration files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Work on OpenMeter currency primitives in pkg/currencyx for fiat and custom currency codes, shared currency interfaces, rounding modes, calculators, allocation precision, fiat/custom boundaries, and callers in billing, charges, ledger, product catalog, subscriptions, API, or currency registry code.
Work with OpenMeter billing charges, including the root charges facade, charge meta queries, charge creation and advancement, usage-based lifecycle state machines, realization runs, and charges test setup. Use when modifying `openmeter/billing/charges/...` or charge-related tests.
Write end-to-end tests for OpenMeter against a live server. Use when adding tests under e2e/ that exercise API endpoints over HTTP (v1 generated SDK or v3 raw HTTP).
Work with the OpenMeter billing package. Use this skill whenever touching invoice lifecycle, billing profiles, customer overrides, invoice line items, gathering invoices, standard invoices, the invoice state machine, billing validation issues, billing-subscription sync, the billing worker, invoice calculation, rating/pricing engine, or tax config on billing objects. Also use when writing or debugging billing integration tests (BaseSuite, SubscriptionMixin), billing adapter (Ent queries), billing HTTP handlers, or the subscription→billing sync algorithm. Trigger this skill for any file under `openmeter/billing/`, `openmeter/billing/worker/`, `openmeter/billing/service/`, `openmeter/billing/adapter/`, `openmeter/billing/rating/`, `test/billing/`, or `cmd/billing-worker/`.
Use when writing or refactoring Go collection/pointer helper code in OpenMeter, especially when choosing between standard library slices/maps helpers and github.com/samber/lo for cloning, copying, equality, sorting, pointer literals, slice-to-map transforms, map keys/values, mapping, filtering, grouping, uniqueness, set-like conversions, and map entry transformations.
Add or modify API endpoints using TypeSpec. Use when adding new API routes, modifying request/response types, or changing the OpenAPI spec.
| name | db-migration |
| description | Create or update database schema and generate migrations. Use when modifying ent schema, adding database fields/tables, or generating migration files. |
| user-invocable | true |
| argument-hint | [description of schema change] |
| allowed-tools | Read, Edit, Write, Bash, Grep, Glob, Agent |
You are helping the user modify the OpenMeter database schema and generate a corresponding migration.
openmeter/ent/schema/*.go — ent schema definitions (source of truth)openmeter/ent/db/ — DO NOT edit manuallytools/migrate/migrations/ — DO NOT edit manually--env local — we do not use Atlas Cloud servicesFollow these steps in order:
Edit or create files in openmeter/ent/schema/. Look at existing schema files for conventions.
If the user described what change they want ($ARGUMENTS), implement it. Otherwise, ask what schema changes are needed. When creating a new schema always define schema to support soft delete.
Schemas supporting soft delete always have a deleted_at field.
Run:
make generate
This runs go generate ./... which regenerates the ent client code in openmeter/ent/db/ from the schema definitions. Check that it completes without errors.
Run:
atlas migrate --env local diff <migration-name>
Where <migration-name> is a short descriptive snake_case name for the change (e.g., add_customer_email, create_invoice_table). Derive the name from the schema change being made.
This creates timestamped .up.sql and .down.sql files in tools/migrate/migrations/ and updates atlas.sum.
If the schema includes ent views (schemas with ent.View), the generated view SQL must be manually copied into the .up.sql migration file. Atlas does not auto-generate view DDL.
make generate to regenerate tools/migrate/views.sql from ent view schemasCREATE VIEW statements from tools/migrate/views.sql into the end of the generated .up.sql migration fileDROP VIEW IF EXISTS "<view_name>" statement before the CREATE VIEWThe view parity test (TestViewDefinitionsMatchGeneratedSchemaSQL in tools/migrate/view_parity_test.go) validates that view definitions in migrations match the generated view SQL. It strips individual VIEW statements from migration files while preserving all other DDL statements in the same file, so mixing VIEW and non-VIEW statements in a single migration is safe.
Read the generated .up.sql file and verify:
Present a summary of the migration to the user.
From pkg/framework/entutils/mixins.go:
| Mixin | Fields | Notes |
|---|---|---|
entutils.IDMixin{} | id char(26) ULID | Auto-generated, unique, immutable |
entutils.NamespaceMixin{} | namespace string | Immutable, indexed |
entutils.TimeMixin{} | created_at, updated_at, deleted_at (nillable) | Provides soft delete support |
entutils.MetadataMixin{} | metadata JSONB map[string]string | Optional |
entutils.ResourceMixin{} | ID + Namespace + Metadata + Time + name + description | Composite of above mixins |
entutils.UniqueResourceMixin{} | Resource + key | Adds unique index on (namespace, key, deleted_at) |
entutils.KeyMixin{} | key string | Immutable, not empty |
entutils.CadencedMixin{} | active_from, active_to (nillable) | For time-bounded entities |
Usage in schema:
func (<Entity>) Mixin() []ent.Mixin {
return []ent.Mixin{
entutils.IDMixin{},
entutils.NamespaceMixin{},
entutils.TimeMixin{},
}
}
For fields, edges (relationships), and indexes, read existing schemas in openmeter/ent/schema/ for conventions. Key things to know:
entutils.JSONStringValueScanner — see openmeter/ent/schema/llmcostprice.gochar(26) schema type to match ULID IDsdeleted_at in the unique constraint (e.g., index.Fields("namespace", "key", "deleted_at").Unique()) — always filter with Where(<entity>db.DeletedAtIsNil()) in queriesentsql.OnDelete(entsql.Cascade) on the parent edgeIf the atlas.sum file gets out of sync (e.g., after manually editing a migration file or resolving conflicts), rehash it:
atlas migrate --env local hash
Atlas uses a Docker-based dev database (docker://postgres/15/dev) for diffing. Make sure Docker is running before generating migrations.
Migrations are generated, never edit them manually. Migrations use golang-migrate format. Each migration has:
<timestamp>_<name>.up.sql — applied when migrating up<timestamp>_<name>.down.sql — applied when migrating down--env local with atlas commandsopenmeter/ent/db/ manuallytools/migrate/migrations manuallymake generate before atlas migrate diff so the ent code is up to datemake generate