From 388472742e8156c5916051a9813828d17ef0ec9f Mon Sep 17 00:00:00 2001 From: Yaro Kasear Date: Thu, 4 Sep 2025 09:47:36 -0500 Subject: [PATCH] Starting to recreate models. --- crudkit/core/base.py | 2 +- crudkit/core/service.py | 2 +- inventory/__init__.py | 23 +++++++++++++++++++++++ inventory/db.py | 28 ++++++++++++++++++++++++++++ inventory/models/__init__.py | 6 ++++++ inventory/models/area.py | 14 ++++++++++++-- inventory/models/brand.py | 18 ++++++++++++++++++ inventory/models/image.py | 20 ++++++++++++++++++++ inventory/models/inventory.py | 18 ++++++++++++++++++ inventory/wsgi.py | 2 ++ pyproject.toml | 3 +++ 11 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 inventory/__init__.py create mode 100644 inventory/db.py create mode 100644 inventory/models/brand.py create mode 100644 inventory/models/image.py create mode 100644 inventory/models/inventory.py create mode 100644 inventory/wsgi.py diff --git a/crudkit/core/base.py b/crudkit/core/base.py index e74fef0..c7de93e 100644 --- a/crudkit/core/base.py +++ b/crudkit/core/base.py @@ -23,4 +23,4 @@ class Version(Base): timestamp = Column(DateTime, default=func.now()) actor = Column(String, nullable=True) - metadata = Column(JSON, nullable=True) + meta = Column('metadata', JSON, nullable=True) diff --git a/crudkit/core/service.py b/crudkit/core/service.py index c235213..5126a9b 100644 --- a/crudkit/core/service.py +++ b/crudkit/core/service.py @@ -98,7 +98,7 @@ class CRUDService(Generic[T]): change_type=change_type, data=data, actor=str(actor) if actor else None, - metadata=metadata + meta=metadata ) self.session.add(version) self.session.commit() diff --git a/inventory/__init__.py b/inventory/__init__.py new file mode 100644 index 0000000..cfb1f17 --- /dev/null +++ b/inventory/__init__.py @@ -0,0 +1,23 @@ +from __future__ import annotations +import os + +from flask import Flask + +from .db import init_db, create_all_tables + +def create_app() -> Flask: + app = Flask(__name__) + + app.config["DATABASE_URL"] = os.getenv("DATABASE_URL", "sqlite:///inventory.db") + + init_db(app.config["DATABASE_URL"]) + + from . import models as _models + + create_all_tables() + + @app.get("/") + def index(): + return {"status": "ok"} + + return app \ No newline at end of file diff --git a/inventory/db.py b/inventory/db.py new file mode 100644 index 0000000..8519233 --- /dev/null +++ b/inventory/db.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, scoped_session + +from crudkit.core.base import Base + +_engine = None +SessionLocal = None + +def init_db(database_url: str) -> None: + global _engine, SessionLocal + connect_args = {} + if database_url.startswith("sqlite:///"): + connect_args["check_same_thread"] = False + + _engine = create_engine(database_url, future=True, echo=False, connect_args=connect_args) + SessionLocal = scoped_session(sessionmaker(bind=_engine, autoflush=False, autocommit=False, future=True)) + +def get_session(): + if SessionLocal is None: + raise RuntimeError("DB not initialized. Call init_db() first.") + return SessionLocal() + +def create_all_tables() -> None: + if _engine is None: + raise RuntimeError("DB engine not initialized.") + Base.metadata.create_all(bind=_engine) diff --git a/inventory/models/__init__.py b/inventory/models/__init__.py index e69de29..f522e87 100644 --- a/inventory/models/__init__.py +++ b/inventory/models/__init__.py @@ -0,0 +1,6 @@ +from typing import Optional + +from sqlalchemy import Integer, Unicode +from sqlalchemy.orm import Mapped, mapped_column + +from crudkit.core.base import Base, CRUDMixin diff --git a/inventory/models/area.py b/inventory/models/area.py index a6e8ddd..a0c3e28 100644 --- a/inventory/models/area.py +++ b/inventory/models/area.py @@ -1,8 +1,18 @@ -from sqlalchemy import Column, Unicode +from typing import List, Optional + +from sqlalchemy import Boolean, Unicode +from sqlalchemy.orm import Mapped, mapped_column, relationship from crudkit.core.base import Base, CRUDMixin class Area(Base, CRUDMixin): __tablename__ = "area" - name = Column(Unicode(255), nullable=True) \ No newline at end of file + name: Mapped[Optional[str]] = mapped_column(Unicode(255), nullable=True) + + rooms: Mapped[List['Room']] = relationship('Room', back_populates='area') + + is_deleted: Mapped[Boolean] = mapped_column(Boolean, nullable=False, default=False) + + def __repr__(self): + return f"" \ No newline at end of file diff --git a/inventory/models/brand.py b/inventory/models/brand.py new file mode 100644 index 0000000..6d2528d --- /dev/null +++ b/inventory/models/brand.py @@ -0,0 +1,18 @@ +from typing import List + +from sqlalchemy import Boolean, Unicode +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from crudkit.core.base import Base, CRUDMixin + +class Brand(Base, CRUDMixin): + __tablename__ = "brand" + + name: Mapped[str] = mapped_column(Unicode(255), nullable=False) + + inventory: Mapped[List['Inventory']] = relationship('Inventory', back_populates='brand') + + is_deleted: Mapped[Boolean] = mapped_column(Boolean, nullable=False, default=False) + + def __repr__(self) -> str: + return f""4 diff --git a/inventory/models/image.py b/inventory/models/image.py new file mode 100644 index 0000000..2c636de --- /dev/null +++ b/inventory/models/image.py @@ -0,0 +1,20 @@ +from typing import List, Optional + +from sqlalchemy import DateTime, Unicode, func +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from crudkit.core.base import Base, CRUDMixin + +class Image(Base, CRUDMixin): + __tablename__ = "images" + + filename: Mapped[str] = mapped_column(Unicode(512)) + caption: Mapped[str] = mapped_column(Unicode(255), default="") + timestamp: Mapped[DateTime] = mapped_column(DateTime, default=func.now(), server_default=func.now()) + + inventory: Mapped[Optional['Inventory']] = relationship('Inventory', back_populates='images') + user: Mapped[Optional['User']] = relationship('User', back_populates='image') + worklogs: Mapped[List['WorkLog']] = relationship('WorkLog', secondary=worklog_images, back_populates='images') + + def __repr__(self): + return f"" diff --git a/inventory/models/inventory.py b/inventory/models/inventory.py new file mode 100644 index 0000000..885fb60 --- /dev/null +++ b/inventory/models/inventory.py @@ -0,0 +1,18 @@ +from typing import Optional + +from sqlalchemy import DateTime, ForeignKey, Index, Integer, Unicode +from sqlalchemy.orm import Mapped, mapped_column + +from crudkit.core.base import Base, CRUDMixin + +class Inventory(Base, CRUDMixin): + __tablename__ = "inventory" + + name: Mapped[Optional[str]] = mapped_column(Unicode(255)) + serial: Mapped[Optional[str]] = mapped_column(Unicode(255)) + + timestamp: Mapped[DateTime] = mapped_column(DateTime) + condition: Mapped[str] = mapped_column(Unicode(255)) + + device_type_id: Mapped[Optional[int]] = mapped_column('type_id', Integer, ForeignKey("item.id"), nullable=True, index=True) + device_type: Mapped[Optional['DeviceType']] diff --git a/inventory/wsgi.py b/inventory/wsgi.py new file mode 100644 index 0000000..112e75e --- /dev/null +++ b/inventory/wsgi.py @@ -0,0 +1,2 @@ +from . import create_app +app = create_app \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 5b208d0..e15d734 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,5 +20,8 @@ dependencies = [ requires = ["setuptools"] build-backend = "setuptools.build_meta" +[tool.pip.dependencies] +crudkit = { path = "../crudkit", editable = true } + [tool.setuptools] packages = ["inventory"]