Skip to main content 홈 크리에이터 johnalbertini14-glitch openclaw-skills fosmvvm-fluent-datamodel-generator
fosmvvm-fluent-datamodel-generator Generate Fluent DataModels for FOSMVVM server-side persistence. Scaffolds models, migrations, and tests for database-backed entities.
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/johnalbertini14-glitch/openclaw-skills --skill fosmvvm-fluent-datamodel-generator명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... name fosmvvm-fluent-datamodel-generator description Generate Fluent DataModels for FOSMVVM server-side persistence. Scaffolds models, migrations, and tests for database-backed entities. homepage https://github.com/foscomputerservices/FOSUtilities metadata {"clawdbot":{"emoji":"🗄️","os":["darwin","linux"]}}
FOSMVVM Fluent DataModel Generator
Generate Fluent DataModels for server-side persistence following FOSMVVM architecture.
Dependency: This skill uses fosmvvm-fields-generator for the Fields layer (protocol, messages, YAML). Run that skill first for form-backed models.
Scope Guard
This skill is specifically for Fluent persistence layer (typically in Vapor server apps).
STOP and ask the user if:
The project doesn't use Fluent
The target is iOS-only with CoreData, SwiftData, or Realm
The user mentions a non-Fluent ORM or persistence layer
You're unsure whether Fluent is the persistence layer
Check for Fluent indicators:
Package.swift imports fluent, fluent-postgres-driver, fluent-sqlite-driver, etc.
Existing models use @ID, @Field, , , property wrappers
@Parent
@Children
@Siblings
A Migrations/ directory exists with Fluent migration patterns
Imports include FluentKit or Fluent If Fluent isn't present, inform the user: "This skill generates Fluent DataModels for server-side persistence. Your project doesn't appear to use Fluent. How would you like to proceed?"
When to Use This Skill
User asks to create a new model/entity/table
User wants to add a database-backed type (Users, Ideas, Documents, etc.)
User mentions needing CRUD operations for a new concept
Creating the persistence layer for a new entity
Architecture Context In FOSMVVM, the Model is the center - the source of truth that reads and writes flow through.
DataModel in the Architecture ┌─────────────────────────────────────┐
│ Fluent DataModel │
│ (implements Model + Fields) │
│ │
│ • All fields (system + user) │
│ • Relationships (@Parent, etc.) │
│ • Timestamps, audit fields │
│ • Persistence logic │
└──────────────┬──────────────────────┘
│
┌────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ ViewModelFactory│ │ CreateRequest │ │ UpdateRequest │
│ (projector) │ │ RequestBody │ │ RequestBody │
│ │ │ │ │ │
│ → ViewModel │ │ → persists to │ │ → updates │
│ (projection) │ │ DataModel │ │ DataModel │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Fields vs DataModels Fields protocol = Form input (user-editable subset)
What users type into forms
Validation, labels, placeholders
NO relationships, NO system-assigned fields
DataModel = Complete entity (Fluent implementation)
All fields including system-assigned (createdBy, timestamps)
All relationships (@Parent, @Siblings, @Children)
Fluent property wrappers, migrations, seeds
Not all entities need Fields:
Session: system auth, no user form → DataModel-only
Audit records: system-generated → DataModel-only
Junction tables: pure storage → DataModel-only
File Structure Each form-backed model requires files across multiple targets:
── fosmvvm-fields-generator ──────────────────────────────────
{ViewModelsTarget}/ (shared protocol layer)
FieldModels/
{Model}Fields.swift ← Protocol + Enum + Validation
{Model}FieldsMessages.swift ← Localization message struct
{ResourcesPath}/ (localization resources)
FieldModels/
{Model}FieldsMessages.yml ← YAML localization strings
── fosmvvm-fluent-datamodel-generator (this skill) ───────────
{WebServerTarget}/ (server implementation)
DataModels/
{Model}.swift ← Fluent model (implements protocol)
Migrations/
{Model}+Schema.swift ← Table creation migration
{Model}+Seed.swift ← Seed data migration
Tests/
{ViewModelsTarget}Tests/
FieldModels/
{Model}FieldsTests.swift ← Unit tests
database.swift ← Register migrations
How to Use This Skill Invocation:
/fosmvvm-fluent-datamodel-generator
Model structure understood from conversation context
Fields protocol exists (if form-backed model) via fosmvvm-fields-generator
Relationships and system-assigned fields identified
Fluent confirmed as the persistence layer
Workflow integration:
This skill is used for server-side persistence with Fluent. For form-backed models, run fosmvvm-fields-generator first to create the Fields protocol. The skill references conversation context automatically—no file paths or Q&A needed.
Pattern Implementation This skill references conversation context to determine DataModel structure:
Model Type Detection From conversation context, the skill identifies:
Entity purpose (user data, system records, audit logs, junction table)
User input involvement (form-backed vs system-generated)
Fields protocol requirement (if user edits this data)
Relationship Analysis From requirements already in context:
One-to-many relationships (@Parent in DataModel, not in Fields)
Many-to-many relationships (Junction table + @Siblings, NOT UUID arrays)
Relationship naming (self-documenting names, not vague references)
Field Classification
User-editable fields (from Fields protocol)
System-assigned fields (createdBy, timestamps, status - DataModel only)
Computed relationships (@Parent, @Children, @Siblings)
File Generation Order If form-backed model (Fields protocol exists):
Fields layer already created via fosmvvm-fields-generator
DataModel implementation referencing Fields
Schema migration
Seed data migration
Tests
Migration registration
If system-only model (no Fields):
DataModel struct
Schema migration
Seed data migration (if needed)
Tests
Migration registration
Design Validation Before generating, the skill validates:
Form requirement - System-generated entities skip Fields
Relationship patterns - Junction tables for many-to-many, @Parent for foreign keys
Naming clarity - Relationships have self-documenting names
Field separation - User fields in protocol, system fields in DataModel only
Context Sources Skill references information from:
Prior conversation : Model requirements, relationships discussed
Fields protocol : If Claude has read Fields protocol into context or just created it
Database schema : From codebase analysis of existing models
Migration patterns : From existing migrations in project
File Templates See reference.md for complete file templates with all patterns.
Key Patterns
Fluent DataModel import FluentKit
import FOSFoundation
import FOSMVVM
import FOSMVVMVapor
import Foundation
final class {Model }: DataModel , {Model }Fields , Hashable , @unchecked Sendable {
static let schema = "{models}"
@ID (key: .id) var id: ModelIdType ?
@Field (key: "field_name" ) var fieldName: FieldType
let {model}ValidationMessages : {Model }FieldsMessages
@Timestamp (key: "created_at" , on: .create) var createdAt: Date ?
@Timestamp (key: "updated_at" , on: .update) var updatedAt: Date ?
init () {
self .{model}ValidationMessages = .init ()
}
init (id : ModelIdType ? = nil , fieldName : FieldType ) {
self .{model}ValidationMessages = .init ()
self .id = id
self .fieldName = fieldName
}
}
Relationships (Associated Types Pattern) PRINCIPLE: Existential types (any Protocol) are a code smell. Always ask "Is there any other way?" before using them.
For required relationships, use associated types in the protocol:
public protocol IdeaFields : ValidatableModel , Codable , Sendable {
associatedtype User : UserFields
var createdBy: User { get set }
}
In the Fluent model, @Parent directly satisfies the protocol:
final class Idea : DataModel , IdeaFields , Hashable , @unchecked Sendable {
@Parent (key: "created_by" ) var createdBy: User
}
In schema: .field("created_by", .uuid, .required, .references(User.schema, "id", onDelete: .cascade))
When to use each pattern:
Associated type (associatedtype User: UserFields): Required relationships
Optional associated type : Not supported - use ModelIdType? for optional FKs
Plain ModelIdType : Optional FKs, external system references
Migrations
Schema migration named: "{Model.schema}-initial"
Seed migration named: "{Model.schema}-seed"
Seed is environment-aware (debug, test, release)
Seed is idempotent: guard count() == 0
Raw SQL in Migrations (PostgreSQL Features) For PostgreSQL-specific features (tsvector, LTREE, etc.), use SQLKit:
import Fluent
import SQLKit
guard let sql = database as? any SQLDatabase else { return }
let schema = Model .schema
try await sql.raw(SQLQueryString ("ALTER TABLE \(unsafeRaw: schema) ADD COLUMN search_vector tsvector" )).run()
Import SQLKit (not just Fluent)
Cast database: database as? any SQLDatabase
Use SQLQueryString with \(unsafeRaw:) for identifiers
These columns are database-only (not in protocol or Fluent model)
Tests
Use @Suite annotation with descriptive name
Conform to LocalizableTestCase
Test all form fields
Test validation with @Test(arguments:)
Create private test struct implementing the Fields protocol
Test structs with associated types:
private struct TestIdea : IdeaFields {
typealias User = TestUser
var id: ModelIdType ?
var createdBy: TestUser
}
private struct TestUser : UserFields {
var id: ModelIdType ? = .init ()
var firstName: String = "Test"
}
Naming Conventions Concept Convention Example Model class PascalCase singular User, IdeaTable name snake_case plural users, ideasField keys snake_case created_at, user_idEnum cases camelCase searchLanguage, inProgressEnum raw values snake_case "search_language", "in_progress"Protocol {Model}FieldsUserFields, IdeaFieldsMessages struct {Model}FieldsMessagesUserFieldsMessages
Common Field Types Swift Type Fluent Type Database String.stringVARCHAR/TEXTInt.intINTEGERBool.boolBOOLEANDate.datetimeTIMESTAMPTZUUID.uuidUUID[UUID].array(of: .uuid)UUID[]Custom Enum .stringVARCHAR (stored as raw value)JSONB.jsonJSONB
See Also
Version History Version Date Changes 1.0 2025-12-23 Initial skill based on SystemConfig pattern 1.1 2025-12-23 Added relationship patterns (@Parent), initialization order, imports list 1.2 2025-12-23 Associated types for relationships (not existentials), raw SQL patterns, test struct patterns 1.3 2025-12-24 Factored out Fields layer to fields-generator skill 2.0 2025-12-26 Renamed to fosmvvm-fluent-datamodel-generator, added Scope Guard, generalized from Kairos-specific to FOSMVVM patterns, added architecture context 2.1 2026-01-24 Update to context-aware approach (remove file-parsing/Q&A). Skill references conversation context instead of asking questions or accepting file paths.