{
"schemas": {
"accounts": {
"TableName": "accounts",
"Columns": [
{
"Name": "id",
"LogicalField": "id",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": true,
"DefaultValue": "",
"Tags": {
"json": "id"
}
},
{
"Name": "user_id",
"LogicalField": "user_id",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "user_id"
}
},
{
"Name": "provider",
"LogicalField": "provider",
"Type": "string",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "provider"
}
},
{
"Name": "provider_account_id",
"LogicalField": "provider_account_id",
"Type": "string",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "provider_account_id"
}
},
{
"Name": "access_token",
"LogicalField": "access_token",
"Type": "text",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "access_token"
}
},
{
"Name": "refresh_token",
"LogicalField": "refresh_token",
"Type": "text",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "refresh_token"
}
},
{
"Name": "access_token_expires_at",
"LogicalField": "access_token_expires_at",
"Type": "time.Time",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "access_token_expires_at"
}
},
{
"Name": "scope",
"LogicalField": "scope",
"Type": "string",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "scope"
}
},
{
"Name": "id_token",
"LogicalField": "id_token",
"Type": "text",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "id_token"
}
},
{
"Name": "created_at",
"LogicalField": "created_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "@now()",
"Tags": {
"json": "created_at"
}
},
{
"Name": "updated_at",
"LogicalField": "updated_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "updated_at"
}
}
],
"Indexes": [
{
"Name": "idx_accounts_user_id_provider",
"Columns": [
"user_id"
],
"Unique": false
},
{
"Name": "idx_accounts_provider_provider_account_id",
"Columns": [
"provider",
"provider_account_id"
],
"Unique": true
}
],
"ForeignKeys": [
{
"Name": "fk_accounts_users_user_id",
"Column": "user_id",
"ReferencedSchema": "users",
"ReferencedField": "id",
"OnDelete": "RESTRICT",
"OnUpdate": "CASCADE"
}
],
"SchemaName": "accounts",
"Extends": "",
"PluginName": ""
},
"rate_limits": {
"TableName": "rate_limits",
"Columns": [
{
"Name": "id",
"LogicalField": "id",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": true,
"DefaultValue": "",
"Tags": {
"json": "id"
}
},
{
"Name": "key",
"LogicalField": "key",
"Type": "string",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "key"
}
},
{
"Name": "count",
"LogicalField": "count",
"Type": "int",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "count"
}
},
{
"Name": "last_request_at",
"LogicalField": "last_request_at",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "last_request_at"
}
}
],
"Indexes": [
{
"Name": "idx_rate_limits_key",
"Columns": [
"key"
],
"Unique": true
}
],
"ForeignKeys": null,
"SchemaName": "rate_limits",
"Extends": "",
"PluginName": ""
},
"sessions": {
"TableName": "sessions",
"Columns": [
{
"Name": "id",
"LogicalField": "id",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": true,
"DefaultValue": "",
"Tags": {
"json": "id"
}
},
{
"Name": "token",
"LogicalField": "token",
"Type": "string",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "token"
}
},
{
"Name": "user_id",
"LogicalField": "user_id",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "user_id"
}
},
{
"Name": "created_at",
"LogicalField": "created_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "@now()",
"Tags": {
"json": "created_at"
}
},
{
"Name": "expires_at",
"LogicalField": "expires_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "expires_at"
}
},
{
"Name": "last_access",
"LogicalField": "last_access",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "last_access"
}
},
{
"Name": "metadata",
"LogicalField": "metadata",
"Type": "map[string]any",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "metadata"
}
}
],
"Indexes": [
{
"Name": "idx_sessions_token",
"Columns": [
"token"
],
"Unique": true
},
{
"Name": "idx_sessions_user_id",
"Columns": [
"user_id"
],
"Unique": false
}
],
"ForeignKeys": [
{
"Name": "fk_sessions_user_id",
"Column": "user_id",
"ReferencedSchema": "users",
"ReferencedField": "id",
"OnDelete": "RESTRICT",
"OnUpdate": "CASCADE"
}
],
"SchemaName": "sessions",
"Extends": "",
"PluginName": ""
},
"users": {
"TableName": "users",
"Columns": [
{
"Name": "id",
"LogicalField": "id",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": true,
"DefaultValue": "",
"Tags": {
"json": "id"
}
},
{
"Name": "email",
"LogicalField": "email",
"Type": "string",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "email"
}
},
{
"Name": "password",
"LogicalField": "password",
"Type": "string",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "-"
}
},
{
"Name": "email_verified_at",
"LogicalField": "email_verified_at",
"Type": "time.Time",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "email_verified_at"
}
},
{
"Name": "first_name",
"LogicalField": "first_name",
"Type": "string",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "first_name"
}
},
{
"Name": "last_name",
"LogicalField": "last_name",
"Type": "string",
"IsNullable": true,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "last_name"
}
},
{
"Name": "created_at",
"LogicalField": "created_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "@now()",
"Tags": {
"json": "created_at"
}
},
{
"Name": "updated_at",
"LogicalField": "updated_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "updated_at"
}
}
],
"Indexes": [
{
"Name": "idx_users_email",
"Columns": [
"email"
],
"Unique": true
}
],
"ForeignKeys": [],
"SchemaName": "users",
"Extends": "",
"PluginName": ""
},
"verifications": {
"TableName": "verifications",
"Columns": [
{
"Name": "id",
"LogicalField": "id",
"Type": "int64",
"IsNullable": false,
"IsPrimaryKey": true,
"DefaultValue": "",
"Tags": {
"json": "id"
}
},
{
"Name": "subject",
"LogicalField": "subject",
"Type": "string",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "subject"
}
},
{
"Name": "value",
"LogicalField": "value",
"Type": "string",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "value"
}
},
{
"Name": "expires_at",
"LogicalField": "expires_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "expires_at"
}
},
{
"Name": "created_at",
"LogicalField": "created_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "@now()",
"Tags": {
"json": "created_at"
}
},
{
"Name": "updated_at",
"LogicalField": "updated_at",
"Type": "time.Time",
"IsNullable": false,
"IsPrimaryKey": false,
"DefaultValue": "",
"Tags": {
"json": "updated_at"
}
}
],
"Indexes": [
{
"Name": "idx_verifications_value",
"Columns": [
"value"
],
"Unique": true
},
{
"Name": "idx_verifications_subject",
"Columns": [
"subject"
],
"Unique": false
}
],
"ForeignKeys": null,
"SchemaName": "verifications",
"Extends": "",
"PluginName": ""
}
},
"useAutoIncrementID": true
}
Summary
limen generate migrationsgenerates multiple migration files with the same timestamp/version prefix.This causes tools like
golang-migrateto fail because the migration version must be unique. Also, manually renaming the files is error-prone because some generated tables have foreign key dependencies and must be applied in the correct order.Steps to reproduce
.limen/schemas.json
{ "schemas": { "accounts": { "TableName": "accounts", "Columns": [ { "Name": "id", "LogicalField": "id", "Type": "int64", "IsNullable": false, "IsPrimaryKey": true, "DefaultValue": "", "Tags": { "json": "id" } }, { "Name": "user_id", "LogicalField": "user_id", "Type": "int64", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "user_id" } }, { "Name": "provider", "LogicalField": "provider", "Type": "string", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "provider" } }, { "Name": "provider_account_id", "LogicalField": "provider_account_id", "Type": "string", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "provider_account_id" } }, { "Name": "access_token", "LogicalField": "access_token", "Type": "text", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "access_token" } }, { "Name": "refresh_token", "LogicalField": "refresh_token", "Type": "text", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "refresh_token" } }, { "Name": "access_token_expires_at", "LogicalField": "access_token_expires_at", "Type": "time.Time", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "access_token_expires_at" } }, { "Name": "scope", "LogicalField": "scope", "Type": "string", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "scope" } }, { "Name": "id_token", "LogicalField": "id_token", "Type": "text", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "id_token" } }, { "Name": "created_at", "LogicalField": "created_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "@now()", "Tags": { "json": "created_at" } }, { "Name": "updated_at", "LogicalField": "updated_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "updated_at" } } ], "Indexes": [ { "Name": "idx_accounts_user_id_provider", "Columns": [ "user_id" ], "Unique": false }, { "Name": "idx_accounts_provider_provider_account_id", "Columns": [ "provider", "provider_account_id" ], "Unique": true } ], "ForeignKeys": [ { "Name": "fk_accounts_users_user_id", "Column": "user_id", "ReferencedSchema": "users", "ReferencedField": "id", "OnDelete": "RESTRICT", "OnUpdate": "CASCADE" } ], "SchemaName": "accounts", "Extends": "", "PluginName": "" }, "rate_limits": { "TableName": "rate_limits", "Columns": [ { "Name": "id", "LogicalField": "id", "Type": "int64", "IsNullable": false, "IsPrimaryKey": true, "DefaultValue": "", "Tags": { "json": "id" } }, { "Name": "key", "LogicalField": "key", "Type": "string", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "key" } }, { "Name": "count", "LogicalField": "count", "Type": "int", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "count" } }, { "Name": "last_request_at", "LogicalField": "last_request_at", "Type": "int64", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "last_request_at" } } ], "Indexes": [ { "Name": "idx_rate_limits_key", "Columns": [ "key" ], "Unique": true } ], "ForeignKeys": null, "SchemaName": "rate_limits", "Extends": "", "PluginName": "" }, "sessions": { "TableName": "sessions", "Columns": [ { "Name": "id", "LogicalField": "id", "Type": "int64", "IsNullable": false, "IsPrimaryKey": true, "DefaultValue": "", "Tags": { "json": "id" } }, { "Name": "token", "LogicalField": "token", "Type": "string", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "token" } }, { "Name": "user_id", "LogicalField": "user_id", "Type": "int64", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "user_id" } }, { "Name": "created_at", "LogicalField": "created_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "@now()", "Tags": { "json": "created_at" } }, { "Name": "expires_at", "LogicalField": "expires_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "expires_at" } }, { "Name": "last_access", "LogicalField": "last_access", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "last_access" } }, { "Name": "metadata", "LogicalField": "metadata", "Type": "map[string]any", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "metadata" } } ], "Indexes": [ { "Name": "idx_sessions_token", "Columns": [ "token" ], "Unique": true }, { "Name": "idx_sessions_user_id", "Columns": [ "user_id" ], "Unique": false } ], "ForeignKeys": [ { "Name": "fk_sessions_user_id", "Column": "user_id", "ReferencedSchema": "users", "ReferencedField": "id", "OnDelete": "RESTRICT", "OnUpdate": "CASCADE" } ], "SchemaName": "sessions", "Extends": "", "PluginName": "" }, "users": { "TableName": "users", "Columns": [ { "Name": "id", "LogicalField": "id", "Type": "int64", "IsNullable": false, "IsPrimaryKey": true, "DefaultValue": "", "Tags": { "json": "id" } }, { "Name": "email", "LogicalField": "email", "Type": "string", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "email" } }, { "Name": "password", "LogicalField": "password", "Type": "string", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "-" } }, { "Name": "email_verified_at", "LogicalField": "email_verified_at", "Type": "time.Time", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "email_verified_at" } }, { "Name": "first_name", "LogicalField": "first_name", "Type": "string", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "first_name" } }, { "Name": "last_name", "LogicalField": "last_name", "Type": "string", "IsNullable": true, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "last_name" } }, { "Name": "created_at", "LogicalField": "created_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "@now()", "Tags": { "json": "created_at" } }, { "Name": "updated_at", "LogicalField": "updated_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "updated_at" } } ], "Indexes": [ { "Name": "idx_users_email", "Columns": [ "email" ], "Unique": true } ], "ForeignKeys": [], "SchemaName": "users", "Extends": "", "PluginName": "" }, "verifications": { "TableName": "verifications", "Columns": [ { "Name": "id", "LogicalField": "id", "Type": "int64", "IsNullable": false, "IsPrimaryKey": true, "DefaultValue": "", "Tags": { "json": "id" } }, { "Name": "subject", "LogicalField": "subject", "Type": "string", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "subject" } }, { "Name": "value", "LogicalField": "value", "Type": "string", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "value" } }, { "Name": "expires_at", "LogicalField": "expires_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "expires_at" } }, { "Name": "created_at", "LogicalField": "created_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "@now()", "Tags": { "json": "created_at" } }, { "Name": "updated_at", "LogicalField": "updated_at", "Type": "time.Time", "IsNullable": false, "IsPrimaryKey": false, "DefaultValue": "", "Tags": { "json": "updated_at" } } ], "Indexes": [ { "Name": "idx_verifications_value", "Columns": [ "value" ], "Unique": true }, { "Name": "idx_verifications_subject", "Columns": [ "subject" ], "Unique": false } ], "ForeignKeys": null, "SchemaName": "verifications", "Extends": "", "PluginName": "" } }, "useAutoIncrementID": true }Expected behaviour
The CLI should generate migration filenames with unique, monotonically increasing versions in an order that respects foreign key dependencies.
For example:
The exact order of independent tables does not matter, but dependent tables should come after the tables they reference.
Alternatively, generating a single migration file containing all table creation statements in dependency-safe order would also avoid the duplicate version issue.
Actual behaviour
limen generate migrationsgenerates multiple migration files with the same timestamp/version prefix.Affected module
cmd/limen (CLI)
Limen version(s)
v0.1.1
Go version
go version go1.26.4 darwin/arm64
OS / environment
macOS 26.3
Additional context
No response
Checklist