Files
bamort/template/.github/copilot-instructions.md
2026-04-01 15:16:12 +02:00

4.2 KiB

MyApp Development Instructions

A Go + Vue.js full-stack web application template with authentication, user management, i18n, and Docker.

Project Overview

  • Architecture: Monorepo with separate backend/frontend in Docker containers
  • Backend: Go 1.25 + Gin framework + GORM + MariaDB
  • Frontend: Vue 3 + Vite + Pinia + vue-i18n
  • Development: Docker Compose with live-reload (Air for Go, Vite HMR for Vue)

Backend Architecture (backend/)

Module Structure

Each domain module follows this pattern:

module/
  model.go         # GORM entities + MigrateStructure(db)
  handlers.go      # HTTP handlers (Gin controllers)
  routes.go        # Route registration: RegisterRoutes(r *gin.RouterGroup)
  *_test.go        # Tests with setupTestEnvironment(t)

Key conventions:

  • Entry point: cmd/main.go registers all modules via RegisterRoutes(protected)
  • Models: Domain-specific models per module
  • Database: Shared database.DB instance, use MigrateStructure(db) per module
  • Configuration: config.Cfg loaded from env vars (see config/config.go)
  • Environment: ENVIRONMENT=test|development|production
  • Database type: DATABASE_TYPE=mysql|sqlite

Testing Requirements

  • NEVER create test files with main() functions
  • ALWAYS use _test.go suffix
  • ALWAYS call setupTestEnvironment(t) at start of each test:
    func setupTestEnvironment(t *testing.T) {
        original := os.Getenv("ENVIRONMENT")
        os.Setenv("ENVIRONMENT", "test")
        t.Cleanup(func() { os.Setenv("ENVIRONMENT", original) })
    }
    
  • Use testutils.SetupTestDB() for database tests (creates SQLite test DB)

API Patterns

  • Protected routes under /api prefix require JWT authentication
  • Use c.JSON(http.StatusBadRequest, gin.H{"error": "message"}) for error responses
  • Route registration example:
    func RegisterRoutes(r *gin.RouterGroup) {
        group := r.Group("/items")
        group.GET("", ListItems)
        group.POST("", CreateItem)
        group.GET("/:id", GetItem)
        group.PUT("/:id", UpdateItem)
        group.DELETE("/:id", DeleteItem)
    }
    

Frontend Architecture (frontend/)

Component Structure

  • Views: src/views/ - Page-level components
  • Components: src/components/ - Reusable components (Menu, forms)
  • Utils: src/utils/api.js - Axios instance with JWT interceptor
  • Locales: src/locales/de and src/locales/en - i18n translations (plain JS objects, no .js extension)
  • Store: Pinia stores in src/stores/

API Communication

  • Use API.get(), API.post(), API.put(), API.delete() from utils/api.js (auto-adds auth headers)
  • Base URL configured via VITE_API_URL env var

Translation Pattern

Add to both locales/de and locales/en:

export default {
  myModule: {
    title: 'My Module',       // EN
    createButton: 'Create'
  }
}

Docker Development Workflow

Container Names & Ports

Start Development

cd docker/
docker-compose -f docker-compose.dev.yml up -d

View Logs

docker logs myapp-backend-dev --tail=50
docker logs myapp-frontend-dev --tail=20

Testing Commands

Backend Tests

cd backend/
go test -v ./items/
go test -v ./user/
go test ./...

Critical Rules

  1. NEVER write example/demo code — only production code
  2. NEVER create test files with main() — use _test.go
  3. ALWAYS use TDD: write failing test first, then implement
  4. ALWAYS use KISS principle: simplest solution that works
  5. ALWAYS add translations to both DE and EN locales
  6. ALWAYS use global CSS (main.css) for consistent styling — avoid local scoped styles for common UI patterns
  7. ALWAYS check docker ps before assuming containers are running

File-Specific Instructions

Load additional instructions for specific file types:

  • Go files: See .github/instructions/go.instructions.md
  • Vue files: See .github/instructions/vue.instructions.md