fix: add missing deleted_at columns to all plugin tables, fix system-settings response schema, fix transaction rollback in permissions
This commit is contained in:
+11
-3
@@ -105,9 +105,17 @@ async def resolve_permissions(
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
# Check system admin first
|
# Check system admin first
|
||||||
user_q = select(User.is_system_admin).where(User.id == user_id)
|
# If a previous query in this session failed, the transaction may be aborted.
|
||||||
user_result = await db.execute(user_q)
|
# Rollback to recover before executing our query.
|
||||||
is_system_admin = user_result.scalar() or False
|
try:
|
||||||
|
user_q = select(User.is_system_admin).where(User.id == user_id)
|
||||||
|
user_result = await db.execute(user_q)
|
||||||
|
is_system_admin = user_result.scalar() or False
|
||||||
|
except Exception:
|
||||||
|
await db.rollback()
|
||||||
|
user_q = select(User.is_system_admin).where(User.id == user_id)
|
||||||
|
user_result = await db.execute(user_q)
|
||||||
|
is_system_admin = user_result.scalar() or False
|
||||||
|
|
||||||
if is_system_admin:
|
if is_system_admin:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ CREATE TABLE IF NOT EXISTS calendar_entry_links (
|
|||||||
tenant_id UUID NOT NULL,
|
tenant_id UUID NOT NULL,
|
||||||
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
||||||
entity_type VARCHAR(50) NOT NULL,
|
entity_type VARCHAR(50) NOT NULL,
|
||||||
entity_id UUID NOT NULL
|
entity_id UUID NOT NULL,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_entry_links_entry ON calendar_entry_links(entry_id);
|
CREATE INDEX IF NOT EXISTS idx_entry_links_entry ON calendar_entry_links(entry_id);
|
||||||
|
|
||||||
@@ -56,7 +59,10 @@ CREATE TABLE IF NOT EXISTS calendar_shares (
|
|||||||
calendar_id UUID REFERENCES calendars(id) ON DELETE CASCADE,
|
calendar_id UUID REFERENCES calendars(id) ON DELETE CASCADE,
|
||||||
user_id UUID,
|
user_id UUID,
|
||||||
group_id UUID,
|
group_id UUID,
|
||||||
permission VARCHAR(10) NOT NULL
|
permission VARCHAR(10) NOT NULL,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_calendar_shares_cal ON calendar_shares(calendar_id);
|
CREATE INDEX IF NOT EXISTS idx_calendar_shares_cal ON calendar_shares(calendar_id);
|
||||||
|
|
||||||
@@ -74,7 +80,9 @@ CREATE TABLE IF NOT EXISTS subtasks (
|
|||||||
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
||||||
title VARCHAR(500) NOT NULL,
|
title VARCHAR(500) NOT NULL,
|
||||||
completed BOOLEAN DEFAULT false,
|
completed BOOLEAN DEFAULT false,
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_subtasks_entry ON subtasks(entry_id);
|
CREATE INDEX IF NOT EXISTS idx_subtasks_entry ON subtasks(entry_id);
|
||||||
|
|
||||||
@@ -82,7 +90,10 @@ CREATE TABLE IF NOT EXISTS resources (
|
|||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
tenant_id UUID NOT NULL,
|
tenant_id UUID NOT NULL,
|
||||||
name VARCHAR(200) NOT NULL,
|
name VARCHAR(200) NOT NULL,
|
||||||
type VARCHAR(50) NOT NULL
|
type VARCHAR(50) NOT NULL,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_resources_tenant ON resources(tenant_id);
|
CREATE INDEX IF NOT EXISTS idx_resources_tenant ON resources(tenant_id);
|
||||||
|
|
||||||
@@ -92,7 +103,10 @@ CREATE TABLE IF NOT EXISTS resource_bookings (
|
|||||||
resource_id UUID REFERENCES resources(id) ON DELETE CASCADE,
|
resource_id UUID REFERENCES resources(id) ON DELETE CASCADE,
|
||||||
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
||||||
start_at TIMESTAMPTZ NOT NULL,
|
start_at TIMESTAMPTZ NOT NULL,
|
||||||
end_at TIMESTAMPTZ NOT NULL
|
end_at TIMESTAMPTZ NOT NULL,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_bookings_resource ON resource_bookings(resource_id);
|
CREATE INDEX IF NOT EXISTS idx_bookings_resource ON resource_bookings(resource_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_bookings_entry ON resource_bookings(entry_id);
|
CREATE INDEX IF NOT EXISTS idx_bookings_entry ON resource_bookings(entry_id);
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
-- Fix: CalendarEntryLink, CalendarShare, Subtask, Resource, ResourceBooking inherit TenantMixin -> SoftDeleteMixin (deleted_at)
|
||||||
|
-- Migration 0001 only added deleted_at to calendars and calendar_entries
|
||||||
|
ALTER TABLE calendar_entry_links ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE calendar_shares ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE subtasks ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE resources ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE resource_bookings ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
-- Also add missing created_at/updated_at for tables that lacked them
|
||||||
|
ALTER TABLE calendar_entry_links ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE calendar_entry_links ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE calendar_shares ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE calendar_shares ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE subtasks ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE resources ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE resources ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE resource_bookings ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
|
ALTER TABLE resource_bookings ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ DEFAULT NOW();
|
||||||
@@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS entity_links (
|
|||||||
entity_type VARCHAR(20) NOT NULL,
|
entity_type VARCHAR(20) NOT NULL,
|
||||||
entity_id UUID NOT NULL,
|
entity_id UUID NOT NULL,
|
||||||
created_by UUID,
|
created_by UUID,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
CONSTRAINT uq_entity_links_file_entity UNIQUE (tenant_id, file_id, entity_type, entity_id)
|
CONSTRAINT uq_entity_links_file_entity UNIQUE (tenant_id, file_id, entity_type, entity_id)
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- Fix: EntityLink inherits TenantMixin -> SoftDeleteMixin (deleted_at)
|
||||||
|
-- Migration 0001 did not include this column
|
||||||
|
ALTER TABLE entity_links ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- Fix: All mail models inherit TenantMixin -> SoftDeleteMixin (deleted_at)
|
||||||
|
-- Migration 0001 did not include deleted_at on most tables; 0008 only fixed mail_sync_queue
|
||||||
|
-- This migration adds deleted_at to all remaining mail tables
|
||||||
|
ALTER TABLE mail_accounts ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_folders ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mails ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_attachments ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_labels ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_label_assignments ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_rules ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_templates ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_signatures ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE vacation_sent_log ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_seen_by ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_account_delegates ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE mail_account_send_permissions ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE pgp_keys ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE contact_pgp_keys ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
@@ -8,6 +8,7 @@ CREATE TABLE IF NOT EXISTS mcp_server_configs (
|
|||||||
description TEXT,
|
description TEXT,
|
||||||
last_connected_at TIMESTAMPTZ,
|
last_connected_at TIMESTAMPTZ,
|
||||||
created_by UUID,
|
created_by UUID,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- Fix: McpServerConfig inherits TenantMixin -> SoftDeleteMixin (deleted_at)
|
||||||
|
-- Migration 0001 did not include this column, causing queries to crash
|
||||||
|
ALTER TABLE mcp_server_configs ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
@@ -4,6 +4,7 @@ CREATE TABLE IF NOT EXISTS tags (
|
|||||||
tenant_id UUID NOT NULL,
|
tenant_id UUID NOT NULL,
|
||||||
name VARCHAR(100) NOT NULL,
|
name VARCHAR(100) NOT NULL,
|
||||||
color VARCHAR(7) NOT NULL DEFAULT '#6B7280',
|
color VARCHAR(7) NOT NULL DEFAULT '#6B7280',
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
CONSTRAINT uq_tags_tenant_name UNIQUE (tenant_id, name)
|
CONSTRAINT uq_tags_tenant_name UNIQUE (tenant_id, name)
|
||||||
@@ -16,6 +17,7 @@ CREATE TABLE IF NOT EXISTS tag_assignments (
|
|||||||
tag_id UUID NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
|
tag_id UUID NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
|
||||||
entity_type VARCHAR(20) NOT NULL,
|
entity_type VARCHAR(20) NOT NULL,
|
||||||
entity_id UUID NOT NULL,
|
entity_id UUID NOT NULL,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
CONSTRAINT uq_tag_assignments_entity UNIQUE (tenant_id, tag_id, entity_type, entity_id)
|
CONSTRAINT uq_tag_assignments_entity UNIQUE (tenant_id, tag_id, entity_type, entity_id)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Fix: Tag and TagAssignment inherit TenantMixin -> SoftDeleteMixin (deleted_at)
|
||||||
|
-- Migration 0001 did not include this column, causing queries to crash
|
||||||
|
ALTER TABLE tags ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE tag_assignments ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
@@ -11,6 +11,7 @@ CREATE TABLE IF NOT EXISTS unified_search_providers (
|
|||||||
plugin_name VARCHAR(80) NOT NULL,
|
plugin_name VARCHAR(80) NOT NULL,
|
||||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
config JSONB NOT NULL DEFAULT '{}'::jsonb,
|
config JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
UNIQUE(tenant_id, entity_type)
|
UNIQUE(tenant_id, entity_type)
|
||||||
@@ -27,7 +28,9 @@ CREATE TABLE IF NOT EXISTS unified_search_index_log (
|
|||||||
action VARCHAR(20) NOT NULL,
|
action VARCHAR(20) NOT NULL,
|
||||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||||
error_message TEXT,
|
error_message TEXT,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS ix_usil_tenant ON unified_search_index_log(tenant_id);
|
CREATE INDEX IF NOT EXISTS ix_usil_tenant ON unified_search_index_log(tenant_id);
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- Fix: SearchProviderRegistry and SearchIndexLog inherit TenantMixin -> SoftDeleteMixin (deleted_at)
|
||||||
|
-- Migration 0001 did not include this column
|
||||||
|
ALTER TABLE unified_search_providers ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
ALTER TABLE unified_search_index_log ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||||
|
-- SearchIndexLog also needs updated_at (TimestampMixin)
|
||||||
|
ALTER TABLE unified_search_index_log ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT now();
|
||||||
@@ -24,7 +24,7 @@ async def get_system_settings(
|
|||||||
tenant_id = uuid.UUID(current_user["tenant_id"])
|
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||||
result = await system_settings_service.get_system_settings(db, tenant_id)
|
result = await system_settings_service.get_system_settings(db, tenant_id)
|
||||||
if result is None:
|
if result is None:
|
||||||
return {}
|
return SystemSettingsResponse()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ class SystemSettingsUpsert(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class SystemSettingsResponse(BaseModel):
|
class SystemSettingsResponse(BaseModel):
|
||||||
id: str
|
id: str | None = None
|
||||||
company_name: str
|
company_name: str = ""
|
||||||
company_legal_form: str | None = None
|
company_legal_form: str | None = None
|
||||||
company_street: str
|
company_street: str = ""
|
||||||
company_city: str
|
company_city: str = ""
|
||||||
company_zip: str
|
company_zip: str = ""
|
||||||
company_country: str
|
company_country: str = ""
|
||||||
tax_number: str | None = None
|
tax_number: str | None = None
|
||||||
vat_id: str | None = None
|
vat_id: str | None = None
|
||||||
iban: str | None = None
|
iban: str | None = None
|
||||||
|
|||||||
Reference in New Issue
Block a user