DX Acceleration & Domain Scaffolding Guide
Craft Engine is built for maximum developer ergonomics and rapid feature delivery. Both AI Agents and Senior Developers can leverage Craft Engine's ORM Mixins, Query Scopes, and Facades to implement complex business domains in record time.
1. ORM Mixins (engine/orm/)
SluggableMixin
Automatically generates unique, URL-safe slugs for models from title, name, or a designated source column.
from craft.orm import Model, SluggableMixin
class BlogPost(Model, SluggableMixin):
__table__ = "blog_posts"
fillable = ["title", "slug", "content"]
slug_source_column = "title" # Default source column
slug_target_column = "slug" # Default target column
# Usage:
post = BlogPost({"title": "Getting Started with Craft Engine"})
post.generate_slug() # -> "getting-started-with-craft-engine"
post.save()
# Querying by slug:
post = BlogPost.find_by_slug("getting-started-with-craft-engine")
PublishableMixin
Provides draft/published status lifecycle management, timestamping (published_at), and built-in query scopes.
from craft.orm import Model, PublishableMixin
class BlogPost(Model, PublishableMixin):
__table__ = "blog_posts"
fillable = ["title", "status", "published_at"]
# Built-in Scopes:
published_posts = BlogPost.published().get()
draft_posts = BlogPost.drafts().get()
# Model instance lifecycle helpers:
post.publish() # Sets status = 'published', fills published_at timestamp, saves
post.unpublish() # Sets status = 'draft', saves
if post.is_published:
...
2. Speeding Up Business Logic
By combining SluggableMixin and PublishableMixin with Craft ORM relations, AI agents and developers write concise, declarative controllers:
from craft.http.controller import Controller
from craft.http.response import JsonResponse
from app.Models.BlogPost import BlogPost
class BlogController(Controller):
def index(self, request):
return JsonResponse([
p.to_dict() for p in BlogPost.published().order_by_desc("created_at").get()
])
def show(self, request, slug):
post = BlogPost.find_by_slug(slug)
if not post or not post.is_published:
return self.not_found("Article not found")
return JsonResponse(post.to_dict())
3. Best Practices for AI Agents & Senior Engineers
- Inherit Mixins First: Always inherit ORM mixins alongside
Model(class Post(Model, SluggableMixin, PublishableMixin)). - Use Query Scopes over Manual Filters: Prefer
BlogPost.published()over manualwhere("status", "published"). - Use Facades & Active Record: Leverage
Route,DB,Auth,Gate,Cachefor clean, expressive controllers.