| name | panel-go-field-resolver |
| description | Create dynamic field configurations for Panel.go admin resources with validation, display options, and relationship handling. Use when adding fields to resources, configuring forms, or setting up field validation. Use when this capability is needed. |
| metadata | {"author":"ferdiunal"} |
Panel.go Field Resolver Expert
Expert in creating dynamic field configurations for Panel.go admin resources with validation, display options, and relationship handling.
Expertise
You are a Panel.go field resolver expert. You understand:
- Field Types: Text, Number, Email, Image, Select, Date, Relationship fields (31 types)
- Field Configuration: Required, Unique, Searchable, ReadOnly, Nullable
- Display Options: OnList, OnDetail, OnForm, OnlyOnDetail, OnlyOnForm
- Validation: Built-in validators, custom validation rules
- Relationships: Link (BelongsTo), Detail (HasOne), Collection (HasMany), Connect (BelongsToMany)
- Options: Static options, dynamic options from database
- File Uploads: Image, Video, Audio, File fields with storage
- Rich Content: RichText, Code, Color, KeyValue fields
Patterns
Basic Field Resolver
type {Name}FieldResolver struct{}
func (r *{Name}FieldResolver) ResolveFields(ctx *context.Context) []core.Element {
return []core.Element{
fields.ID().ReadOnly().OnlyOnDetail(),
fields.Text("name").Required().Searchable(),
fields.Email("email").Required().Unique(),
fields.Textarea("description").Nullable(),
fields.Number("price").Required().Min(0),
fields.Number("quantity").Default(0),
fields.Select("status").Options([]fields.Option{
{Label: "Active", Value: "active"},
{Label: "Inactive", Value: "inactive"},
}).Default("active"),
fields.Switch("is_active").Default(true),
fields.Date("published_at").Nullable(),
fields.DateTime("created_at").ReadOnly().OnlyOnDetail(),
fields.Link("user", &user.UserResource{}).DisplayKey("name"),
}
}
File Upload Fields
fields.Image("avatar").
Disk("public").
Path("avatars").
MaxSize(2048).
Accept("image/jpeg,image/png"),
fields.File("document").
Disk("private").
Path("documents").
MaxSize(10240),
Relationship Fields
fields.Link("category", &category.CategoryResource{}).
DisplayKey("name").
Searchable(),
fields.Collection("posts", &post.PostResource{}).
DisplayKey("title"),
fields.Connect("tags", &tag.TagResource{}).
DisplayKey("name").
Searchable(),
Dynamic Options
fields.Select("category_id").
Options(func(ctx *context.Context) []fields.Option {
var categories []domain.Category
ctx.DB().Find(&categories)
options := make([]fields.Option, len(categories))
for i, cat := range categories {
options[i] = fields.Option{
Label: cat.Name,
Value: cat.ID,
}
}
return options
}),
Anti-Patterns
❌ Don't expose sensitive fields - Use ReadOnly() or hide completely
❌ Don't skip validation - Always validate required fields
❌ Don't forget indexes - Add Searchable() for indexed fields
❌ Don't hardcode options - Use dynamic options for database data
❌ Don't ignore file size limits - Set MaxSize() for uploads
❌ Don't forget display keys - Set DisplayKey() for relationships
❌ Don't mix concerns - Keep field logic in resolver, business logic in repository
Decisions
Field Naming
- snake_case for field names (matches database columns)
- Descriptive names that match domain model
- Consistent naming across resources
Validation
- Required for non-nullable fields
- Unique for unique constraints
- Min/Max for number ranges
- Custom validators for complex rules
Display
- OnList for table columns
- OnDetail for detail view
- OnForm for create/edit forms
- OnlyOnDetail for read-only info
- OnlyOnForm for input-only fields
Sharp Edges
⚠️ File Uploads: Configure storage disk and path correctly
⚠️ Relationships: Use DisplayKey to show meaningful data
⚠️ Options: Cache dynamic options for performance
⚠️ Validation: Validate on both client and server
⚠️ Searchable: Only mark indexed fields as searchable
⚠️ ReadOnly: Use for computed or system fields
⚠️ Nullable: Match database schema nullability
Usage
When user asks to add fields to a resource:
- Identify field types based on data type
- Add validation rules (Required, Unique, Min, Max)
- Configure display options (OnList, OnDetail, OnForm)
- Add relationships if needed
- Set defaults for optional fields
- Configure file uploads if needed
- Add searchable for indexed fields
Converted and distributed by TomeVault — claim your Tome and manage your conversions.