Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Generate Fluent DataModels with migrations and tests for FOSMVVM server-side persistence, including relationships and system-assigned fields, based on existi...
Generate Fluent DataModels with migrations and tests for FOSMVVM server-side persistence, including relationships and system-assigned fields, based on existi...
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
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.
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, @Parent, @Children, @Siblings property wrappers 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?"
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
In FOSMVVM, the Model is the center - the source of truth that reads and writes flow through. See FOSMVVMArchitecture.md | OpenClaw reference for full context.
βββββββββββββββββββββββββββββββββββββββ β 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 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
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
Invocation: /fosmvvm-fluent-datamodel-generator Prerequisites: 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.
This skill references conversation context to determine DataModel structure:
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)
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)
Based on data source: User-editable fields (from Fields protocol) System-assigned fields (createdBy, timestamps, status - DataModel only) Computed relationships (@Parent, @Children, @Siblings)
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
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
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
See reference.md for complete file templates with all patterns.
import FluentKit import FOSFoundation import FOSMVVM import FOSMVVMVapor import Foundation final class {Model}: DataModel, {Model}Fields, Hashable, @unchecked Sendable { static let schema = "{models}" // snake_case plural @ID(key: .id) var id: ModelIdType? // Fields from protocol @Field(key: "field_name") var fieldName: FieldType // Validation messages let {model}ValidationMessages: {Model}FieldsMessages // Timestamps @Timestamp(key: "created_at", on: .create) var createdAt: Date? @Timestamp(key: "updated_at", on: .update) var updatedAt: Date? // CRITICAL: Initialize validationMessages FIRST init() { self.{model}ValidationMessages = .init() } init(id: ModelIdType? = nil, fieldName: FieldType) { self.{model}ValidationMessages = .init() // FIRST! self.id = id self.fieldName = fieldName } }
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 // No computed property needed - @Parent satisfies the associated type directly } 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
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
For PostgreSQL-specific features (tsvector, LTREE, etc.), use SQLKit: import Fluent import SQLKit // Required for raw SQL // In prepare(): 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() Key points: 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)
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 // Satisfy the associated type var id: ModelIdType? var createdBy: TestUser // Concrete type, not existential } private struct TestUser: UserFields { var id: ModelIdType? = .init() var firstName: String = "Test" // ... other required fields with defaults }
ConceptConventionExampleModel classPascalCase singularUser, IdeaTable namesnake_case pluralusers, ideasField keyssnake_casecreated_at, user_idEnum casescamelCasesearchLanguage, inProgressEnum raw valuessnake_case"search_language", "in_progress"Protocol{Model}FieldsUserFields, IdeaFieldsMessages struct{Model}FieldsMessagesUserFieldsMessages
Swift TypeFluent TypeDatabaseString.stringVARCHAR/TEXTInt.intINTEGERBool.boolBOOLEANDate.datetimeTIMESTAMPTZUUID.uuidUUID[UUID].array(of: .uuid)UUID[]Custom Enum.stringVARCHAR (stored as raw value)JSONB.jsonJSONB
FOSMVVMArchitecture.md - Full FOSMVVM architecture fosmvvm-fields-generator - For form validation (Fields protocols) fosmvvm-viewmodel-generator - For ViewModels that project from DataModels reference.md - Complete file templates
VersionDateChanges1.02025-12-23Initial skill based on SystemConfig pattern1.12025-12-23Added relationship patterns (@Parent), initialization order, imports list1.22025-12-23Associated types for relationships (not existentials), raw SQL patterns, test struct patterns1.32025-12-24Factored out Fields layer to fields-generator skill2.02025-12-26Renamed to fosmvvm-fluent-datamodel-generator, added Scope Guard, generalized from Kairos-specific to FOSMVVM patterns, added architecture context2.12026-01-24Update to context-aware approach (remove file-parsing/Q&A). Skill references conversation context instead of asking questions or accepting file paths.
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.