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"]