forked from sagnik/Velocity-OS
fix: Backend added along with missing pages
This commit is contained in:
6
core/backend/__init__.py
Normal file
6
core/backend/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
"""Compatibility package for Velocity-OS backend imports.
|
||||
|
||||
Velocity-OS keeps the simplified source layout (`api/api`, `auth/auth`, etc.)
|
||||
but most copied production modules still import `backend.*`. These path shims
|
||||
preserve the stable import contract without duplicating implementation files.
|
||||
"""
|
||||
3
core/backend/api/__init__.py
Normal file
3
core/backend/api/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
__path__ = [str(Path(__file__).resolve().parents[2] / "api" / "api")]
|
||||
3
core/backend/auth/__init__.py
Normal file
3
core/backend/auth/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
__path__ = [str(Path(__file__).resolve().parents[2] / "auth" / "auth")]
|
||||
1
core/backend/crm/__init__.py
Normal file
1
core/backend/crm/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""CRM compatibility package."""
|
||||
88
core/backend/crm/canonical_schema.py
Normal file
88
core/backend/crm/canonical_schema.py
Normal file
@@ -0,0 +1,88 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fastapi import HTTPException
|
||||
|
||||
from backend.auth.dependencies import default_tenant_id
|
||||
|
||||
_CANONICAL_CRM_SCHEMA_CACHE_KEY = "_canonical_crm_schema_ready"
|
||||
|
||||
|
||||
def _sql_text_literal(value: str) -> str:
|
||||
return "'" + value.replace("'", "''") + "'"
|
||||
|
||||
|
||||
async def ensure_canonical_crm_schema(app: Any) -> None:
|
||||
if getattr(app.state, _CANONICAL_CRM_SCHEMA_CACHE_KEY, False):
|
||||
return
|
||||
|
||||
pool = getattr(app.state, "db_pool", None)
|
||||
if pool is None:
|
||||
raise HTTPException(status_code=503, detail="Database unavailable.")
|
||||
|
||||
tenant_fallback = default_tenant_id()
|
||||
tenant_default_literal = _sql_text_literal(tenant_fallback)
|
||||
tenant_tables = (
|
||||
"crm_people",
|
||||
"crm_accounts",
|
||||
"crm_leads",
|
||||
"crm_opportunities",
|
||||
"crm_property_interests",
|
||||
"intel_interactions",
|
||||
"intel_reminders",
|
||||
"intel_qd_scores",
|
||||
"intel_qd_timeseries",
|
||||
"workflow_actions",
|
||||
"workflow_approvals",
|
||||
"workflow_import_batches",
|
||||
)
|
||||
|
||||
async with pool.acquire() as conn:
|
||||
for table_name in tenant_tables:
|
||||
await conn.execute(f"ALTER TABLE {table_name} ADD COLUMN IF NOT EXISTS tenant_id TEXT")
|
||||
await conn.execute(
|
||||
f"""
|
||||
UPDATE {table_name}
|
||||
SET tenant_id = $1
|
||||
WHERE tenant_id IS NULL OR tenant_id = ''
|
||||
""",
|
||||
tenant_fallback,
|
||||
)
|
||||
await conn.execute(
|
||||
f"ALTER TABLE {table_name} ALTER COLUMN tenant_id SET DEFAULT {tenant_default_literal}"
|
||||
)
|
||||
await conn.execute(f"ALTER TABLE {table_name} ALTER COLUMN tenant_id SET NOT NULL")
|
||||
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_crm_people_tenant_created ON crm_people (tenant_id, created_at DESC)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_crm_leads_tenant_status ON crm_leads (tenant_id, status, updated_at DESC)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_crm_opportunities_tenant_stage ON crm_opportunities (tenant_id, stage, updated_at DESC)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_crm_property_interests_tenant_person ON crm_property_interests (tenant_id, person_id, created_at DESC)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_intel_interactions_tenant_person ON intel_interactions (tenant_id, person_id, happened_at DESC)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_intel_reminders_tenant_status ON intel_reminders (tenant_id, status, due_at)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_intel_qd_scores_tenant_person ON intel_qd_scores (tenant_id, person_id, score_type)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_intel_qd_timeseries_tenant_person ON intel_qd_timeseries (tenant_id, person_id, timestamp DESC)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_workflow_actions_tenant_status ON workflow_actions (tenant_id, status, created_at DESC)"
|
||||
)
|
||||
await conn.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_workflow_import_batches_tenant_lifecycle ON workflow_import_batches (tenant_id, lifecycle, created_at DESC)"
|
||||
)
|
||||
|
||||
setattr(app.state, _CANONICAL_CRM_SCHEMA_CACHE_KEY, True)
|
||||
4
core/backend/db/__init__.py
Normal file
4
core/backend/db/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from pathlib import Path
|
||||
|
||||
_core_db_root = Path(__file__).resolve().parents[2] / "db"
|
||||
__path__ = [str(_core_db_root / "db"), str(_core_db_root)]
|
||||
3
core/backend/migrations/__init__.py
Normal file
3
core/backend/migrations/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
__path__ = [str(Path(__file__).resolve().parents[2] / "migrations" / "migrations")]
|
||||
1
core/backend/observability.py
Normal file
1
core/backend/observability.py
Normal file
@@ -0,0 +1 @@
|
||||
from observability import * # noqa: F401,F403
|
||||
3
core/backend/oracle/__init__.py
Normal file
3
core/backend/oracle/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
__path__ = [str(Path(__file__).resolve().parents[2] / "oracle" / "oracle")]
|
||||
3
core/backend/routers/__init__.py
Normal file
3
core/backend/routers/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
__path__ = [str(Path(__file__).resolve().parents[2] / "routers" / "routers")]
|
||||
3
core/backend/services/__init__.py
Normal file
3
core/backend/services/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
__path__ = [str(Path(__file__).resolve().parents[2] / "services" / "services")]
|
||||
Reference in New Issue
Block a user