Depicter

The Depicter is the primary faΓ§ade for authoring generation scripts in Gen-X. It provides a high-level Go API for assembling a complete application depiction β€” models, forms, views, relations, validations, routers, and file resources β€” without interacting directly with lower-level handlers, appliers, or configurators. Every method on the Depicter coordinates one or more of these internal layers so that your depiction script stays clean and readable.

Table of Contents

Public API

File / Directory Operations

These methods manage how static files and directories are copied from the project’s input directory into the generated output. Use them when your application needs custom assets, pre-written Go files, or entire directory trees that Gen-X should include verbatim.

Method Description
CopyExecutableFile(ctx, config, filePath) Copies a file from the project input directory to the output directory with executable permissions.
AddFile(ctx, config, path) Copies a file from the input directory to the output directory, creating parent directories as needed.
AddDir(ctx, config, path) Copies a directory from the input directory to the output directory.
CopiesOverwrittenFiles(ctx, config) Walks src/, sup/, and tests/ in the input directory and copies every Go file annotated with `//

πŸ’‘ Tip: Use CopiesOverwrittenFiles at the end of your depiction script to apply any handcrafted overrides to the generated code. Files annotated with // |@@| W are treated as intentional overwrites and will replace the generated versions.

Model Operations

Models are the foundational domain entities of your application. Each call to AddModel triggers the full model creation pipeline β€” services, structures, CRUD actors, and utility fields are all set up automatically by the underlying ModelCreateApplier.

Method Description
AddModel(ctx, config, name, crud) Creates a model with the given name and CRUD flag, then runs the model creation applier.
AddModelField(ctx, config, modelField, model) Adds a field to an existing model and runs the field creation applier, returning the reloaded field.
GetModel(ctx, name) Returns the named model within the current project.
AddModelRelation(ctx, model, name, viaField, to, reverseName, reverseKind) Creates an owned model relation via a foreign-key field and, if reverseName is non-empty, creates the reverse relation too.
AddOneToOneModelRelation(ctx, config, fromModel, toModelName) Creates a bidirectional one-to-one relation between fromModel and the named target model, adding the foreign-key field automatically.
AddOneToManyModelRelation(ctx, config, fromModel, toModelName) Creates a bidirectional one-to-many relation between fromModel and the named target model, adding the foreign-key field automatically.
AddManyChildToOneParentRelation(ctx, config, fromModel, toModelName) Alias for AddOneToManyModelRelation.
AddOneChildToOneParentRelation(ctx, config, fromModel, toModelName) Alias for AddOneToOneModelRelation.
SetModelFieldStringEnum(ctx, modelField, values) Configures a string model field as an enum with the given list of allowed values.

πŸ’‘ Tip: Pass crud: true to AddModel to generate the full Create / Read / Update / Delete actor set automatically. Pass crud: false for system or lookup models that do not need user-facing CRUD views.

Form Operations

Forms define the input structures used by CRUD actors. When you add a form field, the underlying FormFieldCreateApplier creates the corresponding structure field and wires it into the actor’s presenter automatically.

Method Description
AddFormField(ctx, form, formFieldName, fieldKind) Creates a form field of the given kind and attaches it to the form.
HasFormField(ctx, formName, formFieldName) Reports whether the named form contains a field with the given name.
AddFormEmbedField(ctx, parentForm, formFieldName, embedFormName, collection) Creates an embedded sub-form and attaches it to the parent form as an embed field; returns the new sub-form.
AddFormSteppedEmbedField(ctx, parentForm, formFieldName, embedFormName, index) Creates an embedded sub-form and attaches it to the parent form as a stepped embed field at the given index; returns the new sub-form.
AddFormStep(ctx, parentForm, name, index) Adds a step to the form by creating a stepped embed field with the given name and index; returns the new sub-form.
HideFormField(ctx, formName, formFieldName) Hides the named field by updating the associated form presenter’s configuration.
GetForm(ctx, name) Returns the named form within the current project.
ShallFindOneForm(ctx, name) Returns the named form within the current project, panicking if not found.
MakeEmbedForm(ctx, name, parentForm) Creates a new child form whose name is derived from the given name combined with the parent form’s name.
MakeSteppedForm(ctx, form) Converts the given form into a stepped form by adding a required step field.

πŸ“ Note: Form field names should match the corresponding model field names by convention. The generation pipeline uses naming patterns to link forms, presenters, and validators together β€” diverging from the convention requires explicit wiring.

Validation

Validation rules are attached to form fields or model fields and are enforced at runtime by the generated form validator services. Each method below registers a specific kind of validation constraint.

Method Description
AddFormValidation(ctx, form, fieldName, kind, data) Attaches a validator of the given kind and optional data to the named field of a form.
AddIntegerRequiredModelValidation(ctx, field) Attaches an integer-required validation rule to a model field.
AddDecimalRequiredModelValidation(ctx, field) Attaches a decimal-required validation rule to a model field.
AddStringRequiredModelValidation(ctx, field) Attaches a string-required validation rule to a model field.
AddRelationIdRequiredModelValidation(ctx, field) Attaches a relation-ID-required validation rule to a model field.

Section / View Operations

Sections are the building blocks of generated HTML views. Each actor owns a view, and each view is composed of ordered sections. The methods below let you add, reorder, hide, or extend sections within any view in the project.

Method Description
AddSectionToView(ctx, name, position, view) Creates a new section service and registers it under the given view at the specified position.
FindSectionByNameAndViewName(ctx, viewName, sectionName) Returns the named section service belonging to the named view.
InsertSectionIntoView(ctx, viewName, sectionName, position) Inserts (or creates) a section in the named view at the given position, shifting later sections up.
GetSection(ctx, viewName, sectionName) Returns the named section service within the named view.
HideSection(ctx, viewName, sectionName) Marks the named section as hidden in the view’s configuration data.
AddSteppedSection(ctx, mae, name, stepPosition, sectionPosition) Delegates to Configurator to add a stepped section to a Maestro view.
AddModelToActor(ctx, actorName, modelName) Associates a model with the named actor and updates its Maestro, related form, and perform step accordingly.
GetView(ctx, name) Returns the named view service within the current project.

Router Operations

Routers register the HTTP endpoints for your application. The Depicter supports both public and exchange routers, each resulting in a Gin router group wired into the project.

Method Description
AddPublicRouter(ctx) Creates a PublicRouter service (writable scaffold) and registers it with the project’s Gin router.
AddExchangeRouter(ctx) Creates an ExchangeRouter service (writable scaffold) and registers it with the project’s Gin router.
MakeFormSectionRemote(ctx, viewName) Marks the FormSection of the named view as a remote form.

πŸ’‘ Tip: Use AddPublicRouter for unauthenticated routes and AddExchangeRouter for API or AJAX endpoints that communicate with the frontend asynchronously.

MAE / Step Operations

Maestros (MAEs) are the controller layer of the generated application. These methods let you extend existing Maestros with new steps, adjust sort configurations, and modify step data without touching the generated code directly.

Method Description
AddStepToMae(ctx, name, data, position, maeName) Creates a new step service and attaches it to the named Maestro at the given position.
ReplaceDataStep(ctx, stepName, maeName, d) Replaces the data payload of an existing step within a Maestro.
AddDefaultSort(ctx, fetcherName, columnName, sort) Configures the default sort column and direction for the named fetcher service.
ShallFindOneStep(ctx, stepName, maeName) Returns the named step within a Maestro, panicking if not found.
ShallFindOneMaestro(ctx, maeName) Returns the named Maestro service within the current project, panicking if not found.
GetMae(ctx, name) Returns the named Maestro service within the current project.
SetServiceFunctionCode(ctx, serviceName, functionName, code) Overwrites the custom code body of a named function within a named service.

πŸ“ Note: Step positions are 1-based and sequential within a Maestro. Inserting a step at an existing position shifts later steps forward automatically.

These methods handle project-level concerns: navigation menus, CLI commands, port configuration, file resources, and dependency declarations. Call them after the core model and actor setup to finalize the project shape.

Method Description
AddIntoTopMenu(ctx, label, url) Appends a new labeled link item to the project’s top navigation menu.
AddCommand(ctx, name) Creates a command service and CLI command record for the given name.
AddCustomPorts(ctx, config, webPort, debugPort) Updates the project configuration with the given web and debug port values.
AddFileResource(ctx, filepath) Registers the given file path as a project resource.
AddDirResource(ctx, filepath) Registers the given directory path as a project resource.
AddUserServiceKind(ctx, kind) Registers a user-defined service kind for the project.
AddUserDependency(ctx, name, version) Registers a user-defined Go dependency with its version for the project.
CreateKinship(ctx, r1) Creates a model kinship record linking a model to a relation.
HideModelFieldInListSub(ctx, presenterName, modelName, fieldName) Hides the named model field from the sub-list column in the named presenter.
HideModelFieldInListMain(ctx, presenterName, modelName, fieldName) Hides the named model field from the main-list column in the named presenter.

Data Helpers

These helpers produce pre-marshalled data payloads used when configuring model fields with specific formats or constraints.

Method Description
TimeDataDMYFormat() Returns marshalled time field data configured for day-month-year format.
StringDataEnum(values) Returns marshalled string field data configured as an enum with the given allowed values.

πŸ’‘ Tip: Pass the result of StringDataEnum directly as the data argument when creating a string model field that should be restricted to a fixed set of values. The generated form will render an appropriate select input automatically.


Private Methods

This section lists all unexported (private) methods of the Depicter struct in src/srv/depicters/depicter.go. These methods are internal helpers used by the public API; they are not intended to be called directly from outside the package.

Project Setup

These private methods handle the creation of output directories and the management of service dependency relationships during generation.

Method Signature (params) Description
createProject projectId, name, folder, packageName, projectConfigData Creates a temporary output directory under /tmp and returns a ProjectConfig for the named project.
injectService ctx, serviceName, injectedName Records a service injection relationship between the named service and the named injected service.
injectImportLib ctx, serviceName, libName, external Creates an import record for libName and associates it with the named service.

Actor Creation (internal)

These private methods create the different kinds of actors that make up the user-facing layer of a generated application. Each actor kind generates a distinct Maestro structure with the appropriate views and routes. See The Blue-Lila CRUD Approach for an explanation of each actor kind.

Method Signature (params) Description
addSee ctx, what Creates a “See” actor for the given entity name. (Deprecated: use display instead.)
addDisplay ctx, what Creates a Display actor for the given entity name.
addDisplayWithModel ctx, what, modelName Creates a Display actor for the given entity name and associates it with the named model.
addOverview ctx, what Creates an Overview actor for the given entity name.
addOverviewWithModel ctx, what, modelName Creates an Overview actor for the given entity name and associates it with the named model.
addPerform ctx, what Creates a Perform actor for the given entity name.
addPerformWithModel ctx, what, modelName Creates a Perform actor for the given entity name and associates it with the named model.
addSeeAndPerform ctx, what Creates both Perform and See actors for the given entity name.
addSeeAndPerformWithModel ctx, what, modelName Creates both Perform and See actors for the given entity name, associating each with the named model.
addSeeAndAndInstruct ctx, what Creates both See and Instruct actors for the given entity name.

MAE / Maestro Internals

These methods manipulate the internal structure of Maestro services β€” adding fields to input/output contracts, locating Maestros by name, and managing custom function code.

Method Signature (params) Description
addServiceFunction ctx, name, service, data Creates a custom-code service function and attaches it to the given service.
serviceDataMaeFromMaeId ctx, maeId Fetches the service by ID and returns its unmarshalled Maestro data.
addIdIntoRequestMae ctx, maestroId Adds an Id primitive field to the Request sub-structure of the named Maestro’s input.
addStructureIntoRequestMae ctx, actor, name, toStructure, array Adds a named structure-typed field into the Response sub-structure of the actor’s Maestro output.
addFieldIntoRequestMae ctx, field, maeId Adds a structure field into the Request sub-structure of the named Maestro’s input.
addFieldIntoFormRequestMae ctx, field, maeId Adds a structure field into the Form sub-structure within a Maestro’s request input.
maeByName ctx, name Returns the Maestro service with the given name scoped to the current project.
addFieldIntoResponseMae ctx, field, maestroId Adds a field into the Response sub-structure of the named Maestro’s output.

Service Importing

These methods import existing Go files into the generation pipeline as free services, allowing handcrafted code to be included alongside generated code.

Method Signature (params) Description
importFolderAsFreeServices ctx, config, path Imports every file in the given input-directory folder as a free service.
importFileAsFreeService ctx, config, location Imports the file at the given location as a free service.

Section Management (internal)

These private methods perform the low-level mutations on view section lists: creating, removing, reordering, and inserting sections while keeping position values consistent.

Method Signature (params) Description
addSection ctx, viewName, sectionName, position Creates a new section service under the named view at the given position and registers it in the view’s data.
removeSection ctx, viewName, sectionName Removes the named section from the named view.
swapSectionsPositions ctx, viewName, sectionName1, sectionName2 Swaps the position values of two named sections within the named view.
addSectionToViewData ctx, view, section Appends a section entry to the view’s HTML data and persists the update.
removeSectionToViewData ctx, view, section Removes the section entry from the view’s HTML data and persists the update.
insertSectionIntoViewData ctx, parent, sectionName, position, d Inserts (or creates) a section at the given position in the view’s section list, shifting later entries up.
upPositionAfterN d, n Increments the position of every section whose position is at or after n, making room for an insert.

Form Internals

These private helpers look up form fields by name and create form fields on named forms, used internally by the public AddFormField methods.

Method Signature (params) Description
getFormFieldName ctx, formName, formFieldName Returns the form field with the given name within the named form.
addFormFieldViaFormName ctx, formName, formFieldName, fieldKind Creates a form field of the given kind on the named form.

File Walking

These methods implement the filepath.Walk callback used by CopiesOverwrittenFiles to identify and copy files marked for overwrite.

Method Signature (params) Description
visit ctx, path, info, err, config filepath.Walk callback that forwards non-directory .go files to checkFile.
checkFile ctx, filename, config Copies filename to the output directory when it contains the // \|@@\| W overwrite annotation.

Model Lookup

These panic-on-miss helpers are used throughout the Depicter to retrieve models and model fields by name, providing an early failure signal when a depiction script references a non-existent entity.

Method Signature (params) Description
shallFindOneModel ctx, name Returns the model with the given name in the current project, panicking if not found.
shallFindOneModelField ctx, fieldName, modelId Returns the named field of the given model, panicking if not found.

File Copy Helpers

These thin wrappers over the file system operations print a progress indicator for each file or directory copied during generation.

Method Signature (params) Description
mustCopy ctx, projectConfig, s Copies a single file from the input directory to the output directory and prints a progress dot.
mustCopyDir ctx, projectConfig, s Copies a directory from the input directory to the output directory and prints a progress dot.

The Blue-Lila CRUD Approach

Blue-Lila’s CRUD approach

Gen-X generates applications using a structured actor model that classifies every user-facing operation by its intent. Rather than generating generic CRUD screens, the Blue-Lila approach distinguishes between operations that display information and operations that perform changes. This distinction drives which Maestro structure, views, and routes are generated for each part of the application.

Actors (See, Display, Show, Perform)

An Actor represents a single user-facing operation in the generated application. Each actor is associated with a model (or a combination of models) and produces a Maestro, a view, and one or more routes. The actor’s kind determines what is generated.

The four actor kinds and their relationships are:

  • Display β€” A read-only view that presents information about one or more entities. A Display actor generates a single GET route and a view with zero or more informational sections. It can be associated with zero or more Perform actors that offer actions from within that view. Use Display for consumer-facing information pages where the user reads but does not submit data directly.

  • See β€” A read actor that always pairs with exactly one Perform actor. See generates a GET route that renders a form; Perform generates the corresponding POST route that processes the form submission. Together they form a read/write pair β€” See prepares and presents the form, Perform handles the submit. Use See + Perform for any operation that involves a user filling in and submitting data (create, edit, or any custom form action).

  • Show β€” A data-centric read actor used for standard CRUD detail views. Show is closely tied to a single model and generates the entity detail page. It sits within the CRUD actor set created automatically when AddModel is called with crud: true.

  • Perform β€” A write actor that handles form submission or any state-changing operation. Perform actors are always paired with either a See actor (for form-based flows) or attached to a Display actor (for inline actions). A standalone Perform actor without a See or Display parent is used for non-visual operations such as background processing or API endpoints.

The key rules of the actor model:

  • See always has exactly 1 Perform β€” the See/Perform pair is the canonical read/write pair for form-based interactions.
  • Display has 0–N Performs β€” a display page can expose zero actions (pure read) or multiple action buttons, each backed by its own Perform actor.
  • Show is data-centric (CRUD) β€” it belongs to the standard CRUD set and presents a single entity in detail.

πŸ“ Note: addSee is marked deprecated in the internal API. Prefer addDisplay for new actors. The Display kind is more flexible and covers all use cases previously handled by See.


Next Steps

  • Architecture Overview β€” Understand how the full generation pipeline works
  • Appliers β€” See what happens after each Depicter call triggers an applier