--- name: gfly description: "gFly framework expert for Go backend. PROACTIVELY use when working with Go controllers, services, repositories, DTOs, migrations, routes. Triggers: Go, controller, service, DTO, migration, route, gFly, API endpoint, mb model builder" license: MIT metadata: author: https://github.com/vinhio version: "1.0.0" domain: backend role: specialist scope: implementation output-format: code related-skills: golang-expert autoInvoke: true priority: high triggers: - "go" - "golang" - "controller" - "service" - "repository" - "dto" - "migration" - "gfly" - "api endpoint" - "model builder" - "mb.Instance" - "storage" - "core.Api" - "core.Ctx" - "core.Data" - "map[string]string" - "map[string]int" - "map[string]bool" allowed-tools: Read, Grep, Glob, Edit, Write, Bash --- # gFly Framework Expert Skill Expert-level gFly framework patterns (https://www.gfly.dev), Clean Architecture, CRUD APIs, model builder queries, and response handling for this project's Go backend. ## Table of Contents - [Hard Rule](#hard-rule) - [Project Context](#project-context) - [Auto-Detection](#auto-detection) - [Reference Guide](#reference-guide) - [Constraints](#constraints) - [Quick Reference](#quick-reference) ## Hard Rule **Local file I/O MUST go through `github.com/gflydev/storage` with the local driver `github.com/gflydev/storage/local` — never raw OS file I/O** (`os.ReadFile`, `os.WriteFile`, `os.Open`, `os.Create`, `os.Stat`, `io/ioutil`, direct `os`/`filepath` reads/writes). ```go fs := storage.Instance(storageLocal.Type) data, err := fs.Get("releases/latest.json") // NOT os.ReadFile(...) ``` Full detail (registration, `Instance()` default-disk gotcha, no directory-listing method): [Anti-Patterns & Gotchas](references/anti-patterns-and-gotchas.md#local-file-io-must-use-gflydevstoragelocal). ## Project Context Before implementing anything, skim `references/architecture-and-project-structure.md` for this project's directory layout and module system. Then load the other reference files below on demand, based on the task — don't read all 19 upfront. When in doubt, look at nearby files in the same module/layer as the one being added. ## Auto-Detection This skill activates when: - Writing or editing `.go` files - Building API controllers (`core.Api`, `core.Ctx`) - Working with services, DTOs, models, transformers - Adding database migrations - Registering routes in `api_routes.go` or module `routes/` ## Reference Guide Load detailed guidance based on context: | Topic | Reference | Load When | |-------|-----------|-----------| | CRUD — Create & Read | `references/crud-create-read.md` | CRUD overview, HTTP helper functions (`ProcessData`, `ProcessFilter`, `ProcessPathID`), Create (POST) and Read (GET single) API patterns | | CRUD — Update, Delete & List | `references/crud-update-delete-list.md` | Update (PUT/PATCH), Delete, and List (GET collection) API patterns | | CRUD — Advanced Filtering | `references/crud-advanced-filtering.md` | Custom filters with multiple query parameters | | CRUD — Errors & Status Codes | `references/crud-errors-and-status-codes.md` | HTTP status code conventions, error handling in CRUD handlers | | CRUD — Complete Example | `references/crud-complete-example.md` | Full worked CRUD example end-to-end, CRUD best practices | | Model Builder — Basics | `references/model-builder-basics.md` | `mb` setup/initialization, basic CRUD operations (`CreateModel`, `GetModelByID`, `UpdateModel`, `DeleteModel`) | | Model Builder — Querying | `references/model-builder-querying.md` | Query builder patterns (`Where`, `Select`), advanced filtering (`WhereGroup`, `When`), pagination & ordering | | Model Builder — Joins & Transactions | `references/model-builder-joins-and-transactions.md` | Joins/relationships, transactions (try/catch pattern), raw SQL queries | | Model Builder — Errors & Best Practices | `references/model-builder-errors-and-best-practices.md` | `mb` error handling patterns, best practices/rules, quick reference | | DTO & Requests | `references/dto-and-requests.md` | Layered architecture overview, DTO as validation source of truth, Request objects with `ToDto()` | | Transformers in the Pipeline | `references/transformers-in-the-pipeline.md` | Where Response/Transformer objects fit in the DTO → Service → Model → Transformer → Response pipeline | | Response & Transformers (full reference) | `references/response-and-transformers.md` | Full response type reference — generic/custom response types, transformers, helper functions | | Validation & Flow Examples | `references/validation-and-flow-examples.md` | Request validation system, complete end-to-end flow examples | | core.Data | `references/core-data.md` | Replacing `map[string]string`/`int`/`bool`/`any` with the typed `core.Data` wrapper | | Storage | `references/storage.md` | File upload/storage, local vs CS3/S3-compatible providers, presigned URLs | | Email Notifications | `references/email-notifications.md` | Notification structs, Pongo2 email templates, SMTP configuration | | Architecture & Project Structure | `references/architecture-and-project-structure.md` | gFly framework overview, project directory layout, module system, routing, auth/authz, rate limiting, env config, dev workflow checklists | | Domain Model, Routes & Migrations | `references/domain-model-routes-and-migrations.md` | Service layer rules, domain model struct tags, route registration, SQL migration file conventions | | Anti-Patterns & Gotchas | `references/anti-patterns-and-gotchas.md` | Storage hard rule (full detail), common mistakes to avoid (`fmt.Errorf` misuse, missing `ToDto()`, swaggo import alias, gocritic patterns) | For generic Go language guidance not listed above (concurrency, generics, error handling idioms, testing, lint), use the `golang-expert` skill instead of duplicating that guidance here. ## Constraints ### MUST DO - Route all local file I/O through `gflydev/storage/local` (see [Hard Rule](#hard-rule)) - Implement `ToDto()` on every Request struct — required by the `AddData`/`UpdateData` interface - Use a pointer receiver for `SetID` — a value receiver silently fails to update the struct - Use `github.com/gflydev/core/errors` in services — never `fmt.Errorf` - Use the `errors.ItemNotFound` sentinel for not-found cases (controllers map it to 404) - Go through the service layer for database access — never query directly from a controller - Import the `response` package with no alias (or blank `_`) — a custom alias breaks swaggo's `@Success`/`@Failure` type resolution - Use `switch` instead of an if-else chain for 3+ conditional branches (gocritic `ifElseChain`) - Use index-based `range` over slices of structs, not value-copy range (gocritic `rangeValCopy`) - Run `make doc` after adding or changing Swagger annotations ### MUST NOT DO - Return response objects from services — return domain models, transform to response DTOs in the transformer layer - Duplicate generic Go language guidance here — that lives in the `golang-expert` skill ## Quick Reference ```go // Get authenticated user user := c.GetData(constants.User).(appModels.User) // Get path param as int channelID, err := strconv.Atoi(c.PathVal("channel_id")) // Get query params keyword := c.QueryStr("keyword") page := c.QueryInt("page", 1) isActive := c.QueryBool("is_active") // returns (bool, error) // Null value helpers dbNull.String("value") // string → sql.NullString dbNull.StringNil(nullStr) // sql.NullString → *string dbNull.TimeNow() // current time as sql.NullTime dbNull.TimeNil(nullTime) // sql.NullTime → *time.Time // Error sentinel check if errors.Is(err, errors.ItemNotFound) { ... } ``` **Framework:** gFly (github.com/gflydev/*)