AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证轻量级 Go Web 框架,从 Aifei(Java 版)移植。遵循"Just Service"理念——扁平架构。
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗轻量级 Go Web 框架,从 Aifei(Java 版)移植。遵循"Just Service"理念——扁平架构,免写 Controller 层,Dao 弱化为可选薄层。
Register() 按命名约定(动词前缀 + 默认动作)自动映射 struct 方法为 RESTful 端点go get,按需组合,不拉入多余依赖#where/#and/#orderBy + 18 种操作符,条件为空自动省略app.yml + 环境变量 + 命令行参数 + 云配置分层加载,支持运行时热更新GetOrStore 自带 singleflight 与缓存穿透防护Subscribe 至少一次投递模块按角色分层:核心框架(aifei 本体)、核心库(零外部依赖原语,可独立使用)、默认运行时(aifei 的 net/http 适配 + 生产引导)、独立框架(不依赖 aifei 的兄弟框架)、代码生成(tools/)、插件(按需引入第三方库的集成)、示例(_test/,不发布)。
| 层 | 模块 | 说明 | 依赖 |
|---|---|---|---|
| 核心框架 | aifei-go | Input/Output 接口、Router、Handler wrapper、Interceptor | — |
| 核心库 | aifei-go/enjoy | 模板/SQL 引擎 | — |
| 核心库 | aifei-go/db | 数据库访问(Row/Dao/Dialect/Enjoy SQL) | — |
| 核心库 | aifei-go/json | JSON 工具 | — |
| 核心库 | aifei-go/log | 日志接口 | — |
| 核心库 | aifei-go/config | 分层配置(yml + 环境变量 + 命令行 + 云配置) | yaml.v3 |
| 默认运行时 | aifei-go/http | net/http 适配器 | aifei |
| 默认运行时 | aifei-go/server | 启动引导、内置 Handler、响应构建器、Register | aifei, http, db, enjoy, log |
| 独立框架 | aifei-go/nami | HTTP RPC 客户端框架(channel/coder/Filter/Discovery) | — |
| 独立框架 | aifei-go/dami | 进程内事件总线(send/call/stream/lpc) | — |
| 代码生成 | aifei-go/tools/generator | Schema → 类型安全 CRUD 代码 | db, enjoy + sqlite |
| 代码生成 | aifei-go/tools/damigen | dami 相关代码生成 | enjoy |
| 插件 | aifei-go/plugins/cache | 两级缓存(本地 + Redis) | aifei, config, log + jetcache-go, go-redis |
| 插件 | aifei-go/plugins/dami | dami 事件总线接入 aifei | aifei, dami, log |
| 插件 | aifei-go/plugins/kafka | Kafka 生产/消费(franz-go) | aifei, config, log + franz-go |
| 插件 | aifei-go/plugins/nacos | 服务注册、配置中心、发现 | aifei, nami, log + nacos-sdk-go |
| 插件 | aifei-go/plugins/storage | 文件存储(本地 + S3 兼容) | aifei, config, log + minio-go |
| 插件 | aifei-go/plugins/swagger |
Requires Go 1.27.
go get github.com/crazy-airhead/aifei-go
package main
import (
"github.com/crazy-airhead/aifei-go"
"github.com/crazy-airhead/aifei-go/server"
)
func main() {
app := aifei.New()
// 全局 Handler 包装链
app.Use(server.Logger(), server.Recover())
// 路由 — HandlerFunc: func(in aifei.Input) aifei.Output
app.GET("/", func(in aifei.Input) aifei.Output {
return server.Ok("Hello, Aifei!")
})
app.GET("/hello/:name", func(in aifei.Input) aifei.Output {
return server.Ok("Hello, " + in.Param("name"))
})
// 启动(支持 CORS、BasicAuth 等 HTTP 级包装器)
server.Run(app, ":8080", server.WithCORS("*"))
}
db 模块不含驱动,用户自行引入所需驱动:
import (
"github.com/crazy-airhead/aifei-go/db"
_ "modernc.org/sqlite" // 或 _ "github.com/go-sql-driver/mysql" 等
)
func main() {
db.Init("sqlite", "./app.db")
// Active Record — 插入
row := db.NewRow("user").Set("name", "james").Set("age", 18)
result, _ := db.Insert(row)
// 主键查询
found, _ := db.FindByID("user", result.GetID())
// 分页查询
page, _ := db.RawSql("SELECT * FROM user ORDER BY id DESC").Paginate(1, 10)
// Enjoy SQL 模板 — 动态条件
data := map[string]interface{}{"minAge": 18, "status": 1}
list, _ := db.Sql(
"SELECT * FROM user #where() #and(age > #para(minAge)) #and(status = #para(status))",
data,
).Find()
}
import "github.com/crazy-airhead/aifei-go/enjoy"
engine := enjoy.NewEngine("myEngine")
tpl := engine.GetTemplateByString("Hello, #(name)! Age: #(age)")
output := tpl.RenderToString(map[string]interface{}{"name": "james", "age": 18})
从数据库 Schema 自动生成类型安全的代码(每表一个包):
import (
"github.com/crazy-airhead/aifei-go/tools/generator"
)
gen := generator.New(pool, dialect, "./myapp/db", "myapp/db")
gen.Generate() // 一次扫描所有表:user/、loginlog/ …,每张表生成独立包(base/model/dao/service)
// 使用生成的类型安全 API
u, _ := user.FindById(123)
u.SetName("new name").Update()
storage 插件统一本地文件系统与 S3 兼容后端(AWS S3 / Minio / OSS / COS),按 bucket 路由;默认 bucket 由顶层 storage.Put/Get/... 操作:
import (
"os"
"strings"
"github.com/crazy-airhead/aifei-go/aifei"
"github.com/crazy-airhead/aifei-go/config"
"github.com/crazy-airhead/aifei-go/server"
"github.com/crazy-airhead/aifei-go/plugins/storage"
)
func main() {
config.Init(os.Args) // 读 app.yml,填充全局配置
p, _ := storage.NewPlugin(nil) // 自动读 config 的 storage.*,装配多 bucket(nil 用默认日志)
app := aifei.New(aifei.WithPlugin(p))
server.Run(app, ":8080")
// 顶层便捷函数操作默认 bucket
media := storage.NewMedia(strings.NewReader("hello"), "text/plain")
storage.Put("a/b.txt", media)
got, _ := storage.Get("a/b.txt") // *storage.Media
// 指定 bucket
storage.Use("avatars").Put("u1.png", media)
}
对应 app.yml 配置(驱动由 driver 字段或 endpoint 协议推断):
storage:
default: local
buckets:
local:
driver: local
endpoint: /var/data
s3:
driver: s3
endpoint: https://s3.example.com
regionId: us-east-1
accessKey: AK...
secretKey: SK...
autoCreateBucket: true
通过 Register() 自动映射 struct 方法为路由,方法签名遵循 func(in aifei.Input) aifei.Output:
type UserService struct{}
func (s *UserService) List(in aifei.Input) aifei.Output { /* GET /api/user/list */ }
func (s *UserService) Paginate(in aifei.Input) aifei.Output { /* GET /api/user */ }
func (s *UserService) Create(in aifei.Input) aifei.Output { /* POST /api/user */ }
func (s *UserService) GetById(in aifei.Input) aifei.Output { /* GET /api/user/:id */ }
func (s *UserService) UpdateById(in aifei.Input) aifei.Output { /* PUT /api/user/:id */ }
func (s *UserService) DeleteById(in aifei.Input) aifei.Output { /* DELETE /api/user/:id */ }
server.Register(app.Router(), "/api/user", &UserService{})
Register() 通过方法名约定自动推断 HTTP 方法和 URL 路径:
精确匹配(默认 RESTful 端点,直接映射到 service prefix):
| 方法名 | HTTP 方法 | URL |
|---|---|---|
List | GET | /prefix/list |
Paginate | GET | /prefix |
Create | POST | /prefix |
前缀匹配(前缀剥离后,剩余部分转为 kebab-case 路径):
| 方法名前缀 | HTTP 方法 | 示例 |
|---|---|---|
Get* | GET | GetById → GET /prefix/:id |
Post* | POST | PostStatus → POST /prefix/status |
Put* | PUT | PutConfig → PUT /prefix/config |
Delete* | DELETE | DeleteItems → DELETE /prefix/items |
Update* | PUT | UpdateById → PUT /prefix/:id |
特殊转换:
ById 后缀自动转为 /:id 路径参数代码生成器默认使用 struct 名的驼峰形式作为 URL 路径(如 loginLog → /api/v1/loginLog)。如需复数形式,直接修改生成的 service.go 中的 ServicePrefix 常量:
const ServicePrefix = "/api/v1/loginLogs" // 手动改为复数
| 包 | 代码行数 | 测试行数 | 文件数 |
|---|---|---|---|
| enjoy | ~2,800 | — | 16 |
| db + db/sql | ~3,800 | 281 | 24 |
| server | ~1,540 | 334 | 13 |
| nami | ~1,700 | ~1,600 | 22 |
| generator | ~1,290 | 371 | 14 |
| config | ~1,060 | ~2,020 | 5 |
| _test | ~1,020 | ~2,020 | 16 |
| kafka | ~970 | 378 | 13 |
| storage | ~870 | 432 | 13 |
| cache | ~780 | 384 | 15 |
| nacos | ~650 | 95 | 7 |
| aifei | ~620 | — | 8 |
| swagger | ~510 | 341 | 5 |
| http | ~430 | — | 3 |
| log | ~110 | 114 | 2 |
| json | ~40 | 45 | 2 |
| 总计 | ~18,200 | ~8,400 | 178 |
| OpenAPI 文档(knife4j-vue3) |
| aifei, config, log + swaggo/swag |
| 示例 | _test/demo | 完整 Web 应用 Demo | core + db + generator + sqlite |
| 示例 | _test/db_test | 数据库集成测试 | db + sqlite |
| 示例 | _test/cache_test | 缓存集成测试 | miniredis |
| 示例 | _test/kafka_test | Kafka 集成测试 | franz-go/kfake |
| 示例 | _test/enjoy_test | Enjoy 引擎测试 | enjoy |