Initial commit - Migrated to Dev environment
This commit is contained in:
0
backend/app/db/__init__.py
Executable file
0
backend/app/db/__init__.py
Executable file
BIN
backend/app/db/__pycache__/__init__.cpython-312.pyc
Executable file
BIN
backend/app/db/__pycache__/__init__.cpython-312.pyc
Executable file
Binary file not shown.
BIN
backend/app/db/__pycache__/base.cpython-312.pyc
Executable file
BIN
backend/app/db/__pycache__/base.cpython-312.pyc
Executable file
Binary file not shown.
BIN
backend/app/db/__pycache__/session.cpython-312.pyc
Executable file
BIN
backend/app/db/__pycache__/session.cpython-312.pyc
Executable file
Binary file not shown.
10
backend/app/db/base.py
Executable file
10
backend/app/db/base.py
Executable file
@@ -0,0 +1,10 @@
|
||||
from sqlalchemy.ext.asyncio import AsyncAttrs
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
|
||||
|
||||
class Base(AsyncAttrs, DeclarativeBase):
|
||||
"""
|
||||
Base class for all SQLAlchemy models.
|
||||
Includes AsyncAttrs to support async attribute access (lazy loading).
|
||||
"""
|
||||
pass
|
||||
38
backend/app/db/context.py
Executable file
38
backend/app/db/context.py
Executable file
@@ -0,0 +1,38 @@
|
||||
from typing import Generator, Optional, Dict, Any
|
||||
from fastapi import Request
|
||||
from app.db.session import get_conn
|
||||
|
||||
def _set_config(cur, key: str, value: str) -> None:
|
||||
cur.execute("SELECT set_config(%s, %s, false);", (key, value))
|
||||
|
||||
def db_tx(request: Request) -> Generator[Dict[str, Any], None, None]:
|
||||
"""
|
||||
Egységes DB tranzakció + session context:
|
||||
BEGIN
|
||||
set_config(app.tenant_org_id, app.account_id, app.is_platform_admin)
|
||||
COMMIT/ROLLBACK
|
||||
"""
|
||||
conn = get_conn()
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("BEGIN;")
|
||||
|
||||
claims: Optional[dict] = getattr(request.state, "claims", None)
|
||||
if claims:
|
||||
org_id = claims.get("org_id") or ""
|
||||
account_id = claims.get("sub") or ""
|
||||
is_platform_admin = claims.get("is_platform_admin", False)
|
||||
|
||||
# Fontos: set_config stringeket vár
|
||||
_set_config(cur, "app.tenant_org_id", str(org_id))
|
||||
_set_config(cur, "app.account_id", str(account_id))
|
||||
_set_config(cur, "app.is_platform_admin", "true" if is_platform_admin else "false")
|
||||
|
||||
yield {"conn": conn, "cur": cur}
|
||||
|
||||
conn.commit()
|
||||
except Exception:
|
||||
conn.rollback()
|
||||
raise
|
||||
finally:
|
||||
conn.close()
|
||||
31
backend/app/db/middleware.py
Executable file
31
backend/app/db/middleware.py
Executable file
@@ -0,0 +1,31 @@
|
||||
from fastapi import Request
|
||||
from app.db.session import SessionLocal
|
||||
from app.services.config_service import config
|
||||
from sqlalchemy import text
|
||||
import json
|
||||
|
||||
async def audit_log_middleware(request: Request, call_next):
|
||||
logging_enabled = await config.get_setting('audit_log_enabled', default=True)
|
||||
|
||||
response = await call_next(request)
|
||||
|
||||
if logging_enabled and request.method != 'GET': # GET-et általában nem naplózunk a zaj miatt, de állítható
|
||||
try:
|
||||
user_id = getattr(request.state, 'user_id', None) # Ha már be van lépve
|
||||
|
||||
async with SessionLocal() as db:
|
||||
await db.execute(text("""
|
||||
INSERT INTO data.audit_logs (user_id, action, endpoint, method, ip_address)
|
||||
VALUES (:u, :a, :e, :m, :ip)
|
||||
"""), {
|
||||
'u': user_id,
|
||||
'a': f'API_CALL_{request.method}',
|
||||
'e': str(request.url.path),
|
||||
'm': request.method,
|
||||
'ip': request.client.host
|
||||
})
|
||||
await db.commit()
|
||||
except Exception:
|
||||
pass # A naplózás hibája nem akaszthatja meg a kiszolgálást
|
||||
|
||||
return response
|
||||
31
backend/app/db/session.py
Executable file
31
backend/app/db/session.py
Executable file
@@ -0,0 +1,31 @@
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
|
||||
from app.core.config import settings
|
||||
from typing import AsyncGenerator
|
||||
|
||||
engine = create_async_engine(
|
||||
settings.DATABASE_URL, # A te eredeti kulcsod
|
||||
echo=getattr(settings, "DEBUG", False),
|
||||
future=True,
|
||||
pool_size=20,
|
||||
max_overflow=10
|
||||
)
|
||||
|
||||
AsyncSessionLocal = async_sessionmaker(
|
||||
engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
autoflush=False
|
||||
)
|
||||
# Ez a sor kell, mert a main.py és a többiek ezen a néven keresik
|
||||
SessionLocal = AsyncSessionLocal
|
||||
|
||||
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
||||
async with AsyncSessionLocal() as session:
|
||||
try:
|
||||
yield session
|
||||
await session.commit()
|
||||
except Exception:
|
||||
await session.rollback()
|
||||
raise
|
||||
finally:
|
||||
await session.close()
|
||||
Reference in New Issue
Block a user