Contents

This guide describes the order to follow when adding a new domain area to GoCore. Example name: Note (notes).

Reading order (before writing code)

  1. READING.md — map, naming glossary, golden path
  2. Existing similar context — map/user.md or map/auth.md
  3. DOMAIN.md — layer rules

After adding a new context, also add a short docs/map/<context>.md map (optional but recommended).

Writing checklist

  • Domain + port (internal/domain/...)
  • Migration + db/queries + sqlc generate
  • Persistence repo (adapters/persistence/postgres)
  • Application use cases (application/...) + Service facade
  • RBAC permission (pkg/rbac + route) — if needed
  • HTTP handler + server.go group (pass only Service to handler)
  • GoUI route + controller — if needed (Service in Deps)
  • Bootstrap in relevant wire_*.go (+ GoUI *Deps group)
  • OpenAPI / i18n — if needed
  • Tests + docs/map/ or DOMAIN table entry

1. Domain

internal/domain/note/

  • entity.go — aggregate / entity, invariants
  • repository.go — port interface (no infrastructure knowledge)
  • events.go, value objects as needed

Domain should depend only on its own package and domain/shared.

2. Migration + sqlc

  1. Incremental SQL under migrations/ (up / down)
  2. db/queries/notes.sql — sqlc queries
  3. sqlc generate → output in internal/adapters/persistence/postgres/db/

During development before production launch, you may prefer consolidating the schema in 000001_schema; after production, use incremental migrations only.

3. Persistence adapter

internal/adapters/persistence/postgres/note_repository.go

  • sqlc Queries → domain entity mapping
  • Implements domain/note.Repository

4. Application

internal/application/note/

  • Command / query use cases (CQRS *Handler)
  • service.go facade — HTTP/GoUI connect only to this
  • DTOs (domain types that do not leak to HTTP/GoUI)
  • Dependencies on ports (repo, clock, event publisher…)

Add to application/shared service registry if needed.

5. RBAC (if protected)

  1. pkg/rbacPermNotesList etc. constant + Catalog entry
  2. Verify written to DB via seed / sync
  3. RequirePermission / GoUI permission field on routes

6. HTTP handler

internal/adapters/http/handler/note_handler.go
Register /api/v1/notes group in server.go.

  • Public / protected split
  • Idempotency middleware on mutations (pattern used in the project)
  • Problem JSON + validation errors

Update OpenAPI: api/openapi.yaml.

7. GoUI (dashboard)

  1. routes.gopageRoutes() entry (screen, path, permission, …)
  2. Factory: add type to relevant *Controller(screen) switch in controllers.go chain
  3. Controller (controller_*.go): Mount / HandleEvent logic; Render with template
  4. View: internal/adapters/goui/views/pages/<name>.goui.html
  5. In controller:
    return p.RenderView("pages.<name>", map[string]any{ /* … */ })
    
    File path views/pages/user_show.goui.html → view name "pages.user_show" (underscore → dot-path).
  6. Shared parts: views/components/* (input, select, pagination, export_links, …) and viewmodels.go helpers (viewPagination, viewExportLinks, viewFieldError, …)
  7. Layout/shell already in layouts.shell + partials; page produces body HTML only
  8. i18n: dashboard.* keys (panel_i18n.go + pkg/i18n/locales/tr.json & en.json)
  9. If export is needed: export_routes.go + pkg/tabular

Template hot-reload is enabled in dev (WatchForChanges); embedded views are used in prod.

8. Bootstrap

The dependency graph in internal/bootstrap is split across bootstrap.go (Build orchestration) and wire_*.go files (wire_infra, wire_repos, wire_authz, …). When adding a new module, in the relevant wire_*.go file:

  • create repo
  • create use cases
  • wire handler / GoUI deps

New dependencies are added via constructor injection; no global singletons. See internal/bootstrap/testkit package comments for tests.

9. Tests

  • Domain entity unit tests
  • Application use case (mock ports — mockery)
  • Handler / middleware if needed
  • go test ./... and CI green

10. Documentation

  • One line in README feature list
  • Context row in DOMAIN.md table if needed
  • OpenAPI + /docs if public API
  • Recommended: docs/map/<context>.md (see user/auth examples)

What not to do

  • Read Fiber, sqlc, or env from domain
  • Put aggregates under pkg/ (pkg/rbac is permission constants only)
  • Mix contact form with recipient CSV (contactpkg/recipients)
  • Store secrets in panel/DB (SMS/payment credentials stay in env)

The checklist matches the Writing checklist at the top of this file.