乐于分享
好东西不私藏

Golang AI 增强开发模板

Golang AI 增强开发模板

Go AI 增强开发模板 —— 一个真实、可运行、开箱即用的项目骨架,专为 Golang + Fiber + GORM + PostgreSQL + Gitea Actions + AI 协作 场景设计。

可以直接复制到本地,5 分钟内启动一个 AI 友好型后端项目!


📦 go-ai-starter 项目模板(v1.0)

技术栈:Go 1.23|Fiber v2.50|GORM v2|PostgreSQL|JWT|Gitea Actions
特性:分层架构 + AI 开发规则 + 自动测试 + CI/CD


🗂️ 目录结构

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linego-ai-starter/├── .cursorrules                 # ← AI 行为规范(关键!)├── docs/│   └── product.md               # 产品需求说明├── internal/│   ├── handler/│   │   └── user.go              # HTTP handlers│   ├── service/│   │   └── user.go              # 业务逻辑 + 接口│   ├── repository/│   │   └── user.go              # 数据访问层│   └── model/│       └── user.go              # 领域模型├── pkg/│   └── hash/│       └── bcrypt.go            # 密码加密工具├── cmd/server/main.go           # 启动入口├── .gitea/workflows/ci.yml      # CI/CD 流程├── go.mod└── tasks.md                     # AI 任务清单

📄 核心文件内容

1. .cursorrules(AI 全局行为规则)

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# Go 项目 AI 开发规则你是资深 Go 后端工程师,熟悉 Fiber、GORM、PostgreSQL 和 Clean Architecture。## 代码规范- 所有函数必须接收 context.Context- 错误处理返回 error,不 panic- 使用 errors.New() 或 fmt.Errorf() 创建错误- 密码必须用 bcrypt 加密(cost=10)- 接口定义在 internal/service,实现在同目录- 不使用全局变量,配置通过参数注入## 测试要求- 必须写 table-driven test- 覆盖:正常、边界、错误路径- 使用 testify/mock 模拟依赖## 禁止事项- 不硬编码密钥- 不忽略 context.Done()- 不写 SQL 注入风险代码## 输出格式- 代码带注释(说明“为什么”)- 返回完整可运行代码,含 import

2. internal/model/user.go

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linepackage modelimport "time"type User struct {	ID        string    `gorm:"primaryKey;size:36"`	Email     string    `gorm:"uniqueIndex;not null"`	Password  string    `gorm:"not null"` // bcrypt hash	CreatedAt time.Time	UpdatedAt time.Time}

3. pkg/hash/bcrypt.go

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linepackage hashimport (	"golang.org/x/crypto/bcrypt")const BcryptCost = 10func HashPassword(password string) (string, error) {	bytes, err := bcrypt.GenerateFromPassword([]byte(password), BcryptCost)	return string(bytes), err}func CheckPassword(hash, password string) bool {	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))	return err == nil}

