fix(evolution): handle super admin login without tenant context
- Update AdminPostgresRepository.findByUsername to support super admin - Add fallback to find super admin by username and isSuperAdmin flag - Add is_super_admin column to admins table Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
0d2e521d69
commit
2df8478d61
|
|
@ -42,7 +42,8 @@
|
||||||
"Bash(pnpm --filter @iconsulting/shared build:*)",
|
"Bash(pnpm --filter @iconsulting/shared build:*)",
|
||||||
"Bash(pnpm --filter @iconsulting/user-service build:*)",
|
"Bash(pnpm --filter @iconsulting/user-service build:*)",
|
||||||
"Bash(pnpm --filter @iconsulting/conversation-service build:*)",
|
"Bash(pnpm --filter @iconsulting/conversation-service build:*)",
|
||||||
"Bash(pnpm --filter @iconsulting/payment-service build:*)"
|
"Bash(pnpm --filter @iconsulting/payment-service build:*)",
|
||||||
|
"Bash(findstr:*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
-- Migration: Add tenant_id column to all tables for multi-tenancy support
|
||||||
|
-- Date: 2026-01-26
|
||||||
|
-- Description: Complete migration to add tenant_id to all service tables
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- User Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE verification_codes ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_users_tenant ON users(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_users_tenant_phone ON users(tenant_id, phone);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_users_tenant_fingerprint ON users(tenant_id, fingerprint);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_verification_codes_tenant ON verification_codes(tenant_id);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN users.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN verification_codes.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Evolution Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
ALTER TABLE admins ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE admin_users ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE audit_logs ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE evolution_logs ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE daily_statistics ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE monthly_financial_reports ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_admins_tenant ON admins(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_admin_users_tenant ON admin_users(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_audit_logs_tenant ON audit_logs(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_evolution_logs_tenant ON evolution_logs(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_daily_statistics_tenant ON daily_statistics(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_monthly_financial_reports_tenant ON monthly_financial_reports(tenant_id);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN admins.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN admin_users.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN audit_logs.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Conversation Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE messages ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE token_usages ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_conversations_tenant ON conversations(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_messages_tenant ON messages(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_token_usages_tenant ON token_usages(tenant_id);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN conversations.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN messages.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN token_usages.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Knowledge Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
ALTER TABLE documents ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE document_embeddings ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE knowledge_articles ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE knowledge_chunks ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE user_memories ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE experiences ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_documents_tenant ON documents(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_document_embeddings_tenant ON document_embeddings(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_knowledge_articles_tenant ON knowledge_articles(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_knowledge_chunks_tenant ON knowledge_chunks(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_user_memories_tenant ON user_memories(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_experiences_tenant ON experiences(tenant_id);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN documents.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN knowledge_articles.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN user_memories.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Payment Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
ALTER TABLE orders ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE payments ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE ledger_entries ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE coupons ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE user_coupons ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
ALTER TABLE service_pricing ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_orders_tenant ON orders(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_payments_tenant ON payments(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ledger_entries_tenant ON ledger_entries(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_coupons_tenant ON coupons(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_user_coupons_tenant ON user_coupons(tenant_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_service_pricing_tenant ON service_pricing(tenant_id);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN orders.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN payments.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
COMMENT ON COLUMN ledger_entries.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- File Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
ALTER TABLE files ADD COLUMN IF NOT EXISTS tenant_id uuid;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_files_tenant ON files(tenant_id);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN files.tenant_id IS 'Tenant ID for multi-tenancy support';
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Verification
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Run this after migration to verify:
|
||||||
|
-- SELECT table_name, column_name FROM information_schema.columns
|
||||||
|
-- WHERE column_name = 'tenant_id' AND table_schema = 'public'
|
||||||
|
-- ORDER BY table_name;
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
-- Migration Rollback: Remove tenant_id column from all tables
|
||||||
|
-- Date: 2026-01-26
|
||||||
|
-- Description: Rollback multi-tenancy support from all tables
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- File Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS idx_files_tenant;
|
||||||
|
ALTER TABLE files DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Payment Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS idx_service_pricing_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_user_coupons_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_coupons_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_ledger_entries_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_payments_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_orders_tenant;
|
||||||
|
|
||||||
|
ALTER TABLE service_pricing DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE user_coupons DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE coupons DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE ledger_entries DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE payments DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE orders DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Knowledge Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS idx_experiences_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_user_memories_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_knowledge_chunks_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_knowledge_articles_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_document_embeddings_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_documents_tenant;
|
||||||
|
|
||||||
|
ALTER TABLE experiences DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE user_memories DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE knowledge_chunks DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE knowledge_articles DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE document_embeddings DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE documents DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Conversation Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS idx_token_usages_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_messages_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_conversations_tenant;
|
||||||
|
|
||||||
|
ALTER TABLE token_usages DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE messages DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE conversations DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Evolution Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS idx_monthly_financial_reports_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_daily_statistics_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_evolution_logs_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_audit_logs_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_admin_users_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_admins_tenant;
|
||||||
|
|
||||||
|
ALTER TABLE monthly_financial_reports DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE daily_statistics DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE evolution_logs DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE audit_logs DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE admin_users DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE admins DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- User Service Tables
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS idx_verification_codes_tenant;
|
||||||
|
DROP INDEX IF EXISTS idx_users_tenant_fingerprint;
|
||||||
|
DROP INDEX IF EXISTS idx_users_tenant_phone;
|
||||||
|
DROP INDEX IF EXISTS idx_users_tenant;
|
||||||
|
|
||||||
|
ALTER TABLE verification_codes DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
ALTER TABLE users DROP COLUMN IF EXISTS tenant_id;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
@ -35,8 +35,20 @@ export class AdminPostgresRepository implements IAdminRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
async findByUsername(username: string): Promise<AdminEntity | null> {
|
async findByUsername(username: string): Promise<AdminEntity | null> {
|
||||||
|
// Try to find by username with tenant context first
|
||||||
|
try {
|
||||||
|
const tenantId = this.getTenantId();
|
||||||
|
const orm = await this.adminRepo.findOne({
|
||||||
|
where: { username, tenantId },
|
||||||
|
});
|
||||||
|
if (orm) return this.toEntity(orm);
|
||||||
|
} catch (error) {
|
||||||
|
// If no tenant context, continue to check for super admin
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for super admin without tenant constraint
|
||||||
const orm = await this.adminRepo.findOne({
|
const orm = await this.adminRepo.findOne({
|
||||||
where: { username, tenantId: this.getTenantId() },
|
where: { username, isSuperAdmin: true },
|
||||||
});
|
});
|
||||||
return orm ? this.toEntity(orm) : null;
|
return orm ? this.toEntity(orm) : null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue