Redesign1 #1

Merged
yaro merged 36 commits from Redesign1 into main 2025-09-22 14:12:39 -05:00
8 changed files with 91 additions and 5 deletions
Showing only changes of commit c43b17662d - Show all commits

View file

@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, DateTime, Boolean, func
from sqlalchemy import Column, Integer, DateTime, Boolean, String, JSON, func
from sqlalchemy.orm import declarative_mixin, declarative_base
Base = declarative_base()
@ -11,3 +11,16 @@ class CRUDMixin:
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
class Version(Base):
__tablename__ = "versions"
id = Column(Integer, primary_key=True)
model_name = Column(String, nullable=False)
object_id = Column(Integer, nullable=False)
change_type = Column(String, nullable=False)
data = Column(JSON, nullable=True)
timestamp = Column(DateTime, default=func.now())
actor = Column(String, nullable=True)
metadata = Column(JSON, nullable=True)

View file

@ -1,5 +1,6 @@
from typing import Type, TypeVar, Generic
from sqlalchemy.orm import Session
from crudkit.core.base import Version
from crudkit.core.spec import CRUDSpec
T = TypeVar("T")
@ -48,13 +49,15 @@ class CRUDService(Generic[T]):
query = query.offset(offset).limit(limit)
return query.all()
def create(self, data: dict) -> T:
def create(self, data: dict, actor=None) -> T:
obj = self.model(**data)
self.session.add(obj)
self.session.commit()
self._log_version("create", obj, actor)
return obj
def update(self, id: int, data: dict) -> T:
def update(self, id: int, data: dict, actor=None) -> T:
obj = self.get(id)
if not obj:
raise ValueError(f"{self.model.__name__} with ID {id} not found.")
@ -64,9 +67,11 @@ class CRUDService(Generic[T]):
if k in valid_fields:
setattr(obj, k, v)
self.session.commit()
self._log_version("update", obj, actor)
return obj
def delete(self, id: int, hard: bool = False):
def delete(self, id: int, hard: bool = False, actor = False):
obj = self.session.get(self.model, id)
if not obj:
return None
@ -77,4 +82,23 @@ class CRUDService(Generic[T]):
obj.is_deleted = True
self.session.commit()
self._log_version("delete", obj, actor)
return obj
def _log_version(self, change_type: str, obj: T, actor=None, metadata: dict = {}):
try:
data = obj.as_dict()
except Exception:
data = {"error": "Failed to serialize object."}
version = Version(
model_name=self.model.__name__,
object_id=obj.id,
change_type=change_type,
data=data,
actor=str(actor) if actor else None,
metadata=metadata
)
self.session.add(version)
self.session.commit()

View file

@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean
from sqlalchemy.orm import relationship
from crudkit.core.base import CRUDMixin, Base
@ -7,6 +7,7 @@ class Dbref(Base, CRUDMixin):
type = Column(String, nullable=False)
name = Column(String, nullable=False)
is_deleted = Column(Boolean, nullable=False, default=False)
owner_id = Column(Integer, ForeignKey("dbref.id"))
location_id = Column(Integer, ForeignKey("dbref.id"))
@ -21,3 +22,21 @@ class Dbref(Base, CRUDMixin):
def __str__(self):
return f"#{self.id} ({self.type}): {self.name}"
def is_type(self, *types: str) -> bool:
return self.type in types
@property
def is_room(self): return self.is_type("room")
@property
def is_thing(self): return self.is_type("thing")
@property
def is_exit(self): return self.is_type("exit")
@property
def is_player(self): return self.is_type("player")
@property
def is_program(self): return self.is_type("programI ho")

6
muck/models/exit.py Normal file
View file

@ -0,0 +1,6 @@
from muck.models.dbref import Dbref
class Exit(Dbref):
__mapper_args__ = {
"polymorphic_identity": "exit"
}

6
muck/models/player.py Normal file
View file

@ -0,0 +1,6 @@
from muck.models.dbref import Dbref
class Player(Dbref):
__mapper_args__ = {
"polymorphic_identity": "player"
}

6
muck/models/program.py Normal file
View file

@ -0,0 +1,6 @@
from muck.models.dbref import Dbref
class Program(Dbref):
__mapper_args__ = {
"polymorphic_identity": "program"
}

6
muck/models/room.py Normal file
View file

@ -0,0 +1,6 @@
from muck.models.dbref import Dbref
class Room(Dbref):
__mapper_args__ = {
"polymorphic_identity": "room"
}

6
muck/models/thing.py Normal file
View file

@ -0,0 +1,6 @@
from muck.models.dbref import Dbref
class Thing(Dbref):
__mapper_args__ = {
"polymorphic_identity": "thing"
}