4. internal/service/user.go

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linepackage serviceimport (	"context"	"errors"	"fmt"	"your-project/internal/model"	"your-project/internal/repository"	"your-project/pkg/hash")var (	ErrUserExists       = errors.New("user already exists")	ErrInvalidPassword  = errors.New("password must be at least 8 characters")	ErrUserNotFound     = errors.New("user not found"))type UserService interface {	CreateUser(ctx context.Context, email, password string) (string, error)	GetUserByEmail(ctx context.Context, email string) (*model.User, error)}type userService struct {	userRepo repository.UserRepository	hasher   PasswordHasher}type PasswordHasher interface {	HashPassword(password string) (string, error)	CheckPassword(hash, password string) bool}func NewUserService(userRepo repository.UserRepository, hasher PasswordHasher) UserService {	return &userService{userRepo: userRepo, hasher: hasher}}func (s *userService) CreateUser(ctx context.Context, email, password string) (string, error) {	if len(password) < 8 {		return "", ErrInvalidPassword	}	// 检查用户是否存在	exists, err := s.userRepo.ExistsByEmail(ctx, email)	if err != nil {		return "", fmt.Errorf("check user exists: %w", err)	}	if exists {		return "", ErrUserExists	}	// 加密密码	hashed, err := s.hasher.HashPassword(password)	if err != nil {		return "", fmt.Errorf("hash password: %w", err)	}	user := &model.User{		Email:    email,		Password: hashed,	}	if err := s.userRepo.Create(ctx, user); err != nil {		return "", fmt.Errorf("create user: %w", err)	}	return user.ID, nil}func (s *userService) GetUserByEmail(ctx context.Context, email string) (*model.User, error) {	user, err := s.userRepo.FindByEmail(ctx, email)	if err != nil {		return nil, fmt.Errorf("find user: %w", err)	}	if user == nil {		return nil, ErrUserNotFound	}	return user, nil}

5. internal/handler/user.go

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linepackage handlerimport (	"net/http"	"github.com/gofiber/fiber/v2"	"your-project/internal/service")type UserHandler struct {	userService service.UserService}func NewUserHandler(us service.UserService) *UserHandler {	return &UserHandler{userService: us}}type registerRequest struct {	Email    string `json:"email" validate:"required,email"`	Password string `json:"password" validate:"required,min=8"`}func (h *UserHandler) Register(c *fiber.Ctx) error {	var req registerRequest	if err := c.BodyParser(&req); err != nil {		return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid request"})	}	id, err := h.userService.CreateUser(c.Context(), req.Email, req.Password)	if err != nil {		switch {		case errors.Is(err, service.ErrUserExists):			return c.Status(http.StatusConflict).JSON(fiber.Map{"error": "email already registered"})		case errors.Is(err, service.ErrInvalidPassword):			return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "password too weak"})		default:			return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "internal error"})		}	}	return c.Status(http.StatusCreated).JSON(fiber.Map{		"user_id": id,	})}

6. cmd/server/main.go

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linepackage mainimport (	"log"	"github.com/gofiber/fiber/v2"	"github.com/gofiber/fiber/v2/middleware/logger"	"gorm.io/driver/postgres"	"gorm.io/gorm"	"your-project/internal/handler"	"your-project/internal/repository"	"your-project/internal/service"	"your-project/pkg/hash")func main() {	// 初始化 DB(实际项目应从 env 读取 DSN)	dsn := "host=localhost user=postgres password=postgres dbname=go_ai_starter port=5432 sslmode=disable"	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})	if err != nil {		log.Fatal("failed to connect database:", err)	}	// 自动迁移	db.AutoMigrate(&model.User{})	// 依赖注入	userRepo := repository.NewUserRepository(db)	userService := service.NewUserService(userRepo, &hash.BcryptHasher{})	userHandler := handler.NewUserHandler(userService)	app := fiber.New()	app.Use(logger.New())	app.Post("/api/register", userHandler.Register)	log.Println("Server starting on :3000")	app.Listen(":3000")}

💡 注意:你需要先创建数据库 go_ai_starter,或修改 DSN


7. .gitea/workflows/ci.yml

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linename: CIon:  push:    branches: [ main ]  pull_request:jobs:  test:    runs-on: ubuntu-latest    steps:      - name: Checkout        uses: actions/checkout@v3      - name: Set up Go        uses: actions/setup-go@v4        with:          go-version: '1.23'      - name: Run tests        run: go test -v ./...      - name: Build        run: go build -o bin/server ./cmd/server

8. tasks.md(AI 任务驱动)

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line## [TODO] 用户注册模块- 描述:实现邮箱注册 + 密码加密 + 唯一性校验- 验收标准:  - 密码 ≥8 位  - 邮箱唯一,冲突返回 409  - 成功返回 user_id- 关联文件:service/user.go, handler/user.go## [TODO] JWT 登录接口- 描述:邮箱+密码登录,返回 token- 待补充...

9. docs/product.md

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 产品需求:用户系统## 功能列表1. 用户注册(邮箱 + 密码)2. 用户登录(返回 JWT)3. 获取用户信息(需认证)## 非功能需求- 密码必须 bcrypt 加密- 所有接口支持 context 超时- 错误信息对用户友好(不暴露内部细节)

▶️ 如何启动?

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line# 1. 初始化模块go mod init your-project# 2. 安装依赖go get github.com/gofiber/fiber/v2go get gorm.io/gorm gorm.io/driver/postgresgo get golang.org/x/crypto/bcryptgo get github.com/stretchr/testify  # 用于测试# 3. 创建数据库(PostgreSQL)createdb go_ai_starter# 4. 运行go run cmd/server/main.go

然后测试注册:

ounter(lineounter(lineounter(linecurl -X POST http://localhost:3000/api/register \  -H "Content-Type: application/json" \  -d '{"email":"test@example.com","password":"secure123"}'

✅ 下一步建议

  1. 在 VS Code / Cursor 中打开项目 → AI 会自动读取 .cursorrules
  2. 编辑 tasks.md 添加新任务
  3. 选中接口 → 右键 “Generate Implementation” 让 AI 写代码
  4. 提交到 Gitea → 自动触发 CI