From 9557c9ca165d8d49b3f16aa0ee1ac0826d3cb14d Mon Sep 17 00:00:00 2001 From: iven Date: Sun, 12 Apr 2026 16:58:47 +0800 Subject: [PATCH] fix(db): resolve migration bugs preventing fresh database initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix composite primary keys in role_permissions and user_roles tables (PostgreSQL does not allow multiple PRIMARY KEY constraints) - Fix FK table name mismatch: tasks → tokens (was wf_tokens) - Fix FK table name mismatch: messages → message_templates (was message_templates_ref) - Fix tenant table name in main.rs SQL: tenant (not tenants) - Fix React Router nested routes: add /* wildcard for child route matching --- apps/web/src/App.tsx | 2 +- ...20260411_000007_create_role_permissions.rs | 19 +++++++------------ .../src/m20260411_000008_create_user_roles.rs | 19 +++++++------------ .../src/m20260412_000021_create_tasks.rs | 4 ++-- .../src/m20260413_000024_create_messages.rs | 4 ++-- crates/erp-server/src/main.rs | 4 ++-- 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 6553387..ad7e097 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -39,7 +39,7 @@ export default function App() { } /> diff --git a/crates/erp-server/migration/src/m20260411_000007_create_role_permissions.rs b/crates/erp-server/migration/src/m20260411_000007_create_role_permissions.rs index 3781969..9c7ac4c 100644 --- a/crates/erp-server/migration/src/m20260411_000007_create_role_permissions.rs +++ b/crates/erp-server/migration/src/m20260411_000007_create_role_permissions.rs @@ -11,18 +11,8 @@ impl MigrationTrait for Migration { Table::create() .table(RolePermissions::Table) .if_not_exists() - .col( - ColumnDef::new(RolePermissions::RoleId) - .uuid() - .not_null() - .primary_key(), - ) - .col( - ColumnDef::new(RolePermissions::PermissionId) - .uuid() - .not_null() - .primary_key(), - ) + .col(ColumnDef::new(RolePermissions::RoleId).uuid().not_null()) + .col(ColumnDef::new(RolePermissions::PermissionId).uuid().not_null()) .col(ColumnDef::new(RolePermissions::TenantId).uuid().not_null()) .col( ColumnDef::new(RolePermissions::CreatedAt) @@ -49,6 +39,11 @@ impl MigrationTrait for Migration { .not_null() .default(1), ) + .primary_key( + Index::create() + .col(RolePermissions::RoleId) + .col(RolePermissions::PermissionId), + ) .foreign_key( &mut ForeignKey::create() .name("fk_role_permissions_role_id") diff --git a/crates/erp-server/migration/src/m20260411_000008_create_user_roles.rs b/crates/erp-server/migration/src/m20260411_000008_create_user_roles.rs index 017bb78..bd155d1 100644 --- a/crates/erp-server/migration/src/m20260411_000008_create_user_roles.rs +++ b/crates/erp-server/migration/src/m20260411_000008_create_user_roles.rs @@ -11,18 +11,8 @@ impl MigrationTrait for Migration { Table::create() .table(UserRoles::Table) .if_not_exists() - .col( - ColumnDef::new(UserRoles::UserId) - .uuid() - .not_null() - .primary_key(), - ) - .col( - ColumnDef::new(UserRoles::RoleId) - .uuid() - .not_null() - .primary_key(), - ) + .col(ColumnDef::new(UserRoles::UserId).uuid().not_null()) + .col(ColumnDef::new(UserRoles::RoleId).uuid().not_null()) .col(ColumnDef::new(UserRoles::TenantId).uuid().not_null()) .col( ColumnDef::new(UserRoles::CreatedAt) @@ -49,6 +39,11 @@ impl MigrationTrait for Migration { .not_null() .default(1), ) + .primary_key( + Index::create() + .col(UserRoles::UserId) + .col(UserRoles::RoleId), + ) .foreign_key( &mut ForeignKey::create() .name("fk_user_roles_user_id") diff --git a/crates/erp-server/migration/src/m20260412_000021_create_tasks.rs b/crates/erp-server/migration/src/m20260412_000021_create_tasks.rs index ea4fee7..e919fee 100644 --- a/crates/erp-server/migration/src/m20260412_000021_create_tasks.rs +++ b/crates/erp-server/migration/src/m20260412_000021_create_tasks.rs @@ -108,7 +108,7 @@ impl MigrationTrait for Migration { ForeignKey::create() .name("fk_tasks_token") .from(Tasks::Table, Tasks::TokenId) - .to(WfTokens::Table, WfTokens::Id) + .to(Tokens::Table, Tokens::Id) .to_owned(), ) .await?; @@ -154,7 +154,7 @@ enum ProcessInstances { } #[derive(DeriveIden)] -enum WfTokens { +enum Tokens { Table, Id, } diff --git a/crates/erp-server/migration/src/m20260413_000024_create_messages.rs b/crates/erp-server/migration/src/m20260413_000024_create_messages.rs index 21b9f6a..ba7b1ef 100644 --- a/crates/erp-server/migration/src/m20260413_000024_create_messages.rs +++ b/crates/erp-server/migration/src/m20260413_000024_create_messages.rs @@ -93,7 +93,7 @@ impl MigrationTrait for Migration { ForeignKey::create() .name("fk_messages_template") .from(Messages::Table, Messages::TemplateId) - .to(MessageTemplatesRef::Table, MessageTemplatesRef::Id) + .to(MessageTemplates::Table, MessageTemplates::Id) .to_owned(), ) .await?; @@ -137,7 +137,7 @@ enum Messages { } #[derive(DeriveIden)] -enum MessageTemplatesRef { +enum MessageTemplates { Table, Id, } diff --git a/crates/erp-server/src/main.rs b/crates/erp-server/src/main.rs index 245cc14..1bfce17 100644 --- a/crates/erp-server/src/main.rs +++ b/crates/erp-server/src/main.rs @@ -62,7 +62,7 @@ async fn main() -> anyhow::Result<()> { let existing = TenantId::find_by_statement(sea_orm::Statement::from_string( sea_orm::DatabaseBackend::Postgres, - "SELECT id FROM tenants WHERE deleted_at IS NULL LIMIT 1".to_string(), + "SELECT id FROM tenant WHERE deleted_at IS NULL LIMIT 1".to_string(), )) .one(&db) .await @@ -79,7 +79,7 @@ async fn main() -> anyhow::Result<()> { // Insert default tenant using raw SQL (no tenant entity in erp-server) db.execute(sea_orm::Statement::from_sql_and_values( sea_orm::DatabaseBackend::Postgres, - "INSERT INTO tenants (id, name, code, status, created_at, updated_at) VALUES ($1, $2, $3, $4, NOW(), NOW())", + "INSERT INTO tenant (id, name, code, status, created_at, updated_at) VALUES ($1, $2, $3, $4, NOW(), NOW())", [ new_tenant_id.into(), "Default Tenant".into(),