Add crudkit!

This commit is contained in:
Yaro Kasear 2025-08-27 10:27:41 -05:00
parent 30ec29d497
commit 559fd56f33
28 changed files with 881 additions and 23 deletions

View file

@ -1,6 +1,7 @@
from flask import Flask, current_app
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.engine.url import make_url
from sqlalchemy.orm import sessionmaker
import logging
import os
@ -23,9 +24,8 @@ def is_in_memory_sqlite():
def create_app():
from config import Config
app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY', 'dev-secret-key-unsafe') # You know what to do for prod
app.secret_key = os.getenv('SECRET_KEY', 'dev-secret-key-unsafe')
app.config.from_object(Config)
db.init_app(app)
with app.app_context():
@ -33,16 +33,25 @@ def create_app():
if is_in_memory_sqlite():
db.create_all()
from .routes import main
from .routes.images import image_bp
from .ui.blueprint import bp as ui_bp
app.register_blueprint(main)
app.register_blueprint(image_bp)
app.register_blueprint(ui_bp)
# ✅ db.engine is only safe to touch inside an app context
SessionLocal = sessionmaker(bind=db.engine, expire_on_commit=False)
from .routes.helpers import generate_breadcrumbs
@app.context_processor
def inject_breadcrumbs():
return {'breadcrumbs': generate_breadcrumbs()}
from .models import registry
from .routes import main
from .routes.images import image_bp
from .ui.blueprint import bp as ui_bp
from crudkit.blueprint import make_blueprint as make_json_bp
from crudkit.html import make_fragments_blueprint as make_html_bp
app.register_blueprint(main)
app.register_blueprint(image_bp)
app.register_blueprint(ui_bp)
app.register_blueprint(make_json_bp(SessionLocal, registry), url_prefix="/api")
app.register_blueprint(make_html_bp(SessionLocal, registry), url_prefix="/ui")
from .routes.helpers import generate_breadcrumbs
@app.context_processor
def inject_breadcrumbs():
return {'breadcrumbs': generate_breadcrumbs()}
return app

View file

@ -44,11 +44,25 @@ Room.ui_eagerload = (
selectinload(Room.users)
)
registry = {
"area": Area,
"brand": Brand,
"image": Image,
"inventory": Inventory,
"item": Item,
"room_function": RoomFunction,
"room": Room,
"user": User,
"work_log": WorkLog,
"work_note": WorkNote
}
__all__ = [
"db",
"Image", "ImageAttachable",
"RoomFunction", "Room",
"Area", "Brand", "Item", "Inventory",
"WorkLog", "WorkNote", "worklog_images",
"User",
"User", "registry"
]

View file

@ -2,12 +2,13 @@ from typing import List, Optional, TYPE_CHECKING
if TYPE_CHECKING:
from .rooms import Room
from crudkit import CrudMixin
from sqlalchemy import Identity, Integer, Unicode
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
class Area(db.Model):
class Area(db.Model, CrudMixin):
__tablename__ = 'area'
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)

View file

@ -2,12 +2,13 @@ from typing import List, TYPE_CHECKING
if TYPE_CHECKING:
from .inventory import Inventory
from crudkit import CrudMixin
from sqlalchemy import Identity, Integer, Unicode
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
class Brand(db.Model):
class Brand(db.Model, CrudMixin):
__tablename__ = 'brand'
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)

View file

@ -12,7 +12,9 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
from .image_links import worklog_images
class Image(db.Model):
from crudkit import CrudMixin
class Image(db.Model, CrudMixin):
__tablename__ = 'images'
id: Mapped[int] = mapped_column(Integer, primary_key=True)

View file

@ -9,6 +9,7 @@ if TYPE_CHECKING:
from .image import Image
from .users import User
from crudkit import CrudMixin
from sqlalchemy import Boolean, ForeignKey, Identity, Index, Integer, Unicode, DateTime, text
from sqlalchemy.orm import Mapped, mapped_column, relationship
import datetime
@ -18,7 +19,7 @@ from .brands import Brand
from .image import ImageAttachable
from .users import User
class Inventory(db.Model, ImageAttachable):
class Inventory(db.Model, ImageAttachable, CrudMixin):
__tablename__ = 'inventory'
__table_args__ = (
Index('Inventory$Barcode', 'barcode'),

View file

@ -2,12 +2,13 @@ from typing import List, Optional, TYPE_CHECKING
if TYPE_CHECKING:
from .inventory import Inventory
from crudkit import CrudMixin
from sqlalchemy import Identity, Integer, Unicode
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
class Item(db.Model):
class Item(db.Model, CrudMixin):
__tablename__ = 'item'
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)

View file

@ -2,12 +2,13 @@ from typing import List, Optional, TYPE_CHECKING
if TYPE_CHECKING:
from .rooms import Room
from crudkit import CrudMixin
from sqlalchemy import Identity, Integer, Unicode
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
class RoomFunction(db.Model):
class RoomFunction(db.Model, CrudMixin):
__tablename__ = 'room_function'
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)

View file

@ -5,12 +5,13 @@ if TYPE_CHECKING:
from .inventory import Inventory
from .users import User
from crudkit import CrudMixin
from sqlalchemy import ForeignKey, Identity, Integer, Unicode
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
class Room(db.Model):
class Room(db.Model, CrudMixin):
__tablename__ = 'rooms'
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)

View file

@ -5,13 +5,14 @@ if TYPE_CHECKING:
from .work_log import WorkLog
from .image import Image
from crudkit import CrudMixin
from sqlalchemy import Boolean, ForeignKey, Identity, Integer, Unicode, text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
from .image import ImageAttachable
class User(db.Model, ImageAttachable):
class User(db.Model, ImageAttachable, CrudMixin):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)

View file

@ -5,6 +5,7 @@ if TYPE_CHECKING:
from .users import User
from .work_note import WorkNote
from crudkit import CrudMixin
from sqlalchemy import Boolean, Identity, Integer, ForeignKey, Unicode, DateTime, text
from sqlalchemy.orm import Mapped, mapped_column, relationship
import datetime
@ -14,7 +15,7 @@ from .image import ImageAttachable
from .image_links import worklog_images
from .work_note import WorkNote
class WorkLog(db.Model, ImageAttachable):
class WorkLog(db.Model, ImageAttachable, CrudMixin):
__tablename__ = 'work_log'
id: Mapped[int] = mapped_column(Integer, Identity(start=1, increment=1), primary_key=True)

View file

@ -1,11 +1,12 @@
import datetime
from crudkit import CrudMixin
from sqlalchemy import ForeignKey, DateTime, UnicodeText, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from . import db
class WorkNote(db.Model):
class WorkNote(db.Model, CrudMixin):
__tablename__ = 'work_note'
id: Mapped[int] = mapped_column(primary_key=True)