# Backend Development Guidelines(oci-portal 后端规范)

> Go 后端(`oci-portal/`)编码规范入口。规范提炼自 Google / Uber Go Style Guide、Effective Go 与 Go 官方模块布局指南,按本项目裁剪;条目与项目约定冲突时,以本 spec 为准。

---

## 技术栈约束

Gin + GORM + SQLite(纯 Go 驱动 `glebarez/sqlite`,免 CGO;默认与推荐)+ AES-GCM 字段加密 + `oracle/oci-go-sdk/v65`;JWT + bcrypt 用于登录。可选 MySQL / PostgreSQL(`DB_DRIVER`/`DB_DSN`,纯 Go 驱动,experimental);模型新增长文本字段时注意 MySQL 映射:确定 <64KB 用 `type:text`,可能超 64KB 用 `size:16777216`(→MEDIUMTEXT),短字段走 DefaultStringSize=512。**不引入 Redis**,单实例部署按需用进程内缓存;SQLite 快照承担"最近一次云端状态"。前端产物经 `internal/webui` go:embed 嵌入,来源为前端仓库 Release 的 `dist.zip`(release.yml 自动下载;本地构建方式见 README)。选型理由与本地运行方式(环境变量等)见 `docs/开发指南.md`。

---

## Guidelines Index

| Guide | 内容 | 状态 |
|-------|------|------|
| [Directory Structure](./directory-structure.md) | 目录职责与代码组织约定 | 已填 |
| [Error Handling](./error-handling.md) | 错误包装、传播与 panic 纪律 | 已填 |
| [Quality Guidelines](./quality-guidelines.md) | 工具链检查与命名规范 | 已填 |
| [Concurrency](./concurrency.md) | goroutine 生命周期与 context 传递 | 已填 |
| [Testing](./testing.md) | table-driven 测试要求 | 已填 |
| [Database Guidelines](./database-guidelines.md) | ORM 模式、查询、迁移 | 待填 |
| [OCI Audit](./oci-audit.md) | 审计事件双通道数据源、检索语义与预算纪律 | 已填 |
| [Logging Guidelines](./logging-guidelines.md) | 结构化日志、日志级别 | 待填 |

---

## Pre-Development Checklist

写代码前确认:

- [ ] 读过 [Directory Structure](./directory-structure.md),新代码放对了包(云请求只出现在 `internal/oci/`)
- [ ] 阻塞 / 远程调用函数第一个参数是 `ctx context.Context`(见 [Concurrency](./concurrency.md))
- [ ] 错误按 [Error Handling](./error-handling.md) 用 `%w` 包装向上返回
- [ ] 复用已有封装,不重复造轮子(见 `../guides/code-reuse-thinking-guide.md`)

## Quality Check

提交前必过:

```bash
gofmt -l . && goimports -l .   # 格式(或由编辑器保存时完成)
go vet ./...
go test ./...
go mod tidy                     # 依赖有变更时
```

有 `golangci-lint` 配置时以其为准。新逻辑必须带 table-driven 测试,`go test ./...` 全绿才算完成。

## API 文档(swagger)

全部 HTTP 接口带 swaggo 注释(@Summary 中文/@Tags 按域/@Param/@Success/@Router;JWT 组接口标 @Security BearerAuth)。**新增或修改接口必须同步注释**,并重新生成 spec:

```bash
go tool swag init -g cmd/server/main.go -o docs --parseInternal --parseDependency --overridesFile docs/.swaggo
```

生成的 `docs/` 一并提交;UI 由 `SWAGGER=1` 开启(/swagger/index.html)。同名 handler 方法(list/create/get/update/remove)分布在多个 struct 上,写注释时确认 @Router 路径与该 receiver 的真实注册一致(routes_*.go)。
