diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9fb8a4..afbc93f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v6 with: + version: latest working-directory: poller frontend-lint: diff --git a/backend/alembic/env.py b/backend/alembic/env.py index d336d91..79095b4 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -9,8 +9,9 @@ from sqlalchemy import pool from sqlalchemy.engine import Connection from sqlalchemy.ext.asyncio import async_engine_from_config -# Import all models to register them with Base.metadata -from app.database import Base +# Import Base without triggering engine creation (app.database creates engines +# at module level, which would fail if DATABASE_URL points to a non-existent DB). +from app.models.base import Base import app.models.tenant # noqa: F401 import app.models.user # noqa: F401 import app.models.device # noqa: F401 diff --git a/backend/app/database.py b/backend/app/database.py index 2dc1bcd..518625a 100644 --- a/backend/app/database.py +++ b/backend/app/database.py @@ -10,15 +10,8 @@ from sqlalchemy.ext.asyncio import ( async_sessionmaker, create_async_engine, ) -from sqlalchemy.orm import DeclarativeBase - from app.config import settings - - -class Base(DeclarativeBase): - """Base class for all SQLAlchemy ORM models.""" - - pass +from app.models.base import Base # noqa: F401 — re-exported for backwards compat # Primary engine using postgres superuser (for migrations/admin) diff --git a/backend/app/models/alert.py b/backend/app/models/alert.py index b239e99..68c986f 100644 --- a/backend/app/models/alert.py +++ b/backend/app/models/alert.py @@ -16,7 +16,7 @@ from sqlalchemy import ( from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column -from app.database import Base +from app.models.base import Base class AlertRule(Base): diff --git a/backend/app/models/api_key.py b/backend/app/models/api_key.py index 1b873e8..77675da 100644 --- a/backend/app/models/api_key.py +++ b/backend/app/models/api_key.py @@ -8,7 +8,7 @@ from sqlalchemy import DateTime, ForeignKey, Text, func from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column -from app.database import Base +from app.models.base import Base class ApiKey(Base): diff --git a/backend/app/models/audit_log.py b/backend/app/models/audit_log.py index e58f1f2..90332dd 100644 --- a/backend/app/models/audit_log.py +++ b/backend/app/models/audit_log.py @@ -8,7 +8,7 @@ from sqlalchemy import DateTime, ForeignKey, String, Text, func from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column -from app.database import Base +from app.models.base import Base class AuditLog(Base): diff --git a/backend/app/models/base.py b/backend/app/models/base.py new file mode 100644 index 0000000..30d60bb --- /dev/null +++ b/backend/app/models/base.py @@ -0,0 +1,9 @@ +"""SQLAlchemy declarative base — importable without triggering engine creation.""" + +from sqlalchemy.orm import DeclarativeBase + + +class Base(DeclarativeBase): + """Base class for all SQLAlchemy ORM models.""" + + pass diff --git a/backend/app/models/certificate.py b/backend/app/models/certificate.py index 23fc77b..183e7e1 100644 --- a/backend/app/models/certificate.py +++ b/backend/app/models/certificate.py @@ -12,7 +12,7 @@ from sqlalchemy import DateTime, ForeignKey, LargeBinary, String, Text, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column -from app.database import Base +from app.models.base import Base class CertificateAuthority(Base): diff --git a/backend/app/models/config_backup.py b/backend/app/models/config_backup.py index e461462..4363abe 100644 --- a/backend/app/models/config_backup.py +++ b/backend/app/models/config_backup.py @@ -18,7 +18,7 @@ from sqlalchemy import ( from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column -from app.database import Base +from app.models.base import Base class ConfigBackupRun(Base): diff --git a/backend/app/models/config_template.py b/backend/app/models/config_template.py index 454a668..3d53e58 100644 --- a/backend/app/models/config_template.py +++ b/backend/app/models/config_template.py @@ -14,7 +14,7 @@ from sqlalchemy import ( from sqlalchemy.dialects.postgresql import JSON, UUID from sqlalchemy.orm import Mapped, mapped_column, relationship -from app.database import Base +from app.models.base import Base class ConfigTemplate(Base): diff --git a/backend/app/models/device.py b/backend/app/models/device.py index de3080d..b7ba62c 100644 --- a/backend/app/models/device.py +++ b/backend/app/models/device.py @@ -18,7 +18,7 @@ from sqlalchemy import ( from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship -from app.database import Base +from app.models.base import Base class DeviceStatus(str, Enum): diff --git a/backend/app/models/firmware.py b/backend/app/models/firmware.py index 01dbd74..5d3ff09 100644 --- a/backend/app/models/firmware.py +++ b/backend/app/models/firmware.py @@ -15,7 +15,7 @@ from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy import ForeignKey -from app.database import Base +from app.models.base import Base class FirmwareVersion(Base): diff --git a/backend/app/models/key_set.py b/backend/app/models/key_set.py index 37a2a06..97608b1 100644 --- a/backend/app/models/key_set.py +++ b/backend/app/models/key_set.py @@ -7,7 +7,7 @@ from sqlalchemy import DateTime, ForeignKey, Integer, LargeBinary, Text, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship -from app.database import Base +from app.models.base import Base class UserKeySet(Base): diff --git a/backend/app/models/maintenance_window.py b/backend/app/models/maintenance_window.py index 886a3cb..c768849 100644 --- a/backend/app/models/maintenance_window.py +++ b/backend/app/models/maintenance_window.py @@ -11,7 +11,7 @@ from sqlalchemy import Boolean, DateTime, ForeignKey, Text, VARCHAR, func from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column -from app.database import Base +from app.models.base import Base class MaintenanceWindow(Base): diff --git a/backend/app/models/tenant.py b/backend/app/models/tenant.py index 565c15f..d38a608 100644 --- a/backend/app/models/tenant.py +++ b/backend/app/models/tenant.py @@ -7,7 +7,7 @@ from sqlalchemy import DateTime, LargeBinary, Integer, String, Text, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship -from app.database import Base +from app.models.base import Base class Tenant(Base): diff --git a/backend/app/models/user.py b/backend/app/models/user.py index ba7043d..65c6473 100644 --- a/backend/app/models/user.py +++ b/backend/app/models/user.py @@ -8,7 +8,7 @@ from sqlalchemy import Boolean, DateTime, ForeignKey, LargeBinary, SmallInteger, from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship -from app.database import Base +from app.models.base import Base class UserRole(str, Enum): diff --git a/backend/app/models/vpn.py b/backend/app/models/vpn.py index c5dbe6b..1a99362 100644 --- a/backend/app/models/vpn.py +++ b/backend/app/models/vpn.py @@ -8,7 +8,7 @@ from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, LargeBinary, Stri from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column -from app.database import Base +from app.models.base import Base class VpnConfig(Base):