Full Code of goal-web/goal for AI

1.0 29044846b598 cached
96 files
194.9 KB
68.3k tokens
266 symbols
1 requests
Download .txt
Showing preview only (220K chars total). Download the full file or copy to clipboard to get everything.
Repository: goal-web/goal
Branch: 1.0
Commit: 29044846b598
Files: 96
Total size: 194.9 KB

Directory structure:
gitextract_fxwyv0x_/

├── .github/
│   └── ISSUE_TEMPLATE.MD
├── .gitignore
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── app/
│   ├── console/
│   │   ├── commands/
│   │   │   └── runner.go
│   │   └── kernel.go
│   ├── controllers/
│   │   ├── helloworld.go
│   │   ├── kernel.go
│   │   ├── project/
│   │   │   └── Project_gen.go
│   │   └── user/
│   │       └── Auth_gen.go
│   ├── enums/
│   │   └── Code_gen.go
│   ├── exceptions/
│   │   └── handler.go
│   ├── http/
│   │   ├── middlewares/
│   │   │   └── example.go
│   │   └── sse/
│   │       └── demo.go
│   ├── jobs/
│   │   └── demo.go
│   ├── listeners/
│   │   └── debug_query.go
│   ├── models/
│   │   ├── Article_gen.go
│   │   ├── Project_gen.go
│   │   ├── User_gen.go
│   │   ├── project/
│   │   │   └── GetProjectRessult_gen.go
│   │   ├── project.go
│   │   └── user/
│   │       └── WechatInfoData_gen.go
│   ├── providers/
│   │   ├── app.go
│   │   ├── console.go
│   │   └── events.go
│   ├── requests/
│   │   ├── project/
│   │   │   ├── CreateProject_gen.go
│   │   │   ├── DeleteProject_gen.go
│   │   │   ├── GetProject_gen.go
│   │   │   ├── ListProjects_gen.go
│   │   │   └── UpdateProject_gen.go
│   │   └── user/
│   │       ├── LoginByWxCode_gen.go
│   │       └── LoginByWxInfo_gen.go
│   ├── response/
│   │   └── utils.go
│   ├── results/
│   │   ├── ResponseResult_gen.go
│   │   ├── project/
│   │   │   ├── CreateProjectResult_gen.go
│   │   │   ├── DeleteProjectResult_gen.go
│   │   │   ├── GetProjectResult_gen.go
│   │   │   ├── ListProjectsResult_gen.go
│   │   │   └── UpdateProjectResult_gen.go
│   │   └── user/
│   │       └── LoginByWxResult_gen.go
│   ├── services/
│   │   ├── project/
│   │   │   ├── Project_gen.go
│   │   │   └── project.go
│   │   └── user/
│   │       └── Auth_gen.go
│   └── websocket/
│       └── demo.go
├── bootstrap/
│   ├── console/
│   │   └── main.go
│   ├── core/
│   │   └── application.go
│   ├── queue/
│   │   └── main.go
│   └── schedule/
│       └── main.go
├── config/
│   ├── README_cache_config.md
│   ├── app.go
│   ├── auth.go
│   ├── bloomfilter.go
│   ├── cache.go
│   ├── cache_example.toml
│   ├── database.go
│   ├── encryption.go
│   ├── filesystem.go
│   ├── http.go
│   ├── mail.go
│   ├── queue.go
│   ├── redis.go
│   ├── serialization.go
│   ├── session.go
│   ├── views.go
│   └── websocket.go
├── database/
│   ├── .gitignore
│   └── migrations/
│       ├── 2024_05_09_141932_create_articles.down.sql
│       └── 2024_05_09_141932_create_articles.sql
├── env.toml
├── go.mod
├── go.sum
├── main.go
├── pro/
│   ├── Article.proto
│   ├── Project.proto
│   ├── common.proto
│   ├── goal-cli.go
│   └── user.proto
├── routes/
│   ├── api.go
│   ├── sse.go
│   └── ws.go
├── sdk.tmpl
├── server.conf
├── storage/
│   ├── app/
│   │   └── .gitignore
│   ├── framework/
│   │   ├── bloomfilter/
│   │   │   └── .gitignore
│   │   ├── cache/
│   │   │   └── .gitignore
│   │   └── sessions/
│   │       └── .gitignore
│   └── logs/
│       └── .gitignore
├── supervisor.conf
├── template.tmpl
├── tests/
│   ├── bootstrap.go
│   ├── bootstrap_test.go
│   ├── db_test.go
│   └── env.toml
└── views/
    └── view.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE.MD
================================================
<!-- Please answer these questions before submitting your issue. Thanks! -->

<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码!否则issue可能会被延期处理! -->
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码!否则issue可能会被延期处理! -->
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码!否则issue可能会被延期处理! -->
<!-- 重要的事情说三遍! -->

### 1. What version of `Go` and system type/arch are you using?
<!-- 
Please paste the output of command `go version` from your terminal.
What expect to see is like: `go 1.25.0, linux/amd64`
-->


### 2. What version of `Goal` are you using?
<!-- You can find the Goal version from your `go.mod` -->


### 3. Can this issue be re-produced with the latest release?



### 4. What did you do?
<!--
If possible, provide a copy of shortest codes for reproducing the error.
A complete runnable program is best.
-->



### 5. What did you expect to see?



### 6. What did you see instead?





================================================
FILE: .gitignore
================================================
.idea
database/*.sqlite
*.pid

/bin*


go.work
go.work.sum

================================================
FILE: Dockerfile
================================================
FROM golang:1.20 as builder
LABEL maintainer="qbhy <qbhy0715@qq.com>"

WORKDIR /app

COPY . /app
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
ENV GOPROXY=https://proxy.golang.com.cn,direct
RUN go build -ldflags="-s -w" -o app main.go

FROM alpine

WORKDIR /app
COPY --from=builder /app/app .

# run
ENTRYPOINT ["/app/app"]

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 桥边红药

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================
DOCKER_TAG=goal

gen:
	go run pro/goal-cli.go --template template.tmpl

run:
	go run main.go run

build:
	go build -o ./bin -v ./

test:
	go test -json ./tests

image:
	docker build -t $(DOCKER_TAG) .

migrate:
	go run bootstrap/console/main.go migrate

migrate-rollback:
	go run bootstrap/console/main.go migrate:rollback

migrate-refresh:
	go run bootstrap/console/main.go migrate:refresh

migrate-reset:
	go run bootstrap/console/main.go migrate:reset

migrate-status:
	go run bootstrap/console/main.go migrate:status

make-migration:
	go run bootstrap/console/main.go make:migration $(NAME)


================================================
FILE: README.md
================================================
# Goal Framework
[![codecov](https://codecov.io/gh/goal-web/goal/branch/master/graph/badge.svg)](https://codecov.io/gh/goal-web/goal)
[![Go Report Card](https://goreportcard.com/badge/github.com/goal-web/goal)](https://goreportcard.com/report/github.com/goal-web/goal)
[![GoDoc](https://pkg.go.dev/badge/github.com/goal-web/goal?status.svg)](https://pkg.go.dev/github.com/goal-web/goal?tab=doc)
[![Join the chat at https://gitter.im/goal-web/goal](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/goal-web/goal?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Sourcegraph](https://sourcegraph.com/github.com/goal-web/goal/-/badge.svg)](https://sourcegraph.com/github.com/goal-web/contracts?badge)
[![Open Source Helpers](https://www.codetriage.com/goal-web/goal/badges/users.svg)](https://www.codetriage.com/goal-web/goal)
[![Release](https://img.shields.io/github/release/goal-web/goal.svg?style=flat-square)](https://github.com/goal-web/goal/releases)
[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/goal-web/goal)](https://www.tickgit.com/browse?repo=github.com/goal-web/goal)

## Star History
![https://api.star-history.com/svg?repos=goal-web/goal&type=Date](https://api.star-history.com/svg?repos=goal-web/goal&type=Date)

## About Goal Framework

Goal Framework is a common application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Goal Framework takes the pain out of development by easing common tasks used in many web projects, such as:

- [Simple and powerful middleware](https://github.com/goal-web/pipeline).
- [Powerful dependency injection container](https://github.com/goal-web/container).
- Multiple back-ends for [session](https://github.com/goal-web/session) and [cache](https://github.com/goal-web/cache) storage.
- Expressive, intuitive [database](https://github.com/goal-web/database).
- [Robust background job processing](https://github.com/goal-web/queue).

Goal framework is accessible, powerful, and provides tools required for large, robust applications.

## Learning Goal Framework
* [Installation](https://github.com/goal-web/doc/blob/wiki/%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/%E5%AE%89%E8%A3%85.md)
* [Documents](https://github.com/goal-web/doc/blob/wiki/README.md)

## Contributing

Thank you for considering contributing to the Goal framework! The contribution guide can be found in the [Goal documentation](https://github.com/goal-web/doc/blob/wiki/%E5%89%8D%E8%A8%80/%E8%B4%A1%E7%8C%AE%E6%8C%87%E5%BC%95.md).

## License

The Goal framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

================================================
FILE: app/console/commands/runner.go
================================================
package commands

import (
	"fmt"
	"github.com/goal-web/contracts"
	"github.com/goal-web/supports/commands"
	"github.com/goal-web/supports/logs"
	"os"
)

type runner struct {
	commands.Command
	app contracts.Application
}

func Runner() (contracts.Command, contracts.CommandHandlerProvider) {
	return commands.Base("run", "启动 goal"),
		func(app contracts.Application) contracts.CommandHandler {
			return &runner{app: app}
		}
}

func (runner *runner) Handle() any {
	path, _ := os.Getwd()
	pidPath := path + "/goal.pid"
	// 写入 pid 文件
	_ = os.WriteFile(pidPath, []byte(fmt.Sprintf("%d", os.Getpid())), os.ModePerm)

	if errors := runner.app.Start(); len(errors) > 0 {
		logs.WithField("errors", errors).Fatal("goal 启动异常!")
	} else {
		_ = os.Remove(pidPath)
		logs.Default().Info("goal 已关闭")
	}
	return nil
}


================================================
FILE: app/console/kernel.go
================================================
package console

import (
	"github.com/goal-web/config"
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/console/commands"
	"github.com/goal-web/supports/logs"
)

var Commands = []contracts.CommandProvider{
	commands.Runner,
	config.EncryptionCommand,
}

func Schedule(schedule contracts.Schedule) {
	schedule.Call(func() {
		//fmt.Println("打印 hello")
		logs.Default().Info("打印 hello")
	}).EveryFiveSeconds()
}


================================================
FILE: app/controllers/helloworld.go
================================================
package controllers

import (
	"fmt"
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/models"
	"github.com/gookit/goutil/dump"
)

func HelloWorld() any {
	createProject()
	updateProject()
	dump.P(23)
	projects := getProjectList()
	return contracts.Fields{
		"data": projects,
	}
}

func createProject() {
	fields := contracts.Fields{
		"uuid":           "45",
		"name":           "your_project_name",
		"creator_id":     1,
		"group_id":       1,
		"key_id":         1,
		"repo_address":   "your_repo_address",
		"project_path":   "your_project_path",
		"default_branch": "main",
		"settings":       "{}",
	}
	model := models.NewProjectModel(fields)
	err := model.Save()
	if err != nil {
		fmt.Printf("Failed to create project: %v\n", err)
	} else {
		fmt.Println("Project created successfully111")
	}
}

func getProjectOne() any {
	query := models.ProjectQuery()
	project := query.Where("id", 1).First() // 假设查询 id 为 1 的记录
	fmt.Printf("Project: %+v\n", project)

	return project
}

func getProjectList() any {
	query := models.ProjectQuery()

	projects := query.Get().ToAnyArray() //
	dump.P(projects)

	return projects
}

func updateProject() {
	query := models.ProjectQuery()
	project := query.Where("id", 1).First() // 假设更新 id 为 1 的记录

	updateFields := contracts.Fields{
		"name": "updated_project_name11",
	}
	err := project.Update(updateFields)

	dump.P(err)
}

func deleteProject() {
	query := models.ProjectQuery()
	project := query.Where("id", 1).First() // 假设删除 id 为 1 的记录

	_ = project.Delete()

}


================================================
FILE: app/controllers/kernel.go
================================================
package controllers

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/controllers/project"
	"github.com/goal-web/goal/app/controllers/user"
)

// Register 注册路由函数
func Register(router contracts.HttpRouter) {
	user.AuthServiceRouter(router)
	project.ProjectServiceRouter(router)

	// 在这里添加您的路由注册逻辑
}


================================================
FILE: app/controllers/project/Project_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
	project "github.com/goal-web/goal/app/requests/project"
	"github.com/goal-web/goal/app/response"
	svc "github.com/goal-web/goal/app/services/project"
	"github.com/goal-web/validation"
)

func ProjectServiceRouter(router contracts.HttpRouter) {
	routeGroup := router.Group("/project")
	routeGroup.Post("/CreateProject", ProjectServiceCreateProject)
	routeGroup.Get("/GetProject", ProjectServiceGetProject)
	routeGroup.Get("/ListProjects", ProjectServiceListProjects)
	routeGroup.Post("/UpdateProject", ProjectServiceUpdateProject)
	routeGroup.Post("/DeleteProject", ProjectServiceDeleteProject)
}
func ProjectServiceCreateProject(request contracts.HttpRequest) any {
	var req project.CreateProjectReq

	if err := request.Parse(&req); err != nil {
		return response.ParseReqErr(err)
	}

	if err := validation.Struct(req); err != nil {
		return response.InvalidReq(err)
	}

	resp, err := svc.ProjectServiceCreateProject(&req, request)
	if err != nil {
		return response.BizErr(err)
	}

	return response.Success(resp)
}
func ProjectServiceGetProject(request contracts.HttpRequest) any {
	var req project.GetProjectReq

	if err := request.Parse(&req); err != nil {
		return response.ParseReqErr(err)
	}

	if err := validation.Struct(req); err != nil {
		return response.InvalidReq(err)
	}

	resp, err := svc.ProjectServiceGetProject(&req, request)
	if err != nil {
		return response.BizErr(err)
	}

	return response.Success(resp)
}
func ProjectServiceListProjects(request contracts.HttpRequest) any {
	var req project.ListProjectsReq

	if err := request.Parse(&req); err != nil {
		return response.ParseReqErr(err)
	}

	if err := validation.Struct(req); err != nil {
		return response.InvalidReq(err)
	}

	resp, err := svc.ProjectServiceListProjects(&req, request)
	if err != nil {
		return response.BizErr(err)
	}

	return response.Success(resp)
}
func ProjectServiceUpdateProject(request contracts.HttpRequest) any {
	var req project.UpdateProjectReq

	if err := request.Parse(&req); err != nil {
		return response.ParseReqErr(err)
	}

	if err := validation.Struct(req); err != nil {
		return response.InvalidReq(err)
	}

	resp, err := svc.ProjectServiceUpdateProject(&req, request)
	if err != nil {
		return response.BizErr(err)
	}

	return response.Success(resp)
}
func ProjectServiceDeleteProject(request contracts.HttpRequest) any {
	var req project.DeleteProjectReq

	if err := request.Parse(&req); err != nil {
		return response.ParseReqErr(err)
	}

	if err := validation.Struct(req); err != nil {
		return response.InvalidReq(err)
	}

	resp, err := svc.ProjectServiceDeleteProject(&req, request)
	if err != nil {
		return response.BizErr(err)
	}

	return response.Success(resp)
}


================================================
FILE: app/controllers/user/Auth_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/user.proto
// 
package user

import (
	"github.com/goal-web/contracts"
	user "github.com/goal-web/goal/app/requests/user"
	"github.com/goal-web/goal/app/response"
	svc "github.com/goal-web/goal/app/services/user"
	"github.com/goal-web/validation"
)

func AuthServiceRouter(router contracts.HttpRouter) {
	routeGroup := router.Group("/auth")
	routeGroup.Post("/LoginByWxAppCode", AuthServiceLoginByWxAppCode, "guest")
	routeGroup.Post("/LoginByWxAppInfo", AuthServiceLoginByWxAppInfo, "guest")
}
func AuthServiceLoginByWxAppCode(request contracts.HttpRequest) any {
	var req user.LoginByWxCodeReq

	if err := request.Parse(&req); err != nil {
		return response.ParseReqErr(err)
	}

	if err := validation.Struct(req); err != nil {
		return response.InvalidReq(err)
	}

	resp, err := svc.AuthServiceLoginByWxAppCode(&req, request)
	if err != nil {
		return response.BizErr(err)
	}

	return response.Success(resp)
}
func AuthServiceLoginByWxAppInfo(request contracts.HttpRequest) any {
	var req user.LoginByWxInfoReq

	if err := request.Parse(&req); err != nil {
		return response.ParseReqErr(err)
	}

	if err := validation.Struct(req); err != nil {
		return response.InvalidReq(err)
	}

	resp, err := svc.AuthServiceLoginByWxAppInfo(&req, request)
	if err != nil {
		return response.BizErr(err)
	}

	return response.Success(resp)
}


================================================
FILE: app/enums/Code_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/common.proto
// 
package enums

type Code int

const (

	// CodeSuccess
	// @msg:成功
	CodeSuccess Code = 0

	// CodeParseReqErr
	// @msg:参数解析失败
	CodeParseReqErr Code = 10400

	// CodeUnauthorized
	// @msg:未登录
	CodeUnauthorized Code = 10401

	// CodeForbidden
	// @msg:没有权限
	CodeForbidden Code = 100403

	// CodeNotFound
	// @msg:找不到
	CodeNotFound Code = 100404

	// CodeBizErr
	// @msg:业务错误
	CodeBizErr  Code = 10201
	CodeUnknown Code = -1000
)

func (item Code) String() string {
	switch item {
	case CodeSuccess:
		return "Success"
	case CodeParseReqErr:
		return "ParseReqErr"
	case CodeUnauthorized:
		return "Unauthorized"
	case CodeForbidden:
		return "Forbidden"
	case CodeNotFound:
		return "NotFound"
	case CodeBizErr:
		return "BizErr"
	default:
		return "Unknown"
	}
}

func (item Code) Message() string {
	switch item {
	case CodeSuccess:
		return "成功"
	case CodeParseReqErr:
		return "参数解析失败"
	case CodeUnauthorized:
		return "未登录"
	case CodeForbidden:
		return "没有权限"
	case CodeNotFound:
		return "找不到"
	case CodeBizErr:
		return "业务错误"
	default:
		return "Unknown"
	}
}

func ParseCodeFromString(msg string) Code {
	switch msg {
	case "Success":
		return CodeSuccess
	case "ParseReqErr":
		return CodeParseReqErr
	case "Unauthorized":
		return CodeUnauthorized
	case "Forbidden":
		return CodeForbidden
	case "NotFound":
		return CodeNotFound
	case "BizErr":
		return CodeBizErr
	default:
		return CodeUnknown
	}
}


================================================
FILE: app/exceptions/handler.go
================================================
package exceptions

import (
	"reflect"
	"runtime/debug"
	"strings"

	"github.com/goal-web/contracts"
	"github.com/goal-web/http"
	"github.com/goal-web/supports/logs"
	"github.com/goal-web/supports/utils"
	"github.com/goal-web/validation"
)

type ExceptionHandler struct {
	dontReportExceptions []reflect.Type
}

func NewHandler() contracts.ExceptionHandler {
	return &ExceptionHandler{utils.ToTypes([]contracts.Exception{})}
}

func (handler *ExceptionHandler) Handle(exception contracts.Exception) any {
	logs.WithException(exception).Warn("报错了")
	switch e := exception.(type) {
	case http.Exception: // http 支持在异常处理器返回响应
		return handler.handleHttpException(e)
	case *validation.Exception:
		return handler.renderValidationException(e)
	default:
		debug.PrintStack()
	}

	logs.WithException(exception).
		WithField("exception", reflect.TypeOf(exception).String()).
		Error("ExceptionHandler")

	if httpException, isHttpException := exception.(http.Exception); isHttpException {
		logs.WithException(httpException).WithFields(contracts.Fields{}).Debug("http请求报错")
	}

	if handler.ShouldReport(exception) {
		handler.Report(exception)
	}

	return nil
}

func (handler *ExceptionHandler) handleHttpException(exception http.Exception) any {

	switch e := exception.Exception.(type) {
	case *validation.Exception:
		return handler.renderValidationException(e)
	default:
		if !strings.Contains(exception.Error(), "404") {
			debug.PrintStack()
		}
		return contracts.Fields{
			"path":  exception.Request.Path(),
			"error": e.Error(),
		}
	}
}

func (handler *ExceptionHandler) renderValidationException(exception *validation.Exception) any {
	return contracts.Fields{
		"msg":    exception.Error(),
		"fields": exception.Param,
		"errors": exception.Errors,
	}
}

func (handler *ExceptionHandler) Report(exception contracts.Exception) {
}
func (handler *ExceptionHandler) ShouldReport(exception contracts.Exception) bool {
	return !utils.IsInstanceIn(exception, handler.dontReportExceptions...)
}


================================================
FILE: app/http/middlewares/example.go
================================================
package middlewares

import (
	"fmt"
	"github.com/goal-web/contracts"
	"github.com/goal-web/http"
)

func Example(request contracts.HttpRequest, next contracts.Pipe) any {
	fmt.Println("controller before")

	result := next(request)

	fmt.Println("controller after")
	return http.NewJsonResponse(contracts.Fields{
		"result": result,
	}, 200)
}


================================================
FILE: app/http/sse/demo.go
================================================
package sse

import (
	"errors"
	"github.com/goal-web/contracts"
)

type DemoController struct {
}

func (d DemoController) OnConnect(request contracts.HttpRequest, fd uint64) error {
	// 伪代码
	if request.GetString("token") != "goal" {
		return errors.New("401")
	}

	// todo: 绑定用户和 fd

	return nil
}

func (d DemoController) OnClose(fd uint64) {
	// todo: 实现解绑
}


================================================
FILE: app/jobs/demo.go
================================================
package jobs

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/queue"
	"github.com/goal-web/supports/class"
	"github.com/goal-web/supports/logs"
	"github.com/goal-web/supports/utils"
	"time"
)

var DemoClass = class.Any(Demo{})

type Demo struct {
	*queue.Job
	Info string `json:"info"`
}

func NewDemo(info string) contracts.Job {
	return &Demo{
		Job: &queue.Job{
			UUID:       utils.RandStr(5),
			CreatedAt:  time.Now().Unix(),
			Queue:      "default",
			Connection: "default",
			Tries:      0,
			MaxTries:   3,
			Timeout:    0,
		},
		Info: info,
	}
}

func (demo *Demo) Handle() {
	logs.Default().WithField("info", demo.Info).Info("demo job")
}


================================================
FILE: app/listeners/debug_query.go
================================================
package listeners

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/database/events"
	"github.com/goal-web/supports/logs"
)

type DebugQuery struct {
}

func (d DebugQuery) Handle(event contracts.Event) {
	if e, ok := event.(*events.QueryExecuted); ok {
		logs.WithFields(contracts.Fields{
			"sql":        e.Sql,
			"bindings":   e.Bindings,
			"connection": e.Connection,
			"time":       e.Time,
		}).Debug("sql executed")
	}
}


================================================
FILE: app/models/Article_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Article.proto
// 
package models

import (
	"encoding/json"
	"fmt"
	"github.com/goal-web/collection"
	"github.com/goal-web/contracts"
	"github.com/goal-web/database/table"
	"github.com/goal-web/migration/migrate"
	"github.com/goal-web/supports/logs"
	"github.com/goal-web/supports/utils"
	"github.com/spf13/cast"
)

var ()

// ArticleModel
// @timestamps
type ArticleModel struct {
	Id uint32 `json:"id" query:"id" form:"id" db:"id;type:INT UNSIGNED;not null;primary key;AUTO_INCREMENT;"`

	Title string `json:"title" query:"title" form:"title" db:"title;type:VARCHAR(255);not null;"`

	CreatedAt string `json:"created_at" query:"created_at" form:"created_at" db:"created_at;type:timestamp;default CURRENT_TIMESTAMP;"`

	UpdatedAt string `json:"updated_at" query:"updated_at" form:"updated_at" db:"updated_at;type:timestamp;DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;"`

	_raw    contracts.Fields
	_update contracts.Fields
	_append contracts.Fields
	_hidden map[string]struct{}

	_relation_loaded map[contracts.RelationType]struct{}
}

var ArticleDefine ArticleStatic

type ArticleStatic struct {
	TableName       string
	Hidden          []string
	Indexes         []string
	With            []contracts.RelationType
	Appends         map[string]func(model *ArticleModel) any
	IdGetter        func(model *ArticleModel, raw uint32) uint32
	IdSetter        func(model *ArticleModel, raw uint32) uint32
	TitleGetter     func(model *ArticleModel, raw string) string
	TitleSetter     func(model *ArticleModel, raw string) string
	CreatedAtGetter func(model *ArticleModel, raw string) string
	CreatedAtSetter func(model *ArticleModel, raw string) string
	UpdatedAtGetter func(model *ArticleModel, raw string) string
	UpdatedAtSetter func(model *ArticleModel, raw string) string

	Saving           func(model *ArticleModel) contracts.Exception
	Saved            func(model *ArticleModel)
	Updating         func(model *ArticleModel, fields contracts.Fields) contracts.Exception
	Updated          func(model *ArticleModel, fields contracts.Fields)
	Deleting         func(model *ArticleModel) contracts.Exception
	Deleted          func(model *ArticleModel)
	PrimaryKeyGetter func(model *ArticleModel) any
}

func ArticleMigrator() migrate.Migrator {
	return func(executor contracts.SqlExecutor) contracts.Exception {
		return migrate.Migrate(ArticleDefine.TableName, ArticleDefine.Indexes, ArticleModel{}, executor)
	}
}

func init() {
	ArticleDefine.TableName = "articles"
	ArticleDefine.Appends = make(map[string]func(model *ArticleModel) any)
}

func NewArticleModel(fields contracts.Fields) *ArticleModel {
	var model = ArticleModel{
		_raw: fields,
	}
	model.Set(fields)
	return &model
}

func ArticleModelSingleRelationSetter[T any](key contracts.RelationType) func(item *ArticleModel, value []any) {
	return func(item *ArticleModel, values []any) {
		var value T
		if len(values) > 0 {
			value = values[0].(T)
		}
		item.Set(contracts.Fields{
			string(key): value,
		})
	}
}
func ArticleModelMultiRelationSetter[T any](key contracts.RelationType) func(item *ArticleModel, value []any) {
	return func(model *ArticleModel, value []any) {
		var results []T
		for _, item := range value {
			results = append(results, item.(T))
		}
		model.Set(contracts.Fields{string(key): results})
	}
}

func ArticleModelLocalKeyGetter(key string) func(item *ArticleModel) any {
	return func(item *ArticleModel) any {
		return item.Get(key)
	}
}

func ArticleModelRelationGetter[T any](query func() *table.Table[T], foreignKey string) func(keys []any) map[string][]any {
	return func(keys []any) map[string][]any {
		var results = map[string][]any{}
		for key, values := range query().WhereIn(foreignKey, keys).Get().GroupBy(foreignKey) {
			results[key] = collection.New(values).ToAnyArray()
		}
		return results
	}
}

func ArticleModelThroughRelationGetter[T any](query func() *table.Table[T], midTable, firstKey, secondKey, secondLocalKey string) func(keys []any) map[string][]any {
	return func(keys []any) map[string][]any {
		var results = map[string][]any{}
		groupKey := fmt.Sprintf("%s.%s", midTable, firstKey)
		for key, values := range query().
			AddSelect(fmt.Sprintf("(%s) as _group_key", groupKey)).
			WhereIn(groupKey, keys).
			Join(midTable, fmt.Sprintf("%s.%s", midTable, secondLocalKey), "=", fmt.Sprintf("%s.%s", query().GetTableName(), secondKey)).
			Get().GroupBy("_group_key") {
			results[key] = collection.New(values).ToAnyArray()
		}
		return results
	}
}
func ArticleQueryWithExecutor(executor contracts.SqlExecutor) *table.Table[ArticleModel] {
	return ArticleQuery().SetExecutor(executor)
}

func ArticleQuery() *table.Table[ArticleModel] {
	return table.NewQuery(ArticleDefine.TableName, NewArticleModel).
		SetPrimaryKey("id").
		SetCreatedTimeColumn("created_at").
		SetUpdatedTimeColumn("updated_at").
		SetWiths(ArticleDefine.With...)
}

func (model *ArticleModel) Hidden(fields ...string) *ArticleModel {
	for _, field := range fields {
		if model._hidden == nil {
			model._hidden = map[string]struct{}{
				field: struct{}{},
			}
		} else {
			model._hidden[field] = struct{}{}
		}

	}

	return model
}

func (model *ArticleModel) Exists() bool {
	return ArticleQuery().Where("id", model.GetPrimaryKey()).Count() > 0
}

func (model *ArticleModel) Save() contracts.Exception {
	if model._update == nil {
		return nil
	}
	if ArticleDefine.Saving != nil {
		if err := ArticleDefine.Saving(model); err != nil {
			return err
		}
	}
	var err contracts.Exception
	var pk = model.GetPrimaryKey()
	if cast.ToUint64(pk) == 0 {
		pk, err = ArticleQuery().Where("id", model.GetPrimaryKey()).InsertGetIdE(model._update)
		if err == nil {
			model.SetId(cast.ToUint32(pk))
		}
	} else {
		_, err = ArticleQuery().Where("id", model.GetPrimaryKey()).UpdateE(model._update)
	}
	if err == nil {
		model._update = nil
		if ArticleDefine.Saved != nil {
			ArticleDefine.Saved(model)
		}
	}

	return err
}

func (model *ArticleModel) Set(fields contracts.Fields) {
	for key, value := range fields {

		switch key {
		case "id":
			switch v := value.(type) {
			case uint32:
				model.SetId(v)
			case func() uint32:
				model.SetId(v())
			case string:
				var vd uint32
				err := json.Unmarshal([]byte(v), &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetId(vd)

			case []byte:
				var vd uint32
				err := json.Unmarshal(v, &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetId(vd)

			default:
				model.SetId(cast.ToUint32(v))
			}
		case "title":
			switch v := value.(type) {
			case string:
				model.SetTitle(v)
			case func() string:
				model.SetTitle(v())
			case []byte:
				model.SetTitle(string(v))

			default:
				model.SetTitle(cast.ToString(v))
			}
		case "created_at":
			switch v := value.(type) {
			case string:
				model.SetCreatedAt(v)
			case func() string:
				model.SetCreatedAt(v())
			case []byte:
				model.SetCreatedAt(string(v))

			default:
				model.SetCreatedAt(cast.ToString(v))
			}
		case "updated_at":
			switch v := value.(type) {
			case string:
				model.SetUpdatedAt(v)
			case func() string:
				model.SetUpdatedAt(v())
			case []byte:
				model.SetUpdatedAt(string(v))

			default:
				model.SetUpdatedAt(cast.ToString(v))
			}
		}

	}
}

func (model *ArticleModel) Only(key ...string) contracts.Fields {
	var fields = make(contracts.Fields)
	for _, k := range key {
		if k == "id" {
			fields[k] = model.GetId()
			continue
		}
		if k == "title" {
			fields[k] = model.GetTitle()
			continue
		}
		if k == "created_at" {
			fields[k] = model.GetCreatedAt()
			continue
		}
		if k == "updated_at" {
			fields[k] = model.GetUpdatedAt()
			continue
		}

		if ArticleDefine.Appends[k] != nil {
			fields[k] = ArticleDefine.Appends[k](model)
		}
	}
	return fields
}

func (model *ArticleModel) Get(key string) any {
	switch key {
	case "id":
		return model.GetId()
	case "title":
		return model.GetTitle()
	case "created_at":
		return model.GetCreatedAt()
	case "updated_at":
		return model.GetUpdatedAt()
	}

	if value, exists := model._append[key]; exists {
		return value
	}

	if fn, exists := ArticleDefine.Appends[key]; exists {
		model._append[key] = fn(model)
		return model._append[key]
	}

	switch contracts.RelationType(key) {
	}

	return nil
}

func (model *ArticleModel) Except(keys ...string) contracts.Fields {
	var excepts = map[string]struct{}{}
	for _, k := range keys {
		excepts[k] = struct{}{}
	}
	var fields = make(contracts.Fields)
	for key, value := range model.ToFields() {
		if _, ok := excepts[key]; ok {
			continue
		}
		fields[key] = value
	}
	return fields
}

func (model *ArticleModel) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}

	model.Hidden(ArticleDefine.Hidden...)

	fields := contracts.Fields{}
	if _, exists := model._hidden["id"]; !exists {
		fields["id"] = model.GetId()
	}
	if _, exists := model._hidden["title"]; !exists {
		fields["title"] = model.GetTitle()
	}
	if _, exists := model._hidden["created_at"]; !exists {
		fields["created_at"] = model.GetCreatedAt()
	}
	if _, exists := model._hidden["updated_at"]; !exists {
		fields["updated_at"] = model.GetUpdatedAt()
	}

	for key := range ArticleDefine.Appends {
		value := model.Get(key)
		if fieldsProvider, ok := value.(contracts.FieldsProvider); ok {
			fields[key] = fieldsProvider.ToFields()
		} else {
			fields[key] = value
		}
	}

	for key := range model._relation_loaded {
		switch key {
		}
	}

	for key, value := range model._raw {
		_, hidden := model._hidden[key]
		if _, exists := fields[key]; !exists && !hidden {
			fields[key] = value
		}
	}

	return fields
}

func (model *ArticleModel) Update(fields contracts.Fields) contracts.Exception {

	if ArticleDefine.Updating != nil {
		if err := ArticleDefine.Updating(model, fields); err != nil {
			return err
		}
	}

	if model._update != nil {
		utils.MergeFields(model._update, fields)
	}

	_, err := ArticleQuery().Where("id", model.GetPrimaryKey()).UpdateE(fields)

	if err == nil {
		model.Set(fields)
		model._update = nil
		if ArticleDefine.Updated != nil {
			ArticleDefine.Updated(model, fields)
		}
	}

	return err
}

func (model *ArticleModel) Refresh() contracts.Exception {
	fields, err := table.ArrayQuery("articles").Where("id", model.GetPrimaryKey()).FirstE()
	if err != nil {
		return err
	}

	model.Set(*fields)
	return nil
}

func (model *ArticleModel) Delete() contracts.Exception {

	if ArticleDefine.Deleting != nil {
		if err := ArticleDefine.Deleting(model); err != nil {
			return err
		}
	}

	_, err := ArticleQuery().Where("id", model.GetPrimaryKey()).DeleteE()
	if err == nil && ArticleDefine.Deleted != nil {
		ArticleDefine.Deleted(model)
	}

	return err
}

func (model *ArticleModel) GetPrimaryKey() any {
	if ArticleDefine.PrimaryKeyGetter != nil {
		return ArticleDefine.PrimaryKeyGetter(model)
	}

	return model.Id
}

func (model *ArticleModel) GetId() uint32 {
	if ArticleDefine.IdGetter != nil {
		return ArticleDefine.IdGetter(model, model.Id)
	}
	return model.Id
}

func (model *ArticleModel) SetId(value uint32) {
	if ArticleDefine.IdSetter != nil {
		value = ArticleDefine.IdSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"id": value}
	} else {
		model._update["id"] = value
	}
	model.Id = value
}

func (model *ArticleModel) GetTitle() string {
	if ArticleDefine.TitleGetter != nil {
		return ArticleDefine.TitleGetter(model, model.Title)
	}
	return model.Title
}

func (model *ArticleModel) SetTitle(value string) {
	if ArticleDefine.TitleSetter != nil {
		value = ArticleDefine.TitleSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"title": value}
	} else {
		model._update["title"] = value
	}
	model.Title = value
}

func (model *ArticleModel) GetCreatedAt() string {
	if ArticleDefine.CreatedAtGetter != nil {
		return ArticleDefine.CreatedAtGetter(model, model.CreatedAt)
	}
	return model.CreatedAt
}

func (model *ArticleModel) SetCreatedAt(value string) {
	if ArticleDefine.CreatedAtSetter != nil {
		value = ArticleDefine.CreatedAtSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"created_at": value}
	} else {
		model._update["created_at"] = value
	}
	model.CreatedAt = value
}

func (model *ArticleModel) GetUpdatedAt() string {
	if ArticleDefine.UpdatedAtGetter != nil {
		return ArticleDefine.UpdatedAtGetter(model, model.UpdatedAt)
	}
	return model.UpdatedAt
}

func (model *ArticleModel) SetUpdatedAt(value string) {
	if ArticleDefine.UpdatedAtSetter != nil {
		value = ArticleDefine.UpdatedAtSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"updated_at": value}
	} else {
		model._update["updated_at"] = value
	}
	model.UpdatedAt = value
}


================================================
FILE: app/models/Project_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package models

import (
	"encoding/json"
	"fmt"
	"github.com/goal-web/collection"
	"github.com/goal-web/contracts"
	"github.com/goal-web/database/table"
	"github.com/goal-web/migration/migrate"
	"github.com/goal-web/supports/logs"
	"github.com/goal-web/supports/utils"
	"github.com/spf13/cast"
)

var ()

// ProjectModel
// @timestamps
type ProjectModel struct {
	Id int64 `json:"id" query:"id" form:"id" db:"id;type:BIGINT;not null;primary key;AUTO_INCREMENT;"`

	Uuid string `json:"uuid" query:"uuid" form:"uuid" db:"uuid;type:VARCHAR(255);not null;"`

	Name string `json:"name" query:"name" form:"name" db:"name;type:VARCHAR(255);not null;"`

	CreatorId int64 `json:"creator_id" query:"creator_id" form:"creator_id" db:"creator_id;type:BIGINT;not null;"`

	GroupId int64 `json:"group_id" query:"group_id" form:"group_id" db:"group_id;type:BIGINT;not null;"`

	KeyId int64 `json:"key_id" query:"key_id" form:"key_id" db:"key_id;type:BIGINT;not null;"`

	RepoAddress string `json:"repo_address" query:"repo_address" form:"repo_address" db:"repo_address;type:VARCHAR(255);not null;"`

	ProjectPath string `json:"project_path" query:"project_path" form:"project_path" db:"project_path;type:VARCHAR(255);not null;"`

	DefaultBranch string `json:"default_branch" query:"default_branch" form:"default_branch" db:"default_branch;type:VARCHAR(255);not null;"`

	Settings string `json:"settings" query:"settings" form:"settings" db:"settings;type:VARCHAR(255);not null;"`

	CreatedAt string `json:"created_at" query:"created_at" form:"created_at" db:"created_at;type:timestamp;default CURRENT_TIMESTAMP;"`

	UpdatedAt string `json:"updated_at" query:"updated_at" form:"updated_at" db:"updated_at;type:timestamp;DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;"`

	_raw    contracts.Fields
	_update contracts.Fields
	_append contracts.Fields
	_hidden map[string]struct{}

	_relation_loaded map[contracts.RelationType]struct{}
}

var ProjectDefine ProjectStatic

type ProjectStatic struct {
	TableName           string
	Hidden              []string
	Indexes             []string
	With                []contracts.RelationType
	Appends             map[string]func(model *ProjectModel) any
	IdGetter            func(model *ProjectModel, raw int64) int64
	IdSetter            func(model *ProjectModel, raw int64) int64
	UuidGetter          func(model *ProjectModel, raw string) string
	UuidSetter          func(model *ProjectModel, raw string) string
	NameGetter          func(model *ProjectModel, raw string) string
	NameSetter          func(model *ProjectModel, raw string) string
	CreatorIdGetter     func(model *ProjectModel, raw int64) int64
	CreatorIdSetter     func(model *ProjectModel, raw int64) int64
	GroupIdGetter       func(model *ProjectModel, raw int64) int64
	GroupIdSetter       func(model *ProjectModel, raw int64) int64
	KeyIdGetter         func(model *ProjectModel, raw int64) int64
	KeyIdSetter         func(model *ProjectModel, raw int64) int64
	RepoAddressGetter   func(model *ProjectModel, raw string) string
	RepoAddressSetter   func(model *ProjectModel, raw string) string
	ProjectPathGetter   func(model *ProjectModel, raw string) string
	ProjectPathSetter   func(model *ProjectModel, raw string) string
	DefaultBranchGetter func(model *ProjectModel, raw string) string
	DefaultBranchSetter func(model *ProjectModel, raw string) string
	SettingsGetter      func(model *ProjectModel, raw string) string
	SettingsSetter      func(model *ProjectModel, raw string) string
	CreatedAtGetter     func(model *ProjectModel, raw string) string
	CreatedAtSetter     func(model *ProjectModel, raw string) string
	UpdatedAtGetter     func(model *ProjectModel, raw string) string
	UpdatedAtSetter     func(model *ProjectModel, raw string) string

	Saving           func(model *ProjectModel) contracts.Exception
	Saved            func(model *ProjectModel)
	Updating         func(model *ProjectModel, fields contracts.Fields) contracts.Exception
	Updated          func(model *ProjectModel, fields contracts.Fields)
	Deleting         func(model *ProjectModel) contracts.Exception
	Deleted          func(model *ProjectModel)
	PrimaryKeyGetter func(model *ProjectModel) any
}

func ProjectMigrator() migrate.Migrator {
	return func(executor contracts.SqlExecutor) contracts.Exception {
		return migrate.Migrate(ProjectDefine.TableName, ProjectDefine.Indexes, ProjectModel{}, executor)
	}
}

func init() {
	ProjectDefine.TableName = "projects"
	ProjectDefine.Appends = make(map[string]func(model *ProjectModel) any)
}

func NewProjectModel(fields contracts.Fields) *ProjectModel {
	var model = ProjectModel{
		_raw: fields,
	}
	model.Set(fields)
	return &model
}

func ProjectModelSingleRelationSetter[T any](key contracts.RelationType) func(item *ProjectModel, value []any) {
	return func(item *ProjectModel, values []any) {
		var value T
		if len(values) > 0 {
			value = values[0].(T)
		}
		item.Set(contracts.Fields{
			string(key): value,
		})
	}
}
func ProjectModelMultiRelationSetter[T any](key contracts.RelationType) func(item *ProjectModel, value []any) {
	return func(model *ProjectModel, value []any) {
		var results []T
		for _, item := range value {
			results = append(results, item.(T))
		}
		model.Set(contracts.Fields{string(key): results})
	}
}

func ProjectModelLocalKeyGetter(key string) func(item *ProjectModel) any {
	return func(item *ProjectModel) any {
		return item.Get(key)
	}
}

func ProjectModelRelationGetter[T any](query func() *table.Table[T], foreignKey string) func(keys []any) map[string][]any {
	return func(keys []any) map[string][]any {
		var results = map[string][]any{}
		for key, values := range query().WhereIn(foreignKey, keys).Get().GroupBy(foreignKey) {
			results[key] = collection.New(values).ToAnyArray()
		}
		return results
	}
}

func ProjectModelThroughRelationGetter[T any](query func() *table.Table[T], midTable, firstKey, secondKey, secondLocalKey string) func(keys []any) map[string][]any {
	return func(keys []any) map[string][]any {
		var results = map[string][]any{}
		groupKey := fmt.Sprintf("%s.%s", midTable, firstKey)
		for key, values := range query().
			AddSelect(fmt.Sprintf("(%s) as _group_key", groupKey)).
			WhereIn(groupKey, keys).
			Join(midTable, fmt.Sprintf("%s.%s", midTable, secondLocalKey), "=", fmt.Sprintf("%s.%s", query().GetTableName(), secondKey)).
			Get().GroupBy("_group_key") {
			results[key] = collection.New(values).ToAnyArray()
		}
		return results
	}
}
func ProjectQueryWithExecutor(executor contracts.SqlExecutor) *table.Table[ProjectModel] {
	return ProjectQuery().SetExecutor(executor)
}

func ProjectQuery() *table.Table[ProjectModel] {
	return table.NewQuery(ProjectDefine.TableName, NewProjectModel).
		SetPrimaryKey("id").
		SetCreatedTimeColumn("created_at").
		SetUpdatedTimeColumn("updated_at").
		SetWiths(ProjectDefine.With...)
}

func (model *ProjectModel) Hidden(fields ...string) *ProjectModel {
	for _, field := range fields {
		if model._hidden == nil {
			model._hidden = map[string]struct{}{
				field: struct{}{},
			}
		} else {
			model._hidden[field] = struct{}{}
		}

	}

	return model
}

func (model *ProjectModel) Exists() bool {
	return ProjectQuery().Where("id", model.GetPrimaryKey()).Count() > 0
}

func (model *ProjectModel) Save() contracts.Exception {
	if model._update == nil {
		return nil
	}
	if ProjectDefine.Saving != nil {
		if err := ProjectDefine.Saving(model); err != nil {
			return err
		}
	}
	var err contracts.Exception
	var pk = model.GetPrimaryKey()
	if cast.ToUint64(pk) == 0 {
		pk, err = ProjectQuery().Where("id", model.GetPrimaryKey()).InsertGetIdE(model._update)
		if err == nil {
			model.SetId(cast.ToInt64(pk))
		}
	} else {
		_, err = ProjectQuery().Where("id", model.GetPrimaryKey()).UpdateE(model._update)
	}
	if err == nil {
		model._update = nil
		if ProjectDefine.Saved != nil {
			ProjectDefine.Saved(model)
		}
	}

	return err
}

func (model *ProjectModel) Set(fields contracts.Fields) {
	for key, value := range fields {

		switch key {
		case "id":
			switch v := value.(type) {
			case int64:
				model.SetId(v)
			case func() int64:
				model.SetId(v())
			case string:
				var vd int64
				err := json.Unmarshal([]byte(v), &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetId(vd)

			case []byte:
				var vd int64
				err := json.Unmarshal(v, &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetId(vd)

			default:
				model.SetId(cast.ToInt64(v))
			}
		case "uuid":
			switch v := value.(type) {
			case string:
				model.SetUuid(v)
			case func() string:
				model.SetUuid(v())
			case []byte:
				model.SetUuid(string(v))

			default:
				model.SetUuid(cast.ToString(v))
			}
		case "name":
			switch v := value.(type) {
			case string:
				model.SetName(v)
			case func() string:
				model.SetName(v())
			case []byte:
				model.SetName(string(v))

			default:
				model.SetName(cast.ToString(v))
			}
		case "creator_id":
			switch v := value.(type) {
			case int64:
				model.SetCreatorId(v)
			case func() int64:
				model.SetCreatorId(v())
			case string:
				var vd int64
				err := json.Unmarshal([]byte(v), &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetCreatorId(vd)

			case []byte:
				var vd int64
				err := json.Unmarshal(v, &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetCreatorId(vd)

			default:
				model.SetCreatorId(cast.ToInt64(v))
			}
		case "group_id":
			switch v := value.(type) {
			case int64:
				model.SetGroupId(v)
			case func() int64:
				model.SetGroupId(v())
			case string:
				var vd int64
				err := json.Unmarshal([]byte(v), &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetGroupId(vd)

			case []byte:
				var vd int64
				err := json.Unmarshal(v, &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetGroupId(vd)

			default:
				model.SetGroupId(cast.ToInt64(v))
			}
		case "key_id":
			switch v := value.(type) {
			case int64:
				model.SetKeyId(v)
			case func() int64:
				model.SetKeyId(v())
			case string:
				var vd int64
				err := json.Unmarshal([]byte(v), &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetKeyId(vd)

			case []byte:
				var vd int64
				err := json.Unmarshal(v, &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetKeyId(vd)

			default:
				model.SetKeyId(cast.ToInt64(v))
			}
		case "repo_address":
			switch v := value.(type) {
			case string:
				model.SetRepoAddress(v)
			case func() string:
				model.SetRepoAddress(v())
			case []byte:
				model.SetRepoAddress(string(v))

			default:
				model.SetRepoAddress(cast.ToString(v))
			}
		case "project_path":
			switch v := value.(type) {
			case string:
				model.SetProjectPath(v)
			case func() string:
				model.SetProjectPath(v())
			case []byte:
				model.SetProjectPath(string(v))

			default:
				model.SetProjectPath(cast.ToString(v))
			}
		case "default_branch":
			switch v := value.(type) {
			case string:
				model.SetDefaultBranch(v)
			case func() string:
				model.SetDefaultBranch(v())
			case []byte:
				model.SetDefaultBranch(string(v))

			default:
				model.SetDefaultBranch(cast.ToString(v))
			}
		case "settings":
			switch v := value.(type) {
			case string:
				model.SetSettings(v)
			case func() string:
				model.SetSettings(v())
			case []byte:
				model.SetSettings(string(v))

			default:
				model.SetSettings(cast.ToString(v))
			}
		case "created_at":
			switch v := value.(type) {
			case string:
				model.SetCreatedAt(v)
			case func() string:
				model.SetCreatedAt(v())
			case []byte:
				model.SetCreatedAt(string(v))

			default:
				model.SetCreatedAt(cast.ToString(v))
			}
		case "updated_at":
			switch v := value.(type) {
			case string:
				model.SetUpdatedAt(v)
			case func() string:
				model.SetUpdatedAt(v())
			case []byte:
				model.SetUpdatedAt(string(v))

			default:
				model.SetUpdatedAt(cast.ToString(v))
			}
		}

	}
}

func (model *ProjectModel) Only(key ...string) contracts.Fields {
	var fields = make(contracts.Fields)
	for _, k := range key {
		if k == "id" {
			fields[k] = model.GetId()
			continue
		}
		if k == "uuid" {
			fields[k] = model.GetUuid()
			continue
		}
		if k == "name" {
			fields[k] = model.GetName()
			continue
		}
		if k == "creator_id" {
			fields[k] = model.GetCreatorId()
			continue
		}
		if k == "group_id" {
			fields[k] = model.GetGroupId()
			continue
		}
		if k == "key_id" {
			fields[k] = model.GetKeyId()
			continue
		}
		if k == "repo_address" {
			fields[k] = model.GetRepoAddress()
			continue
		}
		if k == "project_path" {
			fields[k] = model.GetProjectPath()
			continue
		}
		if k == "default_branch" {
			fields[k] = model.GetDefaultBranch()
			continue
		}
		if k == "settings" {
			fields[k] = model.GetSettings()
			continue
		}
		if k == "created_at" {
			fields[k] = model.GetCreatedAt()
			continue
		}
		if k == "updated_at" {
			fields[k] = model.GetUpdatedAt()
			continue
		}

		if ProjectDefine.Appends[k] != nil {
			fields[k] = ProjectDefine.Appends[k](model)
		}
	}
	return fields
}

func (model *ProjectModel) Get(key string) any {
	switch key {
	case "id":
		return model.GetId()
	case "uuid":
		return model.GetUuid()
	case "name":
		return model.GetName()
	case "creator_id":
		return model.GetCreatorId()
	case "group_id":
		return model.GetGroupId()
	case "key_id":
		return model.GetKeyId()
	case "repo_address":
		return model.GetRepoAddress()
	case "project_path":
		return model.GetProjectPath()
	case "default_branch":
		return model.GetDefaultBranch()
	case "settings":
		return model.GetSettings()
	case "created_at":
		return model.GetCreatedAt()
	case "updated_at":
		return model.GetUpdatedAt()
	}

	if value, exists := model._append[key]; exists {
		return value
	}

	if fn, exists := ProjectDefine.Appends[key]; exists {
		model._append[key] = fn(model)
		return model._append[key]
	}

	switch contracts.RelationType(key) {
	}

	return nil
}

func (model *ProjectModel) Except(keys ...string) contracts.Fields {
	var excepts = map[string]struct{}{}
	for _, k := range keys {
		excepts[k] = struct{}{}
	}
	var fields = make(contracts.Fields)
	for key, value := range model.ToFields() {
		if _, ok := excepts[key]; ok {
			continue
		}
		fields[key] = value
	}
	return fields
}

func (model *ProjectModel) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}

	model.Hidden(ProjectDefine.Hidden...)

	fields := contracts.Fields{}
	if _, exists := model._hidden["id"]; !exists {
		fields["id"] = model.GetId()
	}
	if _, exists := model._hidden["uuid"]; !exists {
		fields["uuid"] = model.GetUuid()
	}
	if _, exists := model._hidden["name"]; !exists {
		fields["name"] = model.GetName()
	}
	if _, exists := model._hidden["creator_id"]; !exists {
		fields["creator_id"] = model.GetCreatorId()
	}
	if _, exists := model._hidden["group_id"]; !exists {
		fields["group_id"] = model.GetGroupId()
	}
	if _, exists := model._hidden["key_id"]; !exists {
		fields["key_id"] = model.GetKeyId()
	}
	if _, exists := model._hidden["repo_address"]; !exists {
		fields["repo_address"] = model.GetRepoAddress()
	}
	if _, exists := model._hidden["project_path"]; !exists {
		fields["project_path"] = model.GetProjectPath()
	}
	if _, exists := model._hidden["default_branch"]; !exists {
		fields["default_branch"] = model.GetDefaultBranch()
	}
	if _, exists := model._hidden["settings"]; !exists {
		fields["settings"] = model.GetSettings()
	}
	if _, exists := model._hidden["created_at"]; !exists {
		fields["created_at"] = model.GetCreatedAt()
	}
	if _, exists := model._hidden["updated_at"]; !exists {
		fields["updated_at"] = model.GetUpdatedAt()
	}

	for key := range ProjectDefine.Appends {
		value := model.Get(key)
		if fieldsProvider, ok := value.(contracts.FieldsProvider); ok {
			fields[key] = fieldsProvider.ToFields()
		} else {
			fields[key] = value
		}
	}

	for key := range model._relation_loaded {
		switch key {
		}
	}

	for key, value := range model._raw {
		_, hidden := model._hidden[key]
		if _, exists := fields[key]; !exists && !hidden {
			fields[key] = value
		}
	}

	return fields
}

func (model *ProjectModel) Update(fields contracts.Fields) contracts.Exception {

	if ProjectDefine.Updating != nil {
		if err := ProjectDefine.Updating(model, fields); err != nil {
			return err
		}
	}

	if model._update != nil {
		utils.MergeFields(model._update, fields)
	}

	_, err := ProjectQuery().Where("id", model.GetPrimaryKey()).UpdateE(fields)

	if err == nil {
		model.Set(fields)
		model._update = nil
		if ProjectDefine.Updated != nil {
			ProjectDefine.Updated(model, fields)
		}
	}

	return err
}

func (model *ProjectModel) Refresh() contracts.Exception {
	fields, err := table.ArrayQuery("projects").Where("id", model.GetPrimaryKey()).FirstE()
	if err != nil {
		return err
	}

	model.Set(*fields)
	return nil
}

func (model *ProjectModel) Delete() contracts.Exception {

	if ProjectDefine.Deleting != nil {
		if err := ProjectDefine.Deleting(model); err != nil {
			return err
		}
	}

	_, err := ProjectQuery().Where("id", model.GetPrimaryKey()).DeleteE()
	if err == nil && ProjectDefine.Deleted != nil {
		ProjectDefine.Deleted(model)
	}

	return err
}

func (model *ProjectModel) GetPrimaryKey() any {
	if ProjectDefine.PrimaryKeyGetter != nil {
		return ProjectDefine.PrimaryKeyGetter(model)
	}

	return model.Id
}

func (model *ProjectModel) GetId() int64 {
	if ProjectDefine.IdGetter != nil {
		return ProjectDefine.IdGetter(model, model.Id)
	}
	return model.Id
}

func (model *ProjectModel) SetId(value int64) {
	if ProjectDefine.IdSetter != nil {
		value = ProjectDefine.IdSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"id": value}
	} else {
		model._update["id"] = value
	}
	model.Id = value
}

func (model *ProjectModel) GetUuid() string {
	if ProjectDefine.UuidGetter != nil {
		return ProjectDefine.UuidGetter(model, model.Uuid)
	}
	return model.Uuid
}

func (model *ProjectModel) SetUuid(value string) {
	if ProjectDefine.UuidSetter != nil {
		value = ProjectDefine.UuidSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"uuid": value}
	} else {
		model._update["uuid"] = value
	}
	model.Uuid = value
}

func (model *ProjectModel) GetName() string {
	if ProjectDefine.NameGetter != nil {
		return ProjectDefine.NameGetter(model, model.Name)
	}
	return model.Name
}

func (model *ProjectModel) SetName(value string) {
	if ProjectDefine.NameSetter != nil {
		value = ProjectDefine.NameSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"name": value}
	} else {
		model._update["name"] = value
	}
	model.Name = value
}

func (model *ProjectModel) GetCreatorId() int64 {
	if ProjectDefine.CreatorIdGetter != nil {
		return ProjectDefine.CreatorIdGetter(model, model.CreatorId)
	}
	return model.CreatorId
}

func (model *ProjectModel) SetCreatorId(value int64) {
	if ProjectDefine.CreatorIdSetter != nil {
		value = ProjectDefine.CreatorIdSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"creator_id": value}
	} else {
		model._update["creator_id"] = value
	}
	model.CreatorId = value
}

func (model *ProjectModel) GetGroupId() int64 {
	if ProjectDefine.GroupIdGetter != nil {
		return ProjectDefine.GroupIdGetter(model, model.GroupId)
	}
	return model.GroupId
}

func (model *ProjectModel) SetGroupId(value int64) {
	if ProjectDefine.GroupIdSetter != nil {
		value = ProjectDefine.GroupIdSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"group_id": value}
	} else {
		model._update["group_id"] = value
	}
	model.GroupId = value
}

func (model *ProjectModel) GetKeyId() int64 {
	if ProjectDefine.KeyIdGetter != nil {
		return ProjectDefine.KeyIdGetter(model, model.KeyId)
	}
	return model.KeyId
}

func (model *ProjectModel) SetKeyId(value int64) {
	if ProjectDefine.KeyIdSetter != nil {
		value = ProjectDefine.KeyIdSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"key_id": value}
	} else {
		model._update["key_id"] = value
	}
	model.KeyId = value
}

func (model *ProjectModel) GetRepoAddress() string {
	if ProjectDefine.RepoAddressGetter != nil {
		return ProjectDefine.RepoAddressGetter(model, model.RepoAddress)
	}
	return model.RepoAddress
}

func (model *ProjectModel) SetRepoAddress(value string) {
	if ProjectDefine.RepoAddressSetter != nil {
		value = ProjectDefine.RepoAddressSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"repo_address": value}
	} else {
		model._update["repo_address"] = value
	}
	model.RepoAddress = value
}

func (model *ProjectModel) GetProjectPath() string {
	if ProjectDefine.ProjectPathGetter != nil {
		return ProjectDefine.ProjectPathGetter(model, model.ProjectPath)
	}
	return model.ProjectPath
}

func (model *ProjectModel) SetProjectPath(value string) {
	if ProjectDefine.ProjectPathSetter != nil {
		value = ProjectDefine.ProjectPathSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"project_path": value}
	} else {
		model._update["project_path"] = value
	}
	model.ProjectPath = value
}

func (model *ProjectModel) GetDefaultBranch() string {
	if ProjectDefine.DefaultBranchGetter != nil {
		return ProjectDefine.DefaultBranchGetter(model, model.DefaultBranch)
	}
	return model.DefaultBranch
}

func (model *ProjectModel) SetDefaultBranch(value string) {
	if ProjectDefine.DefaultBranchSetter != nil {
		value = ProjectDefine.DefaultBranchSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"default_branch": value}
	} else {
		model._update["default_branch"] = value
	}
	model.DefaultBranch = value
}

func (model *ProjectModel) GetSettings() string {
	if ProjectDefine.SettingsGetter != nil {
		return ProjectDefine.SettingsGetter(model, model.Settings)
	}
	return model.Settings
}

func (model *ProjectModel) SetSettings(value string) {
	if ProjectDefine.SettingsSetter != nil {
		value = ProjectDefine.SettingsSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"settings": value}
	} else {
		model._update["settings"] = value
	}
	model.Settings = value
}

func (model *ProjectModel) GetCreatedAt() string {
	if ProjectDefine.CreatedAtGetter != nil {
		return ProjectDefine.CreatedAtGetter(model, model.CreatedAt)
	}
	return model.CreatedAt
}

func (model *ProjectModel) SetCreatedAt(value string) {
	if ProjectDefine.CreatedAtSetter != nil {
		value = ProjectDefine.CreatedAtSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"created_at": value}
	} else {
		model._update["created_at"] = value
	}
	model.CreatedAt = value
}

func (model *ProjectModel) GetUpdatedAt() string {
	if ProjectDefine.UpdatedAtGetter != nil {
		return ProjectDefine.UpdatedAtGetter(model, model.UpdatedAt)
	}
	return model.UpdatedAt
}

func (model *ProjectModel) SetUpdatedAt(value string) {
	if ProjectDefine.UpdatedAtSetter != nil {
		value = ProjectDefine.UpdatedAtSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"updated_at": value}
	} else {
		model._update["updated_at"] = value
	}
	model.UpdatedAt = value
}


================================================
FILE: app/models/User_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/user.proto
// 
package models

import (
	"encoding/json"
	"fmt"
	"github.com/goal-web/collection"
	"github.com/goal-web/contracts"
	"github.com/goal-web/database/table"
	user "github.com/goal-web/goal/app/models/user"
	"github.com/goal-web/migration/migrate"
	"github.com/goal-web/supports/logs"
	"github.com/goal-web/supports/utils"
	"github.com/spf13/cast"
)

var ()

// UserModel
// 用户注释
// @authenticatable
// @timestamps
type UserModel struct {
	Id int64 `json:"id" query:"id" form:"id" db:"id;type:BIGINT;not null;primary key;AUTO_INCREMENT;"`

	Name string `json:"name" query:"name" form:"name" db:"name;type:VARCHAR(255);not null;"`

	Avatar string `json:"avatar" query:"avatar" form:"avatar" db:"avatar;type:VARCHAR(255);not null;"`
	//@index
	//@goTag:db:"open_id;type:varchar(255);default 'xxasdasdsx'"
	OpenId string `db:"open_id;type:varchar(255);default 'xxasdasdsx'" json:"open_id" query:"open_id" form:"open_id"`

	WechatInfo *user.WechatInfoData `json:"wechat_info" query:"wechat_info" form:"wechat_info" db:"wechat_info;type:json;not null;"`

	Channel string `json:"channel" query:"channel" form:"channel" db:"channel;type:VARCHAR(255);not null;"`
	//@hidden
	Password string `json:"password" query:"password" form:"password" db:"password;type:VARCHAR(255);not null;"`

	CreatedAt string `json:"created_at" query:"created_at" form:"created_at" db:"created_at;type:timestamp;default CURRENT_TIMESTAMP;"`

	UpdatedAt string `json:"updated_at" query:"updated_at" form:"updated_at" db:"updated_at;type:timestamp;DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;"`

	_raw    contracts.Fields
	_update contracts.Fields
	_append contracts.Fields
	_hidden map[string]struct{}

	_relation_loaded map[contracts.RelationType]struct{}
}

var UserDefine UserStatic

type UserStatic struct {
	TableName        string
	Hidden           []string
	Indexes          []string
	With             []contracts.RelationType
	Appends          map[string]func(model *UserModel) any
	IdGetter         func(model *UserModel, raw int64) int64
	IdSetter         func(model *UserModel, raw int64) int64
	NameGetter       func(model *UserModel, raw string) string
	NameSetter       func(model *UserModel, raw string) string
	AvatarGetter     func(model *UserModel, raw string) string
	AvatarSetter     func(model *UserModel, raw string) string
	OpenIdGetter     func(model *UserModel, raw string) string
	OpenIdSetter     func(model *UserModel, raw string) string
	WechatInfoGetter func(model *UserModel, raw *user.WechatInfoData) *user.WechatInfoData
	WechatInfoSetter func(model *UserModel, raw *user.WechatInfoData) *user.WechatInfoData
	ChannelGetter    func(model *UserModel, raw string) string
	ChannelSetter    func(model *UserModel, raw string) string
	PasswordGetter   func(model *UserModel, raw string) string
	PasswordSetter   func(model *UserModel, raw string) string
	CreatedAtGetter  func(model *UserModel, raw string) string
	CreatedAtSetter  func(model *UserModel, raw string) string
	UpdatedAtGetter  func(model *UserModel, raw string) string
	UpdatedAtSetter  func(model *UserModel, raw string) string

	Saving           func(model *UserModel) contracts.Exception
	Saved            func(model *UserModel)
	Updating         func(model *UserModel, fields contracts.Fields) contracts.Exception
	Updated          func(model *UserModel, fields contracts.Fields)
	Deleting         func(model *UserModel) contracts.Exception
	Deleted          func(model *UserModel)
	PrimaryKeyGetter func(model *UserModel) any
}

func UserMigrator() migrate.Migrator {
	return func(executor contracts.SqlExecutor) contracts.Exception {
		return migrate.Migrate(UserDefine.TableName, UserDefine.Indexes, UserModel{}, executor)
	}
}

func init() {
	UserDefine.TableName = "users"
	UserDefine.Appends = make(map[string]func(model *UserModel) any)
	UserDefine.Hidden = append(
		UserDefine.Hidden,
		"password",
	)
	UserDefine.Indexes = append(
		UserDefine.Indexes,
		"index;open_id_idx;(open_id)",
	)
}

func NewUserModel(fields contracts.Fields) *UserModel {
	var model = UserModel{
		_raw: fields,
	}
	model.Set(fields)
	return &model
}

func UserModelSingleRelationSetter[T any](key contracts.RelationType) func(item *UserModel, value []any) {
	return func(item *UserModel, values []any) {
		var value T
		if len(values) > 0 {
			value = values[0].(T)
		}
		item.Set(contracts.Fields{
			string(key): value,
		})
	}
}
func UserModelMultiRelationSetter[T any](key contracts.RelationType) func(item *UserModel, value []any) {
	return func(model *UserModel, value []any) {
		var results []T
		for _, item := range value {
			results = append(results, item.(T))
		}
		model.Set(contracts.Fields{string(key): results})
	}
}

func UserModelLocalKeyGetter(key string) func(item *UserModel) any {
	return func(item *UserModel) any {
		return item.Get(key)
	}
}

func UserModelRelationGetter[T any](query func() *table.Table[T], foreignKey string) func(keys []any) map[string][]any {
	return func(keys []any) map[string][]any {
		var results = map[string][]any{}
		for key, values := range query().WhereIn(foreignKey, keys).Get().GroupBy(foreignKey) {
			results[key] = collection.New(values).ToAnyArray()
		}
		return results
	}
}

func UserModelThroughRelationGetter[T any](query func() *table.Table[T], midTable, firstKey, secondKey, secondLocalKey string) func(keys []any) map[string][]any {
	return func(keys []any) map[string][]any {
		var results = map[string][]any{}
		groupKey := fmt.Sprintf("%s.%s", midTable, firstKey)
		for key, values := range query().
			AddSelect(fmt.Sprintf("(%s) as _group_key", groupKey)).
			WhereIn(groupKey, keys).
			Join(midTable, fmt.Sprintf("%s.%s", midTable, secondLocalKey), "=", fmt.Sprintf("%s.%s", query().GetTableName(), secondKey)).
			Get().GroupBy("_group_key") {
			results[key] = collection.New(values).ToAnyArray()
		}
		return results
	}
}
func UserQueryWithExecutor(executor contracts.SqlExecutor) *table.Table[UserModel] {
	return UserQuery().SetExecutor(executor)
}

func UserQuery() *table.Table[UserModel] {
	return table.NewQuery(UserDefine.TableName, NewUserModel).
		SetPrimaryKey("id").
		SetCreatedTimeColumn("created_at").
		SetUpdatedTimeColumn("updated_at").
		SetWiths(UserDefine.With...)
}

func (model *UserModel) Hidden(fields ...string) *UserModel {
	for _, field := range fields {
		if model._hidden == nil {
			model._hidden = map[string]struct{}{
				field: struct{}{},
			}
		} else {
			model._hidden[field] = struct{}{}
		}

	}

	return model
}

func (model *UserModel) Exists() bool {
	return UserQuery().Where("id", model.GetPrimaryKey()).Count() > 0
}

func (model *UserModel) Save() contracts.Exception {
	if model._update == nil {
		return nil
	}
	if UserDefine.Saving != nil {
		if err := UserDefine.Saving(model); err != nil {
			return err
		}
	}
	var err contracts.Exception
	var pk = model.GetPrimaryKey()
	if cast.ToUint64(pk) == 0 {
		pk, err = UserQuery().Where("id", model.GetPrimaryKey()).InsertGetIdE(model._update)
		if err == nil {
			model.SetId(cast.ToInt64(pk))
		}
	} else {
		_, err = UserQuery().Where("id", model.GetPrimaryKey()).UpdateE(model._update)
	}
	if err == nil {
		model._update = nil
		if UserDefine.Saved != nil {
			UserDefine.Saved(model)
		}
	}

	return err
}

func (model *UserModel) Set(fields contracts.Fields) {
	for key, value := range fields {

		switch key {
		case "id":
			switch v := value.(type) {
			case int64:
				model.SetId(v)
			case func() int64:
				model.SetId(v())
			case string:
				var vd int64
				err := json.Unmarshal([]byte(v), &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetId(vd)

			case []byte:
				var vd int64
				err := json.Unmarshal(v, &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetId(vd)

			default:
				model.SetId(cast.ToInt64(v))
			}
		case "name":
			switch v := value.(type) {
			case string:
				model.SetName(v)
			case func() string:
				model.SetName(v())
			case []byte:
				model.SetName(string(v))

			default:
				model.SetName(cast.ToString(v))
			}
		case "avatar":
			switch v := value.(type) {
			case string:
				model.SetAvatar(v)
			case func() string:
				model.SetAvatar(v())
			case []byte:
				model.SetAvatar(string(v))

			default:
				model.SetAvatar(cast.ToString(v))
			}
		case "open_id":
			switch v := value.(type) {
			case string:
				model.SetOpenId(v)
			case func() string:
				model.SetOpenId(v())
			case []byte:
				model.SetOpenId(string(v))

			default:
				model.SetOpenId(cast.ToString(v))
			}
		case "wechat_info":
			switch v := value.(type) {
			case *user.WechatInfoData:
				model.SetWechatInfo(v)
			case func() *user.WechatInfoData:
				model.SetWechatInfo(v())
			case string:
				var vd *user.WechatInfoData
				err := json.Unmarshal([]byte(v), &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetWechatInfo(vd)

			case []byte:
				var vd *user.WechatInfoData
				err := json.Unmarshal(v, &vd)
				if err != nil {
					logs.Default().Warn("Failed to Parse field " + key)
					continue
				}
				model.SetWechatInfo(vd)

			}
		case "channel":
			switch v := value.(type) {
			case string:
				model.SetChannel(v)
			case func() string:
				model.SetChannel(v())
			case []byte:
				model.SetChannel(string(v))

			default:
				model.SetChannel(cast.ToString(v))
			}
		case "password":
			switch v := value.(type) {
			case string:
				model.SetPassword(v)
			case func() string:
				model.SetPassword(v())
			case []byte:
				model.SetPassword(string(v))

			default:
				model.SetPassword(cast.ToString(v))
			}
		case "created_at":
			switch v := value.(type) {
			case string:
				model.SetCreatedAt(v)
			case func() string:
				model.SetCreatedAt(v())
			case []byte:
				model.SetCreatedAt(string(v))

			default:
				model.SetCreatedAt(cast.ToString(v))
			}
		case "updated_at":
			switch v := value.(type) {
			case string:
				model.SetUpdatedAt(v)
			case func() string:
				model.SetUpdatedAt(v())
			case []byte:
				model.SetUpdatedAt(string(v))

			default:
				model.SetUpdatedAt(cast.ToString(v))
			}
		}

	}
}

func (model *UserModel) Only(key ...string) contracts.Fields {
	var fields = make(contracts.Fields)
	for _, k := range key {
		if k == "id" {
			fields[k] = model.GetId()
			continue
		}
		if k == "name" {
			fields[k] = model.GetName()
			continue
		}
		if k == "avatar" {
			fields[k] = model.GetAvatar()
			continue
		}
		if k == "open_id" {
			fields[k] = model.GetOpenId()
			continue
		}
		if k == "wechat_info" {
			fields[k] = model.GetWechatInfo()
			continue
		}
		if k == "channel" {
			fields[k] = model.GetChannel()
			continue
		}
		if k == "password" {
			fields[k] = model.GetPassword()
			continue
		}
		if k == "created_at" {
			fields[k] = model.GetCreatedAt()
			continue
		}
		if k == "updated_at" {
			fields[k] = model.GetUpdatedAt()
			continue
		}

		if UserDefine.Appends[k] != nil {
			fields[k] = UserDefine.Appends[k](model)
		}
	}
	return fields
}

func (model *UserModel) Get(key string) any {
	switch key {
	case "id":
		return model.GetId()
	case "name":
		return model.GetName()
	case "avatar":
		return model.GetAvatar()
	case "open_id":
		return model.GetOpenId()
	case "wechat_info":
		return model.GetWechatInfo()
	case "channel":
		return model.GetChannel()
	case "password":
		return model.GetPassword()
	case "created_at":
		return model.GetCreatedAt()
	case "updated_at":
		return model.GetUpdatedAt()
	}

	if value, exists := model._append[key]; exists {
		return value
	}

	if fn, exists := UserDefine.Appends[key]; exists {
		model._append[key] = fn(model)
		return model._append[key]
	}

	switch contracts.RelationType(key) {
	}

	return nil
}

func (model *UserModel) Except(keys ...string) contracts.Fields {
	var excepts = map[string]struct{}{}
	for _, k := range keys {
		excepts[k] = struct{}{}
	}
	var fields = make(contracts.Fields)
	for key, value := range model.ToFields() {
		if _, ok := excepts[key]; ok {
			continue
		}
		fields[key] = value
	}
	return fields
}

func (model *UserModel) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}

	model.Hidden(UserDefine.Hidden...)

	fields := contracts.Fields{}
	if _, exists := model._hidden["id"]; !exists {
		fields["id"] = model.GetId()
	}
	if _, exists := model._hidden["name"]; !exists {
		fields["name"] = model.GetName()
	}
	if _, exists := model._hidden["avatar"]; !exists {
		fields["avatar"] = model.GetAvatar()
	}
	if _, exists := model._hidden["open_id"]; !exists {
		fields["open_id"] = model.GetOpenId()
	}
	if _, exists := model._hidden["wechat_info"]; !exists {
		fields["wechat_info"] = model.GetWechatInfo()
	}
	if _, exists := model._hidden["channel"]; !exists {
		fields["channel"] = model.GetChannel()
	}
	if _, exists := model._hidden["password"]; !exists {
		fields["password"] = model.GetPassword()
	}
	if _, exists := model._hidden["created_at"]; !exists {
		fields["created_at"] = model.GetCreatedAt()
	}
	if _, exists := model._hidden["updated_at"]; !exists {
		fields["updated_at"] = model.GetUpdatedAt()
	}

	for key := range UserDefine.Appends {
		value := model.Get(key)
		if fieldsProvider, ok := value.(contracts.FieldsProvider); ok {
			fields[key] = fieldsProvider.ToFields()
		} else {
			fields[key] = value
		}
	}

	for key := range model._relation_loaded {
		switch key {
		}
	}

	for key, value := range model._raw {
		_, hidden := model._hidden[key]
		if _, exists := fields[key]; !exists && !hidden {
			fields[key] = value
		}
	}

	return fields
}

func (model *UserModel) Update(fields contracts.Fields) contracts.Exception {

	if UserDefine.Updating != nil {
		if err := UserDefine.Updating(model, fields); err != nil {
			return err
		}
	}

	if model._update != nil {
		utils.MergeFields(model._update, fields)
	}

	_, err := UserQuery().Where("id", model.GetPrimaryKey()).UpdateE(fields)

	if err == nil {
		model.Set(fields)
		model._update = nil
		if UserDefine.Updated != nil {
			UserDefine.Updated(model, fields)
		}
	}

	return err
}

func (model *UserModel) Refresh() contracts.Exception {
	fields, err := table.ArrayQuery("users").Where("id", model.GetPrimaryKey()).FirstE()
	if err != nil {
		return err
	}

	model.Set(*fields)
	return nil
}

func (model *UserModel) Delete() contracts.Exception {

	if UserDefine.Deleting != nil {
		if err := UserDefine.Deleting(model); err != nil {
			return err
		}
	}

	_, err := UserQuery().Where("id", model.GetPrimaryKey()).DeleteE()
	if err == nil && UserDefine.Deleted != nil {
		UserDefine.Deleted(model)
	}

	return err
}

func (model *UserModel) GetPrimaryKey() any {
	if UserDefine.PrimaryKeyGetter != nil {
		return UserDefine.PrimaryKeyGetter(model)
	}

	return model.Id
}
func (model *UserModel) GetAuthenticatableKey() string {
	return fmt.Sprintf("%v", model.GetPrimaryKey())
}

func UserAuthProvider(identify string) contracts.Authenticatable {
	return UserQuery().Find(identify)
}

func (model *UserModel) GetId() int64 {
	if UserDefine.IdGetter != nil {
		return UserDefine.IdGetter(model, model.Id)
	}
	return model.Id
}

func (model *UserModel) SetId(value int64) {
	if UserDefine.IdSetter != nil {
		value = UserDefine.IdSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"id": value}
	} else {
		model._update["id"] = value
	}
	model.Id = value
}

func (model *UserModel) GetName() string {
	if UserDefine.NameGetter != nil {
		return UserDefine.NameGetter(model, model.Name)
	}
	return model.Name
}

func (model *UserModel) SetName(value string) {
	if UserDefine.NameSetter != nil {
		value = UserDefine.NameSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"name": value}
	} else {
		model._update["name"] = value
	}
	model.Name = value
}

func (model *UserModel) GetAvatar() string {
	if UserDefine.AvatarGetter != nil {
		return UserDefine.AvatarGetter(model, model.Avatar)
	}
	return model.Avatar
}

func (model *UserModel) SetAvatar(value string) {
	if UserDefine.AvatarSetter != nil {
		value = UserDefine.AvatarSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"avatar": value}
	} else {
		model._update["avatar"] = value
	}
	model.Avatar = value
}

func (model *UserModel) GetOpenId() string {
	if UserDefine.OpenIdGetter != nil {
		return UserDefine.OpenIdGetter(model, model.OpenId)
	}
	return model.OpenId
}

func (model *UserModel) SetOpenId(value string) {
	if UserDefine.OpenIdSetter != nil {
		value = UserDefine.OpenIdSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"open_id": value}
	} else {
		model._update["open_id"] = value
	}
	model.OpenId = value
}

func (model *UserModel) GetWechatInfo() *user.WechatInfoData {
	if UserDefine.WechatInfoGetter != nil {
		return UserDefine.WechatInfoGetter(model, model.WechatInfo)
	}
	return model.WechatInfo
}

func (model *UserModel) SetWechatInfo(value *user.WechatInfoData) {
	if UserDefine.WechatInfoSetter != nil {
		value = UserDefine.WechatInfoSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"wechat_info": value}
	} else {
		model._update["wechat_info"] = value
	}
	model.WechatInfo = value
}

func (model *UserModel) GetChannel() string {
	if UserDefine.ChannelGetter != nil {
		return UserDefine.ChannelGetter(model, model.Channel)
	}
	return model.Channel
}

func (model *UserModel) SetChannel(value string) {
	if UserDefine.ChannelSetter != nil {
		value = UserDefine.ChannelSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"channel": value}
	} else {
		model._update["channel"] = value
	}
	model.Channel = value
}

func (model *UserModel) GetPassword() string {
	if UserDefine.PasswordGetter != nil {
		return UserDefine.PasswordGetter(model, model.Password)
	}
	return model.Password
}

func (model *UserModel) SetPassword(value string) {
	if UserDefine.PasswordSetter != nil {
		value = UserDefine.PasswordSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"password": value}
	} else {
		model._update["password"] = value
	}
	model.Password = value
}

func (model *UserModel) GetCreatedAt() string {
	if UserDefine.CreatedAtGetter != nil {
		return UserDefine.CreatedAtGetter(model, model.CreatedAt)
	}
	return model.CreatedAt
}

func (model *UserModel) SetCreatedAt(value string) {
	if UserDefine.CreatedAtSetter != nil {
		value = UserDefine.CreatedAtSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"created_at": value}
	} else {
		model._update["created_at"] = value
	}
	model.CreatedAt = value
}

func (model *UserModel) GetUpdatedAt() string {
	if UserDefine.UpdatedAtGetter != nil {
		return UserDefine.UpdatedAtGetter(model, model.UpdatedAt)
	}
	return model.UpdatedAt
}

func (model *UserModel) SetUpdatedAt(value string) {
	if UserDefine.UpdatedAtSetter != nil {
		value = UserDefine.UpdatedAtSetter(model, value)
	}

	if model._update == nil {
		model._update = contracts.Fields{"updated_at": value}
	} else {
		model._update["updated_at"] = value
	}
	model.UpdatedAt = value
}


================================================
FILE: app/models/project/GetProjectRessult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:21:38
// source: pro/Project.proto
// 
package project

import (
	models "github.com/goal-web/goal/app/models"
)

type GetProjectRessult struct {
	Project models.ProjectModel `json:"project" query:"project" form:"project"`
}


================================================
FILE: app/models/project.go
================================================
package models

func init() {
	ProjectDefine.Appends = map[string]func(model *ProjectModel) any{
		"id-plus-1": func(model *ProjectModel) any {
			return model.Id + 0
		},
	}
}


================================================
FILE: app/models/user/WechatInfoData_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/user.proto
// 
package user

import ()

type WechatInfoData struct {
	City      string `json:"city" query:"city" form:"city"`
	Gender    int64  `json:"gender" query:"gender" form:"gender"`
	OpenId    string `json:"open_id" query:"open_id" form:"open_id"`
	Country   string `json:"country" query:"country" form:"country"`
	Language  string `json:"language" query:"language" form:"language"`
	Nickname  string `json:"nickname" query:"nickname" form:"nickname"`
	Province  string `json:"province" query:"province" form:"province"`
	AvatarUrl string `json:"avatar_url" query:"avatar_url" form:"avatar_url"`
}


================================================
FILE: app/providers/app.go
================================================
package providers

import (
	"github.com/goal-web/application"
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/console"
	"github.com/goal-web/goal/app/models"
	"github.com/goal-web/migration/migrate"
	"github.com/golang-module/carbon/v2"
)

type appServiceProvider struct {
	serviceProviders []contracts.ServiceProvider
}

func NewApp() contracts.ServiceProvider {
	return &appServiceProvider{
		serviceProviders: []contracts.ServiceProvider{
			NewConsoleService(
				console.Commands,
				console.Schedule,
			),
		},
	}
}

func (app appServiceProvider) Register(instance contracts.Application) {
	instance.RegisterServices(app.serviceProviders...)

	instance.Call(func(config contracts.Config, dispatcher contracts.EventDispatcher, factory contracts.DBFactory) {
		appConfig := config.Get("app").(application.Config)
		carbon.SetLocale(appConfig.Locale)
		carbon.SetTimezone(appConfig.Timezone)
		instance.Instance("app.env", appConfig.Env)

		migrate.Auto(
			factory,
			models.UserMigrator(),
			models.ProjectMigrator(),
		)
	})
}

func (app appServiceProvider) Start() error {
	return nil
}

func (app appServiceProvider) Stop() {
}


================================================
FILE: app/providers/console.go
================================================
package providers

import (
	"github.com/goal-web/contracts"
)

type Console struct {
	Commands []contracts.CommandProvider
	Schedule func(schedule contracts.Schedule)
}

func NewConsoleService(commands []contracts.CommandProvider, schedule func(schedule2 contracts.Schedule)) contracts.ServiceProvider {
	return Console{
		Commands: commands,
		Schedule: schedule,
	}
}

func (c Console) Register(application contracts.Application) {
	application.Call(func(console contracts.Console, schedule contracts.Schedule) {
		for _, provider := range c.Commands {
			console.RegisterCommand(provider)
		}

		c.Schedule(schedule)
	})
}

func (c Console) Start() error {
	return nil
}

func (c Console) Stop() {
}


================================================
FILE: app/providers/events.go
================================================
package providers

import (
	"github.com/goal-web/contracts"
	events2 "github.com/goal-web/database/events"
	"github.com/goal-web/goal/app/listeners"
)

type EventsServiceProvider struct {
	listeners map[contracts.Event][]contracts.EventListener
}

func NewEvents() contracts.ServiceProvider {
	return &EventsServiceProvider{
		listeners: map[contracts.Event][]contracts.EventListener{
			&events2.QueryExecuted{}: {listeners.DebugQuery{}},
		},
	}
}

func (provider EventsServiceProvider) Stop() {

}

func (provider EventsServiceProvider) Start() error {
	return nil
}

func (provider EventsServiceProvider) Register(container contracts.Application) {
	container.Call(func(dispatcher contracts.EventDispatcher) {
		for event, items := range provider.listeners {
			for _, listener := range items {
				dispatcher.Register(event.Event(), listener)
			}
		}
	})
}


================================================
FILE: app/requests/project/CreateProject_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type CreateProjectReq struct {
	Uuid          string `json:"uuid" query:"uuid" form:"uuid"`
	Name          string `json:"name" query:"name" form:"name"`
	CreatorId     int64  `json:"creator_id" query:"creator_id" form:"creator_id"`
	GroupId       int64  `json:"group_id" query:"group_id" form:"group_id"`
	KeyId         int64  `json:"key_id" query:"key_id" form:"key_id"`
	RepoAddress   string `json:"repo_address" query:"repo_address" form:"repo_address"`
	ProjectPath   string `json:"project_path" query:"project_path" form:"project_path"`
	DefaultBranch string `json:"default_branch" query:"default_branch" form:"default_branch"`
	Settings      string `json:"settings" query:"settings" form:"settings"`
}

func (model *CreateProjectReq) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}
	fields := contracts.Fields{
		"uuid":           model.Uuid,
		"name":           model.Name,
		"creator_id":     model.CreatorId,
		"group_id":       model.GroupId,
		"key_id":         model.KeyId,
		"repo_address":   model.RepoAddress,
		"project_path":   model.ProjectPath,
		"default_branch": model.DefaultBranch,
		"settings":       model.Settings,
	}
	return fields
}


================================================
FILE: app/requests/project/DeleteProject_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type DeleteProjectReq struct {
	Id string `json:"id" query:"id" form:"id"`
}

func (model *DeleteProjectReq) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}
	fields := contracts.Fields{
		"id": model.Id,
	}
	return fields
}


================================================
FILE: app/requests/project/GetProject_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type GetProjectReq struct {
	Id string `json:"id" query:"id" form:"id"`
}

func (model *GetProjectReq) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}
	fields := contracts.Fields{
		"id": model.Id,
	}
	return fields
}


================================================
FILE: app/requests/project/ListProjects_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type ListProjectsReq struct {
	Page    int64 `json:"page" query:"page" form:"page"`
	PerPage int64 `json:"per_page" query:"per_page" form:"per_page"`
}

func (model *ListProjectsReq) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}
	fields := contracts.Fields{
		"page":     model.Page,
		"per_page": model.PerPage,
	}
	return fields
}


================================================
FILE: app/requests/project/UpdateProject_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type UpdateProjectReq struct {
	Id            int64  `json:"id" query:"id" form:"id"`
	Uuid          string `json:"uuid" query:"uuid" form:"uuid"`
	Name          string `json:"name" query:"name" form:"name"`
	CreatorId     int64  `json:"creator_id" query:"creator_id" form:"creator_id"`
	GroupId       int64  `json:"group_id" query:"group_id" form:"group_id"`
	KeyId         int64  `json:"key_id" query:"key_id" form:"key_id"`
	RepoAddress   string `json:"repo_address" query:"repo_address" form:"repo_address"`
	ProjectPath   string `json:"project_path" query:"project_path" form:"project_path"`
	DefaultBranch string `json:"default_branch" query:"default_branch" form:"default_branch"`
	Settings      string `json:"settings" query:"settings" form:"settings"`
}

func (model *UpdateProjectReq) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}
	fields := contracts.Fields{
		"id":             model.Id,
		"uuid":           model.Uuid,
		"name":           model.Name,
		"creator_id":     model.CreatorId,
		"group_id":       model.GroupId,
		"key_id":         model.KeyId,
		"repo_address":   model.RepoAddress,
		"project_path":   model.ProjectPath,
		"default_branch": model.DefaultBranch,
		"settings":       model.Settings,
	}
	return fields
}


================================================
FILE: app/requests/user/LoginByWxCode_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/user.proto
// 
package user

import (
	"github.com/goal-web/contracts"
)

type LoginByWxCodeReq struct {
	Code string `json:"code" query:"code" form:"code"`
}

func (model *LoginByWxCodeReq) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}
	fields := contracts.Fields{
		"code": model.Code,
	}
	return fields
}


================================================
FILE: app/requests/user/LoginByWxInfo_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/user.proto
// 
package user

import (
	"github.com/goal-web/contracts"
)

type LoginByWxInfoReq struct {
	Iv            string `json:"iv" query:"iv" form:"iv"`
	SessionKey    string `json:"sessionKey" query:"sessionKey" form:"sessionKey"`
	EncryptedData string `json:"encryptedData" query:"encryptedData" form:"encryptedData"`
}

func (model *LoginByWxInfoReq) ToFields() contracts.Fields {
	if model == nil {
		return nil
	}
	fields := contracts.Fields{
		"iv":            model.Iv,
		"sessionKey":    model.SessionKey,
		"encryptedData": model.EncryptedData,
	}
	return fields
}


================================================
FILE: app/response/utils.go
================================================
package response

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/enums"
	"github.com/goal-web/goal/app/results"
)

func ParseReqErr(err error) any {
	return results.ResponseResult{
		Message:    err.Error(),
		Code:       int32(enums.CodeParseReqErr),
		ErrMessage: enums.CodeParseReqErr.Message(),
		Data:       nil,
	}
}

func InvalidReq(err error) any {
	return results.ResponseResult{
		Message:    err.Error(),
		Code:       int32(enums.CodeParseReqErr),
		ErrMessage: enums.CodeParseReqErr.Message(),
		Data:       nil,
	}
}

func BizErr(err error) any {
	return results.ResponseResult{
		Message:    err.Error(),
		Code:       int32(enums.CodeBizErr),
		ErrMessage: enums.CodeBizErr.Message(),
		Data:       nil,
	}
}

func Success(data any) any {
	result := results.ResponseResult{
		Message:    "",
		Code:       int32(enums.CodeSuccess),
		ErrMessage: enums.CodeSuccess.Message(),
	}

	if fieldsProvider, ok := data.(contracts.FieldsProvider); ok {
		result.Data = fieldsProvider.ToFields()
	} else {
		result.Data = data
	}

	return result
}


================================================
FILE: app/results/ResponseResult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/common.proto
// 
package results

import (
	"github.com/goal-web/contracts"
)

type ResponseResult struct {
	Code       int32  `json:"code" query:"code" form:"code"`
	ErrMessage string `json:"err_message" query:"err_message" form:"err_message"`
	Message    string `json:"message" query:"message" form:"message"`
	Data       any    `json:"data" query:"data" form:"data"`
}

func (result *ResponseResult) ToFields() contracts.Fields {

	fields := contracts.Fields{
		"code":        result.Code,
		"err_message": result.ErrMessage,
		"message":     result.Message,
		"data":        result.Data,
	}

	return fields
}


================================================
FILE: app/results/project/CreateProjectResult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type CreateProjectResult struct {
	Code string `json:"code" query:"code" form:"code"`
}

func (result *CreateProjectResult) ToFields() contracts.Fields {

	fields := contracts.Fields{
		"code": result.Code,
	}

	return fields
}


================================================
FILE: app/results/project/DeleteProjectResult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type DeleteProjectResult struct {
	Code string `json:"code" query:"code" form:"code"`
}

func (result *DeleteProjectResult) ToFields() contracts.Fields {

	fields := contracts.Fields{
		"code": result.Code,
	}

	return fields
}


================================================
FILE: app/results/project/GetProjectResult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
	models "github.com/goal-web/goal/app/models"
)

type GetProjectResult struct {
	Project models.ProjectModel `json:"project" query:"project" form:"project"`
}

func (result *GetProjectResult) ToFields() contracts.Fields {

	fields := contracts.Fields{
		"project": result.Project,
	}

	return fields
}


================================================
FILE: app/results/project/ListProjectsResult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
	models "github.com/goal-web/goal/app/models"
)

type ListProjectsResult struct {
	Total    int64                  `json:"total" query:"total" form:"total"`
	Projects []*models.ProjectModel `json:"projects" query:"projects" form:"projects"`
}

func (result *ListProjectsResult) ToFields() contracts.Fields {

	fields := contracts.Fields{
		"total":    result.Total,
		"projects": result.Projects,
	}
	projectsList := make([]contracts.Fields, len(result.Projects))
	for i, item := range result.Projects {
		projectsList[i] = item.ToFields()
	}
	fields["projects"] = projectsList

	return fields
}


================================================
FILE: app/results/project/UpdateProjectResult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
)

type UpdateProjectResult struct {
	Code string `json:"code" query:"code" form:"code"`
}

func (result *UpdateProjectResult) ToFields() contracts.Fields {

	fields := contracts.Fields{
		"code": result.Code,
	}

	return fields
}


================================================
FILE: app/results/user/LoginByWxResult_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/user.proto
// 
package user

import (
	"github.com/goal-web/contracts"
	models "github.com/goal-web/goal/app/models"
)

type LoginByWxResult struct {
	Token      string            `json:"token" query:"token" form:"token"`
	User       *models.UserModel `json:"user" query:"user" form:"user"`
	SessionKey string            `json:"sessionKey" query:"sessionKey" form:"sessionKey"`
}

func (result *LoginByWxResult) ToFields() contracts.Fields {

	fields := contracts.Fields{
		"token":      result.Token,
		"user":       result.User,
		"sessionKey": result.SessionKey,
	}

	return fields
}


================================================
FILE: app/services/project/Project_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/Project.proto
// 
package project

import (
	"github.com/goal-web/contracts"
	project "github.com/goal-web/goal/app/requests/project"
	project0 "github.com/goal-web/goal/app/results/project"
)

var ProjectServiceDefine ProjectServiceStatic

type ProjectServiceStatic struct {
	CreateProject func(req *project.CreateProjectReq, ctx contracts.Context) (*project0.CreateProjectResult, error)
	GetProject    func(req *project.GetProjectReq, ctx contracts.Context) (*project0.GetProjectResult, error)
	ListProjects  func(req *project.ListProjectsReq, ctx contracts.Context) (*project0.ListProjectsResult, error)
	UpdateProject func(req *project.UpdateProjectReq, ctx contracts.Context) (*project0.UpdateProjectResult, error)
	DeleteProject func(req *project.DeleteProjectReq, ctx contracts.Context) (*project0.DeleteProjectResult, error)
}

func ProjectServiceCreateProject(req *project.CreateProjectReq, ctx contracts.Context) (*project0.CreateProjectResult, error) {
	if ProjectServiceDefine.CreateProject != nil {
		return ProjectServiceDefine.CreateProject(req, ctx)
	}
	return nil, nil
}

func ProjectServiceGetProject(req *project.GetProjectReq, ctx contracts.Context) (*project0.GetProjectResult, error) {
	if ProjectServiceDefine.GetProject != nil {
		return ProjectServiceDefine.GetProject(req, ctx)
	}
	return nil, nil
}

func ProjectServiceListProjects(req *project.ListProjectsReq, ctx contracts.Context) (*project0.ListProjectsResult, error) {
	if ProjectServiceDefine.ListProjects != nil {
		return ProjectServiceDefine.ListProjects(req, ctx)
	}
	return nil, nil
}

func ProjectServiceUpdateProject(req *project.UpdateProjectReq, ctx contracts.Context) (*project0.UpdateProjectResult, error) {
	if ProjectServiceDefine.UpdateProject != nil {
		return ProjectServiceDefine.UpdateProject(req, ctx)
	}
	return nil, nil
}

func ProjectServiceDeleteProject(req *project.DeleteProjectReq, ctx contracts.Context) (*project0.DeleteProjectResult, error) {
	if ProjectServiceDefine.DeleteProject != nil {
		return ProjectServiceDefine.DeleteProject(req, ctx)
	}
	return nil, nil
}


================================================
FILE: app/services/project/project.go
================================================
package project

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/requests/project"
	project0 "github.com/goal-web/goal/app/results/project"
)

func init() {

	ProjectServiceDefine.GetProject = func(req *project.GetProjectReq, ctx contracts.Context) (*project0.GetProjectResult, error) {
		return &project0.GetProjectResult{
			// 查询项目
		}, nil

	}

}


================================================
FILE: app/services/user/Auth_gen.go
================================================
// Code generated by goal-cli. DO NOT EDIT.
// versions:
// 	goal-cli v0.5.24
// 	go       go1.24.0
//
// updated_at: 2025-03-24 20:22:07
// source: pro/user.proto
// 
package user

import (
	"github.com/goal-web/contracts"
	user "github.com/goal-web/goal/app/requests/user"
	user0 "github.com/goal-web/goal/app/results/user"
)

var AuthServiceDefine AuthServiceStatic

type AuthServiceStatic struct {
	LoginByWxAppCode func(req *user.LoginByWxCodeReq, ctx contracts.Context) (*user0.LoginByWxResult, error)
	LoginByWxAppInfo func(req *user.LoginByWxInfoReq, ctx contracts.Context) (*user0.LoginByWxResult, error)
}

func AuthServiceLoginByWxAppCode(req *user.LoginByWxCodeReq, ctx contracts.Context) (*user0.LoginByWxResult, error) {
	if AuthServiceDefine.LoginByWxAppCode != nil {
		return AuthServiceDefine.LoginByWxAppCode(req, ctx)
	}
	return nil, nil
}

func AuthServiceLoginByWxAppInfo(req *user.LoginByWxInfoReq, ctx contracts.Context) (*user0.LoginByWxResult, error) {
	if AuthServiceDefine.LoginByWxAppInfo != nil {
		return AuthServiceDefine.LoginByWxAppInfo(req, ctx)
	}
	return nil, nil
}


================================================
FILE: app/websocket/demo.go
================================================
package websocket

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/supports/logs"
)

type DemoController struct {
}

func (d DemoController) OnConnect(request contracts.HttpRequest, fd uint64) error {
	// todo: 绑定用户和 fd
	return nil
}

func (d DemoController) OnMessage(frame contracts.WebSocketFrame) {
	logs.Default().Info("received websocket message:" + frame.RawString())
}

func (d DemoController) OnClose(fd uint64) {
	// todo: 解绑 fd
}


================================================
FILE: bootstrap/console/main.go
================================================
package main

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/bootstrap/core"
)

func main() {
	app := core.Application()

	app.Call(func(console3 contracts.Console, input contracts.ConsoleInput) {
		console3.Run(input)
	})
}


================================================
FILE: bootstrap/core/application.go
================================================
package core

import (
	"github.com/goal-web/application"
	"github.com/goal-web/bloomfilter"
	"github.com/goal-web/cache"
	"github.com/goal-web/config"
	"github.com/goal-web/console"
	"github.com/goal-web/console/scheduling"
	"github.com/goal-web/contracts"
	"github.com/goal-web/database"
	"github.com/goal-web/email"
	"github.com/goal-web/encryption"
	"github.com/goal-web/events"
	"github.com/goal-web/filesystem"
	"github.com/goal-web/goal/app/exceptions"
	"github.com/goal-web/goal/app/providers"
	config2 "github.com/goal-web/goal/config"
	"github.com/goal-web/hashing"
	"github.com/goal-web/http/sse"
	"github.com/goal-web/http/websocket"
	"github.com/goal-web/migration"
	"github.com/goal-web/queue"
	"github.com/goal-web/ratelimiter"
	"github.com/goal-web/redis"
	"github.com/goal-web/routing"
	"github.com/goal-web/serialization"
	"github.com/goal-web/supports/utils"
	"github.com/golang-module/carbon/v2"
	"os"
)

type App struct {
	QueueWorker      bool
	SchedulingWorker bool
}

func Application(c ...App) contracts.Application {
	env := config.NewToml(config.File("env.toml"))
	app := application.Singleton(env.GetBool("app.debug"))
	pwd, _ := os.Getwd()
	app.Instance("pwd", pwd)

	conf := utils.DefaultValue(c, App{})
	// 设置异常处理器
	app.Singleton("exceptions.handler", func() contracts.ExceptionHandler {
		return exceptions.NewHandler()
	})

	app.RegisterServices(
		config.NewService(env, config2.GetConfigProviders()),
		hashing.NewService(),
		encryption.NewService(),
		filesystem.NewService(),
		serialization.NewService(),
		events.NewService(),
		providers.NewEvents(),
		redis.NewService(),
		cache.NewService(),
		bloomfilter.NewService(),
		ratelimiter.NewService(),
		database.NewService(),
		queue.NewService(conf.QueueWorker),
		email.NewService(),
		console.NewService(),
		scheduling.NewService(conf.SchedulingWorker),
		migration.NewService(),
		routing.NewService(),
		sse.NewService(),
		websocket.NewService(),
	)

	app.RegisterServices(
		providers.NewApp(),
	)

	app.Call(func(config contracts.Config, dispatcher contracts.EventDispatcher, console3 contracts.Console) {
		appConfig := config.Get("app").(application.Config)
		carbon.SetLocale(appConfig.Locale)
		carbon.SetTimezone(appConfig.Timezone)
	})

	return app
}


================================================
FILE: bootstrap/queue/main.go
================================================
package main

import (
	"github.com/goal-web/goal/bootstrap/core"
	"github.com/goal-web/supports/logs"
)

func main() {
	app := core.Application(core.App{
		QueueWorker: true,
	})

	if errors := app.Start(); len(errors) > 0 {
		logs.WithField("errors", errors).Fatal("goal 异常!")
	} else {
		logs.Default().Info("goal 已关闭")
	}
}


================================================
FILE: bootstrap/schedule/main.go
================================================
package main

import (
	"github.com/goal-web/goal/bootstrap/core"
	"github.com/goal-web/supports/logs"
)

func main() {
	app := core.Application(core.App{
		SchedulingWorker: true,
	})

	if errors := app.Start(); len(errors) > 0 {
		logs.WithField("errors", errors).Fatal("goal 异常!")
	} else {
		logs.Default().Info("goal 已关闭")
	}
}


================================================
FILE: config/README_cache_config.md
================================================
# 缓存配置说明

## 概述

本文档说明了Goal Web框架中缓存组件的配置选项和使用方法。

## 配置结构

缓存配置支持三种驱动:
- **memory**: 内存缓存(RAM驱动)
- **file**: 文件缓存
- **redis**: Redis缓存

## 配置选项

### 基本配置

```go
cache.Config{
    Default: "memory",  // 默认缓存驱动
    Stores: map[string]contracts.Fields{
        // 各种缓存驱动的配置
    },
}
```

### 环境变量

| 环境变量 | 默认值 | 说明 |
|----------|--------|------|
| `CACHE_DEFAULT` | `memory` | 默认缓存驱动 |
| `CACHE_PREFIX` | `""` | 缓存键前缀 |
| `CACHE_TTL` | `86400` | 默认缓存TTL(秒) |
| `CACHE_FILE_PATH` | `./storage/cache` | 文件缓存路径 |
| `CACHE_CONNECTION` | `default` | Redis连接名称 |

## 驱动配置

### 1. 内存缓存 (memory)

```go
"memory": {
    "driver": "ram",
    "prefix": env.GetString("cache.prefix"),
    "ttl":    utils.IntOr(env.GetInt("cache.ttl"), 24*int(time.Hour)),
}
```

**配置参数:**
- `driver`: 固定为 "ram"
- `prefix`: 缓存键前缀
- `ttl`: 默认过期时间(秒)

**特点:**
- 高性能,数据存储在内存中
- 应用重启后数据丢失
- 支持统计和监控功能

### 2. 文件缓存 (file)

```go
"file": {
    "driver": "file",
    "path":   utils.StringOr(env.GetString("cache.file.path"), "./storage/cache"),
    "prefix": env.GetString("cache.prefix"),
}
```

**配置参数:**
- `driver`: 固定为 "file"
- `path`: 缓存文件存储路径
- `prefix`: 缓存键前缀

**特点:**
- 持久化存储,应用重启后数据保留
- 适合开发环境和小型应用
- 自动创建缓存目录

### 3. Redis缓存 (redis)

```go
"redis": {
    "driver":     "redis",
    "connection": utils.StringOr(env.GetString("cache.connection"), "default"),
    "prefix":     env.GetString("cache.prefix"),
}
```

**配置参数:**
- `driver`: 固定为 "redis"
- `connection`: Redis连接名称
- `prefix`: 缓存键前缀

**特点:**
- 高性能,支持分布式
- 持久化存储
- 支持复杂数据结构

## 使用示例

### 1. 基本使用

```go
// 获取默认缓存实例
cache := cache.Store()

// 获取指定驱动缓存实例
memoryCache := cache.Store("memory")
fileCache := cache.Store("file")
redisCache := cache.Store("redis")
```

### 2. 环境配置

```bash
# 设置环境变量
export CACHE_DEFAULT=memory
export CACHE_PREFIX=myapp_
export CACHE_TTL=3600
export CACHE_FILE_PATH=/tmp/cache
export CACHE_CONNECTION=redis1
```

### 3. 配置文件

```toml
# config.toml
[cache]
default = "memory"
prefix = "myapp_"
ttl = 3600

[cache.file]
path = "/tmp/cache"

[cache.redis]
connection = "redis1"
```

## 配置最佳实践

### 1. 开发环境
```go
// 使用内存缓存,快速开发
cache.default = "memory"
```

### 2. 测试环境
```go
// 使用文件缓存,便于调试
cache.default = "file"
cache.file.path = "./test_cache"
```

### 3. 生产环境
```go
// 使用Redis缓存,高性能和可靠性
cache.default = "redis"
cache.connection = "production_redis"
```

### 4. 混合使用
```go
// 不同类型的数据使用不同的缓存
userCache := cache.Store("memory")    // 用户会话
configCache := cache.Store("file")    // 配置数据
dataCache := cache.Store("redis")     // 业务数据
```

## 性能考虑

### 1. 内存缓存
- **优点**: 最高性能,零延迟
- **缺点**: 内存占用,重启丢失
- **适用**: 临时数据,会话缓存

### 2. 文件缓存
- **优点**: 持久化,简单部署
- **缺点**: 磁盘I/O,性能中等
- **适用**: 配置缓存,开发环境

### 3. Redis缓存
- **优点**: 高性能,分布式,持久化
- **缺点**: 需要额外服务,网络延迟
- **适用**: 生产环境,大数据量

## 监控和调试

### 1. 统计信息
```go
// 获取缓存统计(仅内存缓存支持)
if memoryCache, ok := cache.Store("memory").(*drivers.Memory); ok {
    stats := memoryCache.GetStats()
    fmt.Printf("命中率: %.2f%%\n", stats["hit_rate"])
    fmt.Printf("内存使用: %.2f MB\n", stats["memory_usage"].(map[string]any)["total_mb"])
}
```

### 2. 键管理
```go
// 获取所有键(仅内存缓存支持)
if memoryCache, ok := cache.Store("memory").(*drivers.Memory); ok {
    keys := memoryCache.GetKeys()
    fmt.Printf("当前有 %d 个缓存键\n", len(keys))
}
```

### 3. 清理过期项
```go
// 手动清理过期项(仅内存缓存支持)
if memoryCache, ok := cache.Store("memory").(*drivers.Memory); ok {
    cleaned := memoryCache.CleanupAllExpired()
    fmt.Printf("清理了 %d 个过期项\n", cleaned)
}
```

## 故障排除

### 1. 常见问题

**问题**: 缓存不生效
**解决**: 检查驱动名称是否正确,确保缓存服务正常运行

**问题**: 内存使用过高
**解决**: 调整TTL设置,定期清理过期项

**问题**: 文件权限错误
**解决**: 确保缓存目录有写入权限

**问题**: Redis连接失败
**解决**: 检查Redis服务状态和连接配置

### 2. 调试技巧

```go
// 启用调试日志
logs.SetLevel(logs.DebugLevel)

// 检查缓存状态
stats := cache.GetStats()
logs.Debug("Cache stats", stats)
```

## 总结

缓存配置提供了灵活的选项来满足不同场景的需求:

1. **开发环境**: 使用内存缓存,快速迭代
2. **测试环境**: 使用文件缓存,便于调试
3. **生产环境**: 使用Redis缓存,高性能和可靠性

通过合理配置缓存驱动和参数,可以显著提升应用程序的性能和用户体验。




================================================
FILE: config/app.go
================================================
package config

import (
	"github.com/goal-web/application"
	"github.com/goal-web/contracts"
)

var configs = make(map[string]contracts.ConfigProvider)

func GetConfigProviders() map[string]contracts.ConfigProvider {
	return configs
}

func init() {
	configs["app"] = func(env contracts.Env) any {
		return application.Config{
			Name:     env.GetString("app.name"),
			Debug:    env.GetBool("app.debug"),
			Timezone: env.GetString("app.timezone"),
			Env:      env.GetString("app.env"),
			Locale:   env.GetString("app.locale"),
			Key:      env.GetString("app.key"),
		}
	}
}


================================================
FILE: config/auth.go
================================================
package config

import (
	"github.com/goal-web/auth"
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/models"
	"github.com/golang-jwt/jwt"
	"time"
)

func init() {
	configs["auth"] = func(env contracts.Env) any {
		return auth.Config{
			Defaults: auth.Defaults{
				Guard: env.StringOptional("auth.default", "jwt"),
				User:  env.StringOptional("auth.user", "db"),
			},
			Guards: map[string]contracts.Fields{
				"jwt": {
					"driver":   "jwt",
					"secret":   env.GetString("auth.jwt.secret"),
					"method":   jwt.SigningMethodHS256,
					"lifetime": 60 * 60 * 24 * time.Second,
					"provider": "db",
				},
				"session": {
					"driver":      "session",
					"provider":    "db",
					"session_key": env.StringOptional("auth.session.key", "auth_session"),
				},
			},
			Users: map[string]contracts.Fields{
				"db": {
					"driver":   "db",
					"provider": models.UserAuthProvider,
				},
			},
		}
	}
}


================================================
FILE: config/bloomfilter.go
================================================
package config

import (
	"github.com/goal-web/bloomfilter"
	"github.com/goal-web/contracts"
)

func init() {
	configs["bloomfilter"] = func(env contracts.Env) any {
		return bloomfilter.Config{
			Default: "default",
			Filters: bloomfilter.Filters{
				"default": contracts.Fields{
					"driver":   "file", // 将数据序列化到文件中,不支持分布式
					"size":     100000,
					"k":        .01,
					"filepath": "storage/bloomfilter/default", // 完整路径
				},
				"users": contracts.Fields{
					"driver": "redis", // 通过 redis bitmap 存储,支持分布式
					"size":   100000,
					"k":      .01,
					"key":    "bloomfilter:{name}", // {name} 表示该 filter 的key,这里是 users
					//"connection": "cache", // redis 连接
				},
			},
		}
	}
}


================================================
FILE: config/cache.go
================================================
package config

import (
	"time"

	"github.com/goal-web/cache"
	"github.com/goal-web/contracts"
	"github.com/goal-web/supports/utils"
)

func init() {
	configs["cache"] = func(env contracts.Env) any {
		return cache.Config{
			Default: utils.StringOr(env.GetString("cache.default"), "memory"),
			Stores: map[string]contracts.Fields{
				"memory": {
					"driver": "ram",
					"prefix": env.GetString("cache.prefix"),
					"ttl":    utils.IntOr(env.GetInt("cache.ttl"), 24*int(time.Hour)), // 默认缓存生命周期
				},
				"file": {
					"driver": "file",
					"path":   utils.StringOr(env.GetString("cache.file.path"), "./storage/cache"),
					"prefix": env.GetString("cache.prefix"),
				},
				"redis": {
					"driver":     "redis",
					"connection": utils.StringOr(env.GetString("cache.connection"), "default"),
					"prefix":     env.GetString("cache.prefix"),
				},
			},
		}
	}
}


================================================
FILE: config/cache_example.toml
================================================
# 缓存配置示例
# Cache Configuration Example

# 默认缓存驱动
cache.default = "memory"

# 缓存键前缀
cache.prefix = "goal_"

# 默认缓存TTL(秒)
cache.ttl = 86400

# 文件缓存配置
cache.file.path = "./storage/cache"

# Redis缓存配置
cache.connection = "default"

# 环境变量示例
# CACHE_DEFAULT=memory
# CACHE_PREFIX=goal_
# CACHE_TTL=86400
# CACHE_FILE_PATH=./storage/cache
# CACHE_CONNECTION=default




================================================
FILE: config/database.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/database"
	"strings"
)

func init() {
	configs["database"] = func(env contracts.Env) any {
		return database.Config{
			Default: env.StringOptional("db.connection", "mysql"),
			Connections: map[string]contracts.Fields{
				"sqlite": {
					"driver":   "sqlite",
					"database": env.GetString("db.sqlite.database"),
				},
				"mysql": {
					"driver":          "mysql",
					"host":            env.GetString("db.host"),
					"port":            env.GetString("db.port"),
					"database":        env.GetString("db.database"),
					"username":        env.GetString("db.username"),
					"password":        env.GetString("db.password"),
					"unix_socket":     env.GetString("db.unix_socket"),
					"charset":         env.StringOptional("db.charset", "utf8mb4"),
					"collation":       env.StringOptional("db.collation", "utf8mb4_unicode_ci"),
					"prefix":          env.GetString("db.prefix"),
					"strict":          env.GetBool("db.struct"),
					"max_connections": env.GetInt("db.max_connections"),
					"max_idles":       env.GetInt("db.max_idles"),
					"other":           "&parseTime=true&multiStatements=true",
				},
				"pgsql": {
					"driver":          "postgres",
					"host":            env.GetString("db.pgsql.host"),
					"port":            env.GetString("db.pgsql.port"),
					"database":        env.GetString("db.pgsql.database"),
					"username":        env.GetString("db.pgsql.username"),
					"password":        env.GetString("db.pgsql.password"),
					"charset":         env.StringOptional("db.pgsql.charset", "utf8mb4"),
					"prefix":          env.GetString("db.pgsql.prefix"),
					"schema":          env.StringOptional("db.pgsql.schema", "public"),
					"sslmode":         env.StringOptional("db.pgsql.sslmode", "disable"),
					"max_connections": env.GetInt("db.pgsql.max_connections"),
					"max_idles":       env.GetInt("db.pgsql.max_idles"),
				},
				"clickhouse": {
					"driver":          "clickhouse",
					"dsn":             env.GetString("db.clickhouse.dsn"), // see https://github.com/ClickHouse/clickhouse-go#dsn
					"max_connections": env.GetInt("db.clickhouse.max_connections"),
					"max_idles":       env.GetInt("db.clickhouse.max_idles"),
					"address":         strings.Split(env.GetString("db.clickhouse.address"), ","),
					"database":        env.GetString("db.clickhouse.database"),
					"username":        env.GetString("db.clickhouse.username"),
					"password":        env.GetString("db.clickhouse.password"),
					"debug":           env.GetString("db.clickhouse.debug"),
				},
			},
		}
	}
}


================================================
FILE: config/encryption.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/encryption"
)

func init() {
	configs["encryption"] = func(env contracts.Env) any {
		return encryption.Config{
			Default: "AES",
			Drivers: map[string]contracts.EncryptDriver{},
		}
	}
}


================================================
FILE: config/filesystem.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/filesystem"
	"os"
)

func init() {
	configs["filesystem"] = func(env contracts.Env) any {
		return filesystem.Config{
			Default: env.StringOptional("filesystem.disk", "public"),
			Disks: map[string]contracts.Fields{
				"public": {
					"driver": "local",
					"root":   env.StringOptional("filesystem.root", "storage/app/public"),
					"perm":   os.ModePerm,
				},
				"qiniu": {
					"driver":     "qiniu",
					"ttl":        3600, // 私有 url 有效期,单位秒
					"private":    env.GetBool("qiniu.private"),
					"domain":     env.GetBool("qiniu.domain"), // example: https://image.example.com"
					"bucket":     env.GetString("qiniu.bucket"),
					"access_key": env.GetString("qiniu.access.key"),
					"secret_key": env.GetString("qiniu.secret.key"),
				},
			},
		}
	}
}


================================================
FILE: config/http.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/http"
)

func init() {
	configs["http"] = func(env contracts.Env) any {
		config := http.Config{
			Host:              env.GetString("http.host"),
			Port:              env.GetString("http.port"),
			StaticDirectories: map[string]string{
				//"/": "public",
			},
		}

		if env.GetString("app.env") == "local" {
			config.StaticDirectories["/"] = "public"
		}

		return config
	}
}


================================================
FILE: config/mail.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/email"
)

func init() {
	configs["mail"] = func(env contracts.Env) any {
		return email.Config{
			Default: "default",
			Mailers: map[string]contracts.Fields{
				"default": {
					"driver": "mailer",
					//"tls":      &tls.Config{InsecureSkipVerify: true},
					"from":     env.GetString("mail.from"),
					"host":     env.GetString("mail.host"),
					"port":     env.GetString("mail.port"),
					"username": env.GetString("mail.username"),
					"password": env.GetString("mail.password"),
				},
			},
		}
	}
}


================================================
FILE: config/queue.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/queue"
	"github.com/nsqio/go-nsq"
	"strings"
)

func init() {
	configs["queue"] = func(env contracts.Env) any {
		return queue.Config{
			Defaults: queue.Defaults{
				Connection: env.StringOptional("queue.connection", "default"),
				Queue:      env.StringOptional("queue.default", "default"),
			},
			Connections: map[string]contracts.Fields{
				"default": {
					"driver":  "kafka",
					"delay":   "delay_queue", // 延迟队列名
					"brokers": strings.Split(env.GetString("queue.kafka.brokers"), ","),
					//"dialer": &kafka.Dialer{}, // 自定义 kafka.Dialer
					"queue": []string{
						"default", "slow", "high",
					},
				},
				"nsq": {
					"driver":           "nsq",
					"address":          env.GetString("queue.nsq.address"),
					"lookup_addresses": strings.Split(env.GetString("queue.nsq.lookup_addresses"), ","),
					"config":           &nsq.Config{}, // 自定义 nsq 设置
					"queue": []string{
						"default", "slow", "high",
					},
				},
				"sync":      {"driver": "sync"},
				"empty":     {"driver": "empty"},
				"goroutine": {"driver": "goroutine"},
			},
			Failed: queue.FailedJobs{
				Database: env.StringOptional("db.connection", "mysql"),
				Table:    "failed_jobs",
			},
			Workers: map[string]queue.Workers{ // 相当于 laravel 的 horizon 配置
				"local": { // 本地环境
					"default": { // 工作组
						Connection: env.StringOptional("queue.connection", "default"), // 指定连接
						Tries:      3,                                                 // 最大尝试次数
						Queue:      []string{"default", "slow", "high"},               // 处理指定队列
						Processes:  10,                                                // 十个协程(工人)
					},
				},
				"production": { // 生产环境

				},
			},
		}
	}
}


================================================
FILE: config/redis.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/redis"
	"github.com/goal-web/supports/utils"
)

func init() {
	configs["redis"] = func(env contracts.Env) any {
		return redis.Config{
			Default: utils.StringOr(env.GetString("redis.default"), "default"),
			Stores: map[string]contracts.Fields{
				"default": {
					"network":  env.GetString("redis.network"),
					"host":     env.GetString("redis.host"),
					"port":     env.GetString("redis.port"),
					"username": env.GetString("redis.username"),
					"password": env.GetString("redis.password"),
					"db":       env.GetInt64("redis.db"),
					"retries":  env.GetInt64("redis.retries"),
				},
				"cache": {
					"network":  env.GetString("redis.cache.network"),
					"host":     env.GetString("redis.cache.host"),
					"port":     env.GetString("redis.cache.port"),
					"username": env.GetString("redis.cache.username"),
					"password": env.GetString("redis.cache.password"),
					"db":       env.GetInt64("redis.cache.db"),
					"retries":  env.GetInt64("redis.cache.retries"),
				},
			},
		}
	}
}


================================================
FILE: config/serialization.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/jobs"
	"github.com/goal-web/serialization"
)

func init() {
	configs["serialization"] = func(env contracts.Env) any {
		return serialization.Config{
			Default: "json", // 支持:json、gob、xml。
			Class: []contracts.Class[any]{ // 需要序列化的类
				jobs.DemoClass,
			},
		}
	}
}


================================================
FILE: config/session.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/session"
	"time"
)

func init() {
	configs["session"] = func(env contracts.Env) any {
		return session.Config{
			Driver:     "redis", // 目前支持 cookie、redis
			Encrypt:    true,
			Domain:     env.GetString("session.domain"),
			Lifetime:   time.Duration(env.GetInt("session.lifetime")),
			Connection: "default",         // database、redis 用到
			Key:        "goal_session:%s", // redis 驱动所用到的 key
			Table:      "sessions",        // database 用到
			Name:       env.StringOptional("session.name", "goal"),
		}
	}
}


================================================
FILE: config/views.go
================================================
package config

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/views"
)

func init() {
	configs["views"] = func(env contracts.Env) any {
		return views.Config{
			Path: env.StringOptional("views.path", "views"),
		}
	}
}


================================================
FILE: config/websocket.go
================================================
package config

import (
	websocket2 "github.com/fasthttp/websocket"
	"github.com/goal-web/contracts"
	"github.com/goal-web/http/websocket"
)

func init() {
	configs["websocket"] = func(env contracts.Env) any {
		return websocket.Config{
			Upgrader: websocket2.FastHTTPUpgrader{
				HandshakeTimeout: 5,
				//ReadBufferSize:    0,
				//WriteBufferSize:   0,
				//WriteBufferPool:   nil,
				//Subprotocols:      nil,
				//Error:             nil,
				//CheckOrigin:       nil,
				//EnableCompression: false,
			},
		}
	}
}


================================================
FILE: database/.gitignore
================================================


================================================
FILE: database/migrations/2024_05_09_141932_create_articles.down.sql
================================================
drop table if exists articles

================================================
FILE: database/migrations/2024_05_09_141932_create_articles.sql
================================================
CREATE TABLE IF NOT EXISTS articles
(
    `id`       INT UNSIGNED AUTO_INCREMENT,
    title      varchar(20) not null,
    created_at timestamp,
    updated_at timestamp,
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

================================================
FILE: env.toml
================================================
[app]
name = "goal"
key = "dQcxsKvBZKNfWivwnhKlDwvseguknBZPEiiDRQlIatjKLLpbzK"
env = "local"
debug = true

[http]
host = "0.0.0.0"
port = "8009"


[queue]
connection = "goroutine"
kafka.brokers = "localhost:9092"
nsq.address = "localhost:49156"

[db]
connection = "mysql"
host = "127.0.0.1"
port = "3306"
database = "goal"
username = "root"
password = "root"

[db.sqlite]
database = "database/database.sqlite"

[db.pgsql]
host = "localhost"
port = "55433"
database = "postgres"
username = "postgres"
password = "123456"

[redis]
host = "hsy"
port = "6379"
password = "123456"

[redis.cache]
host = "hsy"
port = "6379"
db = 1

# 缓存配置
[cache]
driver = "redis"
connection = "cache"
prefix = "redis_"

# 哈希配置
[hashing]
driver = "bcrypt"
cost = "14"
salt = "goal"
# 自定义哈希
[hashing.hashers]
md5.driver = "md5"
md5.salt = "goal"

# 文件系统配置
[filesystem]
disk = "public"
root = "storage/app/public"
perm = "0777"

[filesystem.qiniu]
private = "false"
bucket = "aa"
domain = "https://xxx.xxx.com"
access_key = ""
secret_key = ""

# session 配置
[session]
id = "goal"
name = "goal_session:"



================================================
FILE: go.mod
================================================
module github.com/goal-web/goal

go 1.25.0

replace github.com/goal-web/goal-cli => ../goal-cli

require (
	github.com/alicebob/miniredis/v2 v2.34.0
	github.com/fasthttp/websocket v1.5.10
	github.com/go-redis/redis/v8 v8.11.4
	github.com/goal-web/application v0.5.2
	github.com/goal-web/auth v0.5.3
	github.com/goal-web/bloomfilter v0.5.2
	github.com/goal-web/cache v0.5.2
	github.com/goal-web/collection v0.5.2
	github.com/goal-web/config v0.5.4
	github.com/goal-web/console v0.5.4
	github.com/goal-web/contracts v0.5.3
	github.com/goal-web/database v0.5.3
	github.com/goal-web/email v0.5.2
	github.com/goal-web/encryption v0.5.2
	github.com/goal-web/events v0.5.2
	github.com/goal-web/filesystem v0.5.2
	github.com/goal-web/goal-cli v0.5.42
	github.com/goal-web/hashing v0.5.2
	github.com/goal-web/http v0.5.11
	github.com/goal-web/migration v0.5.6
	github.com/goal-web/queue v0.5.2
	github.com/goal-web/ratelimiter v0.5.2
	github.com/goal-web/redis v0.5.2
	github.com/goal-web/routing v0.5.2
	github.com/goal-web/serialization v0.5.2
	github.com/goal-web/session v0.5.2
	github.com/goal-web/supports v0.5.7
	github.com/goal-web/validation v0.5.2
	github.com/goal-web/views v0.5.2
	github.com/golang-jwt/jwt v3.2.2+incompatible
	github.com/golang-module/carbon/v2 v2.3.12
	github.com/google/uuid v1.6.0
	github.com/gookit/goutil v0.6.18
	github.com/nsqio/go-nsq v1.1.0
	github.com/spf13/cast v1.7.1
)

require (
	github.com/BurntSushi/toml v1.4.0 // indirect
	github.com/joho/godotenv v1.5.1 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
)

require (
	github.com/ClickHouse/clickhouse-go/v2 v2.0.9 // indirect
	github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect
	github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
	github.com/andybalholm/brotli v1.1.0 // indirect
	github.com/apex/log v1.9.0 // indirect
	github.com/bits-and-blooms/bitset v1.2.1 // indirect
	github.com/cespare/xxhash/v2 v2.2.0 // indirect
	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
	github.com/emicklei/proto v1.13.2 // indirect
	github.com/flosch/pongo2/v6 v6.0.0 // indirect
	github.com/fsnotify/fsnotify v1.6.0 // indirect
	github.com/go-playground/locales v0.14.0 // indirect
	github.com/go-playground/universal-translator v0.18.0 // indirect
	github.com/go-playground/validator/v10 v10.10.0 // indirect
	github.com/go-sql-driver/mysql v1.6.0 // indirect
	github.com/goal-web/container v0.5.3 // indirect
	github.com/goal-web/pipeline v0.5.2 // indirect
	github.com/goal-web/querybuilder v0.5.4 // indirect
	github.com/golang/snappy v0.0.4 // indirect
	github.com/gookit/color v1.5.4 // indirect
	github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 // indirect
	github.com/jmoiron/sqlx v1.3.4 // indirect
	github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
	github.com/klauspost/compress v1.17.9 // indirect
	github.com/leodido/go-urn v1.2.1 // indirect
	github.com/lib/pq v1.10.4 // indirect
	github.com/mattn/go-sqlite3 v1.14.10 // indirect
	github.com/modood/table v0.0.0-20220527013332-8d47e76dad33 // indirect
	github.com/paulmach/orb v0.4.0 // indirect
	github.com/pierrec/lz4 v2.6.1+incompatible // indirect
	github.com/pierrec/lz4/v4 v4.1.14 // indirect
	github.com/pkg/errors v0.9.1 // indirect
	github.com/qbhy/parallel v1.4.0 // indirect
	github.com/qiniu/go-sdk/v7 v7.11.1 // indirect
	github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
	github.com/segmentio/kafka-go v0.4.27 // indirect
	github.com/shopspring/decimal v1.4.0 // indirect
	github.com/valyala/bytebufferpool v1.0.0 // indirect
	github.com/valyala/fasthttp v1.55.0 // indirect
	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
	github.com/yuin/gopher-lua v1.1.1 // indirect
	go.opentelemetry.io/otel v1.3.0 // indirect
	go.opentelemetry.io/otel/trace v1.3.0 // indirect
	go.uber.org/ratelimit v0.2.0 // indirect
	golang.org/x/crypto v0.24.0 // indirect
	golang.org/x/net v0.26.0 // indirect
	golang.org/x/sync v0.10.0 // indirect
	golang.org/x/sys v0.28.0 // indirect
	golang.org/x/text v0.21.0 // indirect
)


================================================
FILE: go.sum
================================================
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/ClickHouse/clickhouse-go v1.5.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/ClickHouse/clickhouse-go/v2 v2.0.9 h1:JKtF6JlROrcdZRMoQUTv6fW8CBSL9FiBKylXXQx5YnY=
github.com/ClickHouse/clickhouse-go/v2 v2.0.9/go.mod h1:FfiBHxYkESSf1DQxROQ1kOP2XtI4Fy8XDVPasZSkI+k=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE=
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis/v2 v2.34.0 h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQggTglU/0=
github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI=
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/apex/log v1.9.0 h1:FHtw/xuaM8AgmvDDTI9fiwoAL25Sq2cxojnZICUU8l0=
github.com/apex/log v1.9.0/go.mod h1:m82fZlWIuiWzWP04XCTXmnX0xRkYYbCdYn8jbJeLBEA=
github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE=
github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/bits-and-blooms/bitset v1.2.1 h1:M+/hrU9xlMp7t4TyTDQW97d3tRPVuKFC6zBEK16QnXY=
github.com/bits-and-blooms/bitset v1.2.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY=
github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/fasthttp/websocket v1.5.10 h1:bc7NIGyrg1L6sd5pRzCIbXpro54SZLEluZCu0rOpcN4=
github.com/fasthttp/websocket v1.5.10/go.mod h1:BwHeuXGWzCW1/BIKUKD3+qfCl+cTdsHu/f243NcAI/Q=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU=
github.com/flosch/pongo2/v6 v6.0.0/go.mod h1:CuDpFm47R0uGGE7z13/tTlt1Y6zdxvr2RLT5LJhsHEU=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/goal-web/application v0.5.2 h1:bDatyicAwuz4kNCKg+T47kNOtfXETlaRGEcPyWcM2AE=
github.com/goal-web/application v0.5.2/go.mod h1:JVFX9zGWI9uG2ur1jlH87pWSG3hbatWGDyEHYj3FkHo=
github.com/goal-web/auth v0.5.3 h1:i2UdvuY79TAwIqDHLI5KhBXZLTDncGVHDWPoQCqt6Vk=
github.com/goal-web/auth v0.5.3/go.mod h1:y4ytkPR47ZQFJx26l0kVkbw0YXhCnWPkPMe+wEMbwJ0=
github.com/goal-web/bloomfilter v0.5.2 h1:r4bdTOM3lXeb7qgrZI9SYI6I1ehBrB9l+kuf88g71dE=
github.com/goal-web/bloomfilter v0.5.2/go.mod h1:uczJ+qBurMla6+nGhuR/Ezk3X4aydRFCqismyJ7SGDo=
github.com/goal-web/cache v0.5.2 h1:gmUVwfOzzNMe53bXb4sTnAjdbmip1/uHe6wSw3gI0/Y=
github.com/goal-web/cache v0.5.2/go.mod h1:RdZd3TeiJnhGzwrWACZPeZjqbBHR5vHjgtix2KpNOwA=
github.com/goal-web/collection v0.5.2 h1:lPZbHeV4juiAh/NWp5FkG8+Wjb4ouu7IoQN8SNhtvq0=
github.com/goal-web/collection v0.5.2/go.mod h1:dwO/vxDW4hLKzkHtDNXdgdgDWV8D+MHVXHKYy/nEKfQ=
github.com/goal-web/config v0.5.4 h1:2w9bkpnXEuKA8V/2x21fAewWidyLNoUZWUoL8lLmJGo=
github.com/goal-web/config v0.5.4/go.mod h1:L7qzwZnE547rioTSlhxZ2WyEYeqkboAiDoRk1G/dY2s=
github.com/goal-web/console v0.5.4 h1:G7GvqgbpGV+iMOStz5s5sX1Cj8N+JpU+Nn+t4VaBUfw=
github.com/goal-web/console v0.5.4/go.mod h1:8/MEDbVCMm1my5IYDS/6yMGlDXCsg8gLsy39pzfmEvo=
github.com/goal-web/container v0.5.3 h1:pSz+ARibpOKXbGKLN8Yw/LbKfLSq5MdOwp9xlWHDsQs=
github.com/goal-web/container v0.5.3/go.mod h1:RbzqAvWBKywaljql2JY1uoYzx1XJLjlDf7SIYiKbVlw=
github.com/goal-web/contracts v0.5.3 h1:/W8n1B/GoKtXWwElrVR5RbbVSKRPkGVuJsLoSkbNJaw=
github.com/goal-web/contracts v0.5.3/go.mod h1:mDFF5dx3G3newdB4qvfOWMnwWkGxQuzbymiNSKcdlzM=
github.com/goal-web/database v0.5.3 h1:BoJ3juFknn0H9CBzDKpjix7Q3ejQOa3snwKXbXJlcBY=
github.com/goal-web/database v0.5.3/go.mod h1:2R/b0mjO2xNImP0/v3gT/FL2eOceY6cDHZgFiFYxrds=
github.com/goal-web/email v0.5.2 h1:MjWr2o8gwHekmH0J0DYeKNozkcavKjmRtJfcOf9LcsI=
github.com/goal-web/email v0.5.2/go.mod h1:sI8eznbLhejS7j7/ZZehBTXFYiB2gVqQP3+Zx/I7ST4=
github.com/goal-web/encryption v0.5.2 h1:YkCiLOt0ZLPjZfPpCyvPDR+HJy9kfIYHYPRKY3k9R5s=
github.com/goal-web/encryption v0.5.2/go.mod h1:lzshlcMozyd3K39GBoKQhmZmJkjveQ0bNCiuyEsuqsM=
github.com/goal-web/events v0.5.2 h1:Z+uHCp/axjjcoeEIZMb3Ug0g7MY70FZ2/qMurdY3GEY=
github.com/goal-web/events v0.5.2/go.mod h1:33AiZ3h+HgXv2tEmbjLGob9t89wwFOdLfYGcN6PkwsA=
github.com/goal-web/filesystem v0.5.2 h1:yXJDaEq8c6pAyRYdCcLcPaIqdhJ4SWH9+bSgsOZ26XA=
github.com/goal-web/filesystem v0.5.2/go.mod h1:3VaOj8fzMnCh2EY28xUGhphRBmxbzKnSoaHfdOJgqvQ=
github.com/goal-web/hashing v0.5.2 h1:QN3LetMqiJsTWT6Lo52GPD0FBaJ3c8+D7bIOVBs5VjY=
github.com/goal-web/hashing v0.5.2/go.mod h1:Ft7MTHZSzppWPbtF8JNhtU0XLv5i2NEwYVpuDWc3c+M=
github.com/goal-web/http v0.5.11 h1:7AuCNQ85Gmg8RN3pYC6P5kojD+iQ6v7+695ycMgsQec=
github.com/goal-web/http v0.5.11/go.mod h1:+3RXhErKxuutSmxuIUaL52/7WVg0oCc10hJcDcgPCzY=
github.com/goal-web/migration v0.5.6 h1:xNPirTwGIbgmY4e3dfeUmeKoh8i6FxTpZ9QeQL5CupU=
github.com/goal-web/migration v0.5.6/go.mod h1:iGbpVpwPHQJde/I8//09HcHkKUovB8qQJmxgEyzvnNA=
github.com/goal-web/pipeline v0.5.2 h1:aEpGmulH5CzOXqnSAZr7J43D4yy3Wi8quAY6t5ejseg=
github.com/goal-web/pipeline v0.5.2/go.mod h1:9JPnhTvotfXdcdhH98oMjQmvuPa9WKye0TI8xb+y8HY=
github.com/goal-web/querybuilder v0.5.4 h1:e6VGrM6Em+n6femrwIqCjpvzZ/uh1BwsfZHWysctz/s=
github.com/goal-web/querybuilder v0.5.4/go.mod h1:v8Z8nnrriyq70QX7W5zGgxhSoz98DB/cnmN+tJQNyn0=
github.com/goal-web/queue v0.5.2 h1:o/7V1B/lyHR4aGR4nqZaRWMQs84aDWnpR5AXx8X68WE=
github.com/goal-web/queue v0.5.2/go.mod h1:Jr9dXUcY34T4/5g1F1CLZFPT9d0o42wB58hNfYekgjs=
github.com/goal-web/ratelimiter v0.5.2 h1:S1gDxpZdvmQsdlULVafoK5dqhG74bNZ2R0nhkqcdhgs=
github.com/goal-web/ratelimiter v0.5.2/go.mod h1:8j/SxH51dJSg7n7GYkvoGaiRfOv9EW2VNfwLDzQLwTY=
github.com/goal-web/redis v0.5.2 h1:lBz/avfsDkp1pnubaYW+wFGrWN6wm7j/edsUYOBPqdg=
github.com/goal-web/redis v0.5.2/go.mod h1:UWlrR1lkdbweOCiKzTOAGMcvCdwTZG0dNwKYOcVu3BQ=
github.com/goal-web/routing v0.5.2 h1:i86o3vmu45xPaYQNYpx3utPST4L9Cx5iou8QVfYqRZA=
github.com/goal-web/routing v0.5.2/go.mod h1:rtLq7/7qHmOAgNNikEF0HdMeEHqn5Rvt4WjPLag1Rzg=
github.com/goal-web/serialization v0.5.2 h1:SipUuA7AF65FprNF271x7Isr6Yg1H/z4vSkDuovtOVE=
github.com/goal-web/serialization v0.5.2/go.mod h1:7D5zjCADeHBXxFU4olxYhYaNRX1B/IgBGtY1MyS/mcg=
github.com/goal-web/session v0.5.2 h1:juOXuFW/dOIRsa8YqsLEnBQ+NlFXIos/NN6lHlTqs2Y=
github.com/goal-web/session v0.5.2/go.mod h1:WR7c7K+vvX5CqPhIg5Qwdt7GYDpnunaSEOg0xUlJQaA=
github.com/goal-web/supports v0.5.7 h1:j0c0ZY5IJyiozGyp9fq0hy6Qkh4AMCP/GRSwDEQaOzE=
github.com/goal-web/supports v0.5.7/go.mod h1:TViRmtPhjFfQ1YqOKBfxej8vdFkYwbzWe2uvhgGO2Zg=
github.com/goal-web/validation v0.5.2 h1:3ufzNB30gqa4TqcZhFH/I3JWVxsSKCVhjvJgxZ5MMKQ=
github.com/goal-web/validation v0.5.2/go.mod h1:UvlpuogwjQqngAqVAkSxHSEoxqWINolaXM1RLjkopao=
github.com/goal-web/views v0.5.2 h1:euAKBqEgumpiGcNVQms8ROsZrg2Tze69qYrTsTOn9R8=
github.com/goal-web/views v0.5.2/go.mod h1:yCo/xoXkBFKd8hUvVWaTcFO2jpxMO6LqTn/j6pAaR+4=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-module/carbon/v2 v2.3.12 h1:VC1DwN1kBwJkh5MjXmTFryjs5g4CWyoM8HAHffZPX/k=
github.com/golang-module/carbon/v2 v2.3.12/go.mod h1:HNsedGzXGuNciZImYP2OMnpiwq/vhIstR/vn45ib5cI=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
github.com/gookit/goutil v0.6.18 h1:MUVj0G16flubWT8zYVicIuisUiHdgirPAkmnfD2kKgw=
github.com/gookit/goutil v0.6.18/go.mod h1:AY/5sAwKe7Xck+mEbuxj0n/bc3qwrGNe3Oeulln7zBA=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY=
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk=
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615/go.mod h1:Ad7oeElCZqA1Ufj0U9/liOF4BtVepxRcTvr2ey7zTvM=
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33 h1:T5IbS9C1G2zeHb6eBy6OfIvj5tfQB23kGFpewCJuGDg=
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33/go.mod h1:41qyXVI5QH9/ObyPj27CGCVau5v/njfc3Gjj7yzr0HQ=
github.com/nsqio/go-nsq v1.1.0 h1:PQg+xxiUjA7V+TLdXw7nVrJ5Jbl3sN86EhGCQj4+FYE=
github.com/nsqio/go-nsq v1.1.0/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/paulmach/orb v0.4.0 h1:ilp1MQjRapLJ1+qcays1nZpe0mvkCY+b8JU/qBKRZ1A=
github.com/paulmach/orb v0.4.0/go.mod h1:FkcWtplUAIVqAuhAOV2d3rpbnQyliDOjOcLW9dUrfdU=
github.com/paulmach/protoscan v0.2.1-0.20210522164731-4e53c6875432/go.mod h1:2sV+uZ/oQh66m4XJVZm5iqUZ62BN88Ex1E+TTS0nLzI=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4/v4 v4.1.13/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qbhy/parallel v1.4.0 h1:RvdjXbxIRNMG2lA6gkaEOgVhr7JbNy4BljabsD+u9JI=
github.com/qbhy/parallel v1.4.0/go.mod h1:gjKS0IACnz3SWXkeEOUvPPZZxpeQAOW47jT4cpWPvqU=
github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
github.com/qiniu/go-sdk/v7 v7.11.1 h1:/LZ9rvFS4p6SnszhGv11FNB1+n4OZvBCwFg7opH5Ovs=
github.com/qiniu/go-sdk/v7 v7.11.1/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w=
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
github.com/segmentio/kafka-go v0.4.27 h1:sIhEozeL/TLN2mZ5dkG462vcGEWYKS+u31sXPjKhAM4=
github.com/segmentio/kafka-go v0.4.27/go.mod h1:XzMcoMjSzDGHcIwpWUI7GB43iKZ2fTVmryPSGLf/MPg=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk=
github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc=
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA=
go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220220014-0732a990476f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=


================================================
FILE: main.go
================================================
package main

import (
	"fmt"
	"syscall"

	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/controllers"
	"github.com/goal-web/goal/bootstrap/core"
	"github.com/goal-web/goal/routes"
	"github.com/goal-web/http"
	"github.com/goal-web/http/sse"
	"github.com/goal-web/http/websocket"
	"github.com/goal-web/session"
	"github.com/goal-web/supports/signal"
	"github.com/goal-web/views"
)

func main() {

	a := "a"
	fmt.Println(a)

	app := core.Application(core.App{
		QueueWorker:      true,
		SchedulingWorker: true,
	})

	app.RegisterServices(
		views.NewService(),
		http.NewService(
			routes.Api,
			routes.WebSocket,
			routes.Sse,
			controllers.Register,
		),
		session.NewService(),
		sse.NewService(),
		websocket.NewService(),
		signal.NewService(syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT),
	)

	app.Call(func(console3 contracts.Console, input contracts.ConsoleInput) {
		console3.Run(input)
	})
}


================================================
FILE: pro/Article.proto
================================================
syntax = "proto3";


//@table: articles
//@timestamps
message ArticleModel {
    uint32 id = 1;
    string title = 2;
    string created_at = 3;
    string updated_at = 4;
}


================================================
FILE: pro/Project.proto
================================================
syntax = "proto3";

option go_package = "project";

//@timestamps
//@table: projects
message ProjectModel {
  int64 id = 1;
  string uuid = 2;
  string name = 3;
  int64 creator_id = 4;
  int64 group_id = 5;
  int64 key_id = 6;
  string repo_address = 7;
  string project_path = 8;
  string default_branch = 9;
  string settings = 10;
  string created_at = 11;
  string updated_at = 12;
}


//@controller:/project
service ProjectService {
  rpc CreateProject(CreateProjectReq) returns (CreateProjectResult) {}
  //@method:Get
  rpc GetProject(GetProjectReq) returns (GetProjectResult) {}
  //@method:Get
  rpc ListProjects(ListProjectsReq) returns (ListProjectsResult) {}
  rpc UpdateProject(UpdateProjectReq) returns (UpdateProjectResult) {}
  rpc DeleteProject(DeleteProjectReq) returns (DeleteProjectResult) {}
}

message CreateProjectReq {
  string uuid = 1;
  string name = 2;
  int64 creator_id = 3;
  int64 group_id = 4;
  int64 key_id = 5;
  string repo_address = 6;
  string project_path = 7;
  string default_branch = 8;
  string settings = 9;
}
message CreateProjectResult {
  string code = 1;
}


message GetProjectReq {
  string id = 1;
}
message GetProjectResult {
  ProjectModel project = 1;
}



message ListProjectsReq {
  int64 page = 1;
  int64 per_page = 2;
}
message ListProjectsResult {
  int64 total = 1;
  //@ptr
  repeated ProjectModel projects = 2;
}



message UpdateProjectReq {
  int64 id = 1;
  string uuid = 2;
  string name = 3;
  int64 creator_id = 4;
  int64 group_id = 5;
  int64 key_id = 6;
  string repo_address = 7;
  string project_path = 8;
  string default_branch = 9;
  string settings = 10;
}
message UpdateProjectResult {
  string code = 1;
}


message DeleteProjectReq {
  string id = 1;
}

message DeleteProjectResult {
  string code = 1;
}




================================================
FILE: pro/common.proto
================================================
syntax = "proto3";

option go_package = ".";

enum Code {
  //@msg:成功
  Success = 0;

  //@msg:参数解析失败
  ParseReqErr = 10400;
  //@msg:未登录
  Unauthorized = 10401;
  //@msg:没有权限
  Forbidden = 100403;
  //@msg:找不到
  NotFound = 100404;
  //@msg:业务错误
  BizErr = 10201;
}

message ResponseResult {
  int32 code = 1;
  string err_message = 2;
  string message = 3;
  //@goType:any
  string data = 4;
}


================================================
FILE: pro/goal-cli.go
================================================
package main

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"

	"github.com/goal-web/goal-cli/app/gen"
)

func main() {
	// 定义命令行参数
	out := flag.String("out", "app", "output")                   // 输出目录
	template := flag.String("template", "template.tmpl", "模板文件") // 模板文件
	dir := flag.String("dir", "pro", "指定扫描的 proto 文件目录")         // 要扫描的目录
	mode := flag.String("mode", "pro", "pro 或者 SDK")

	flag.Parse()

	// 检查是否指定了 proto 文件目录
	if *dir == "" {
		fmt.Println("请指定要扫描的 proto 文件目录, 使用 --dir 参数")
		os.Exit(1)
	}

	// 获取指定目录中的所有 proto 文件
	protoFiles, err := scanProtoFiles(*dir)
	if err != nil {
		fmt.Printf("扫描目录 %s 中的 proto 文件失败: %v\n", *dir, err)
		os.Exit(1)
	}

	if *mode == "pro" {
		// 遍历所有找到的 proto 文件,依次调用 gen.Pro()
		for _, protoFile := range protoFiles {
			fmt.Printf("正在处理 proto 文件: %s\n", protoFile)
			gen.Pro(protoFile, *template, *out)
		}
	} else {
		// 遍历所有找到的 proto 文件,依次调用 gen.Pro()
		gen.SDK(protoFiles, *template, *out)
	}
}

// scanProtoFiles 扫描指定目录,返回所有的 .proto 文件路径
func scanProtoFiles(root string) ([]string, error) {
	var protoFiles []string

	// 使用 filepath.Walk 遍历目录,查找所有 .proto 文件
	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// 如果是 .proto 文件,则加入到列表中
		if !info.IsDir() && filepath.Ext(path) == ".proto" {
			protoFiles = append(protoFiles, path)
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return protoFiles, nil
}


================================================
FILE: pro/user.proto
================================================
syntax = "proto3";

option go_package = "user";

message WechatInfoData {
  string city = 1;
  int64 gender = 2;
  string open_id = 3;
  string country = 4;
  string language = 5;
  string nickname = 6;
  string province = 7;
  string avatar_url = 8;
}

// 用户注释
//@authenticatable
//@table: users
//@timestamps
message UserModel {

  int64 id = 1;
  string name = 2;
  string avatar = 3;

  //@index
  //@goTag:db:"open_id;type:varchar(255);default 'xxasdasdsx'"
  string open_id = 4;

  //@ptr
  WechatInfoData wechat_info = 5;

  string channel = 6;

  //@hidden
  string password = 9;

  string created_at = 7;
  string updated_at = 8;
}

// 通过微信小程序的 code 登录
message LoginByWxCodeReq {
  //@gotag:validate:"required"
  string code = 1;
}

// 通过微信小程序的 code 登录
message LoginByWxInfoReq {
  //@gotag: validate:"required"
  string iv = 1;
  //@gotag: validate:"required"
  string sessionKey = 2;
  //@gotag: validate:"required"
  string encryptedData = 3;
}

message LoginByWxResult {
  //@gotag:json:"token,omitempty"
  string token = 1;
  //@ptr
  //@gotag:json:"user,omitempty"
  UserModel user = 2;
  //@gotag:json:"sessionKey,omitempty"
  string sessionKey = 3;
}

//@controller:/auth
service AuthService {

  //@method:Post
  //@middleware:guest
  rpc LoginByWxAppCode(LoginByWxCodeReq) returns(LoginByWxResult);

  //@middleware:guest
  rpc LoginByWxAppInfo(LoginByWxInfoReq) returns(LoginByWxResult);
}

================================================
FILE: routes/api.go
================================================
package routes

import (
	"github.com/goal-web/contracts"
	"github.com/goal-web/goal/app/controllers"
)

func Api(router contracts.HttpRouter) {

	router.Get("/wrk/{name}", func(request contracts.HttpRequest) any {
		return request.Param("name")
	})

	router.Get("/", controllers.HelloWorld)
	router.Get("/view", func(views contracts.Views) any {
		return views.Render("view.html")
	})
}


================================================
FILE: routes/sse.go
================================================
package routes

import (
	"github.com/goal-web/contracts"
	sse2 "github.com/goal-web/goal/app/http/sse"
	"github.com/goal-web/http/sse"
)

func Sse(router contracts.HttpRouter) {
	// 自定义 sse 控制器
	router.Get(sse.New("/sse-demo", sse2.DemoController{}))

	// 默认 sse 控制器
	router.Get(sse.Default())

	router.Get("/send-sse", func(sse contracts.Sse, request contracts.HttpRequest) error {
		return sse.Send(uint64(request.GetInt64("fd")), request.GetString("msg"))
	})

	router.Get("/close-sse", func(sse contracts.Sse, request contracts.HttpRequest) error {
		return sse.Close(uint64(request.GetInt64("fd")))
	})
}


================================================
FILE: routes/ws.go
================================================
package routes

import (
	"fmt"
	"github.com/goal-web/contracts"
	websocket2 "github.com/goal-web/goal/app/websocket"
	"github.com/goal-web/http/websocket"
)

func WebSocket(router contracts.HttpRouter) {

	router.Get("/ws-demo", websocket.New(websocket2.DemoController{}))

	router.Get("/ws", websocket.Default(func(frame contracts.WebSocketFrame) {

		fmt.Println("收到消息", frame.RawString(), frame.Connection().Fd())
		_ = frame.Send("来自服务器的回复1")
		_ = frame.SendBytes([]byte("来自服务器的回复2"))

	}))

}


================================================
FILE: sdk.tmpl
================================================
{{- define "request" -}}
{{- range .Imports }}
import {{ .Alias }} from "{{ .Pkg }}"
{{- end }}

export default interface {{ .Model.Name }} {
  {{- range .Fields }}
  {{ .JSONName }}{{ if hasComment .Comment "@nullable" }}?{{end}}: {{ tsType . }}
  {{- end }}
}
{{ end }}

{{- define "model" -}}
{{- range .Imports }}
import {{ .Alias }} from "{{ .Pkg }}"
{{- end }}

export default interface {{ .Model.Name }} {
  {{- range .Fields }}
  {{ .JSONName }}{{ if hasComment .Comment "@nullable" }}?{{end}}: {{ tsType . }}
  {{- end }}
}
{{ end }}


{{- define "result" -}}
{{- range .Imports }}
import {{ .Alias }} from "{{ .Pkg }}"
{{- end }}

export default interface {{ .Model.Name }} {
  {{- range .Fields }}
  {{ .JSONName }}{{ if hasComment .Comment "@nullable" }}?{{end}}: {{ tsType . }}
  {{- end }}
}
{{ end }}

{{- define "enum" -}}

{{- $enumName := .Name }}

export enum {{ $enumName }} {
  {{- range .Values }}
  {{- $FieldName := sprintf "%s%s" $enumName .Name }}

  {{ toComments $FieldName .Comments }}
  {{ .Name }} = {{ .Value }},
  {{- end }}
}

{{ end }}

{{- define "data" -}}

{{- range .Imports }}
import {{ .Alias }} from "{{ .Pkg }}"
{{- end }}

export default interface {{ .Model.Name }} {
  {{- range .Fields }}
  {{ .JSONName }}{{ if hasComment .Comment "@nullable" }}?{{end}}: {{ tsType . }}
  {{- end }}
}
{{ end }}

{{- define "controller" -}}
import {alovaInstance, wrapParams} from "../index";
import {useRequest} from "alova/client";
import {RequestHookConfig} from "alova/client";
{{- range .Imports }}
import {{ .Alias }} from "{{ .Pkg }}"
{{- end }}

{{- $serviceName := .Name }}
{{- $prefix := .Prefix }}
{{- $hasHook := hasComment .Comment "@hook" }}

{{- range .Methods }}

{{- $name := .Name }}
{{- $req := .InputUsageName }}
{{- $resp := .OutputUsageName }}
{{- $path := .Path }}
{{- $hook := or $hasHook (hasComment .Comment "@hook") }}

{{- if eq (len .Method) 1 }}

export function {{ .Name }}(req: {{ .InputUsageName }}) {
    return alovaInstance.{{ (index .Method 0) }}<{{ .OutputUsageName }}>("{{ $prefix }}{{ .Path }}", wrapParams('{{ index .Method 0 }}', req))
}

{{- if $hook }}
export function use{{ .Name }}(req: {{ .InputUsageName }}, config?: RequestHookConfig<any, any>) {
    return useRequest({{ .Name }}(req), config)
}
{{- end }}

{{- else }}
{{- range .Method }}

export function {{ . }}{{ $name }}(req: {{ $req }}) {
    return alovaInstance.{{ . }}<{{ $resp }}>("{{ $prefix }}{{ $path }}", wrapParams('{{ . }}', req))
}

{{- if $hook }}
export function use{{ . }}{{ $name }}(req: {{ .InputUsageName }}, config?: RequestHookConfig<any, any>) {
    return useRequest({{ . }}{{ $name }}(req), config)
}
{{- end }}

{{- end }}

{{- end }}

{{- end }}


{{ end }}

================================================
FILE: server.conf
================================================
server {
    listen 80;

    server_name example.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location / {
        proxy_pass http://localhost:8008;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

================================================
FILE: storage/app/.gitignore
================================================
*
!.gitignore
!public

================================================
FILE: storage/framework/bloomfilter/.gitignore
================================================
.gitignore
!.gitignore


================================================
FILE: storage/framework/cache/.gitignore
================================================
.gitignore
!.gitignore


================================================
FILE: storage/framework/sessions/.gitignore
================================================
.gitignore
!.gitignore


================================================
FILE: storage/logs/.gitignore
================================================
*
!.gitignore


================================================
FILE: supervisor.conf
================================================
[program:goal-server]
command=/opt/app/goal
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/opt/app/storage/logs/goal.log


================================================
FILE: template.tmpl
================================================
{{- define "model" -}}
package {{ .Package }}

import (
    "encoding/json"
    "github.com/goal-web/supports/logs"
    "github.com/goal-web/contracts"
    "github.com/goal-web/database/table"
	"github.com/goal-web/migration/migrate"
    "github.com/goal-web/supports/utils"
    "github.com/goal-web/collection"
	"github.com/spf13/cast"
    "fmt"
    {{- if hasMsgComment .Model "@carbon" }}
    "github.com/golang-module/carbon/v2"
    {{- end }}
    {{- range .Imports }}
    {{ .Alias }} "{{ .Pkg }}"
    {{- end }}
)

{{- $modelName := .Model.Name }}
{{- $rawName := .Model.RawName }}
{{- $tableName := .Model.TableName }}
{{- $primaryKey := .Model.PrimaryKey }}

var (
    {{- range .Relations }}
    {{ $rawName }}{{ .Name }}Relation contracts.RelationType = "{{ .JSONName }}"
    {{- end }}
)

{{ toComments .Model.Name .Model.Comments }}
type {{ $modelName }} struct {

  {{- range .Fields }}
  {{- if hasComment .Comment "@belongsTo" }}
  {{- else }}
  {{ .Comments }}
  {{ .Name }} {{ goType . }} `{{ toTags . }}`
  {{- end }}
  {{- end }}

  _raw contracts.Fields
  _update contracts.Fields
  _append contracts.Fields
  _hidden map[string]struct{}

  _relation_loaded map[contracts.RelationType]struct{}
  {{- range .Relations }}
    _{{ .Name }} {{ goType . }}
  {{- end }}
}

{{- $define := join $rawName "Define" }}
var {{ $define }} {{ $rawName }}Static

type {{ $rawName }}Static struct {
    TableName string
	Hidden []string
	Indexes []string
	With []contracts.RelationType
	Appends map[string]func(model *{{ $modelName }}) any

  {{- range .Fields }}
  {{ .Name }}Getter func(model *{{ $modelName }}, raw {{ goType . }}) {{ goType . }}
  {{ .Name }}Setter func(model *{{ $modelName }}, raw {{ goType . }}) {{ goType . }}
  {{- end }}

  Saving   func(model *{{ $modelName }}) contracts.Exception
  Saved    func(model *{{ $modelName }})
  Updating func(model *{{ $modelName }}, fields contracts.Fields) contracts.Exception
  Updated  func(model *{{ $modelName }}, fields contracts.Fields)
  Deleting func(model *{{ $modelName }}) contracts.Exception
  Deleted  func(model *{{ $modelName }})
  PrimaryKeyGetter func(model *{{ $modelName }}) any
}

func {{ $rawName }}Migrator() migrate.Migrator {
	return func(executor contracts.SqlExecutor) contracts.Exception {
	    return migrate.Migrate({{ $define }}.TableName, {{ $define }}.Indexes, {{ $modelName }}{}, executor)
	}
}

func init() {
    {{ $define }}.TableName = "{{ $tableName }}"
    {{ $define }}.Appends = make(map[string]func(model *{{ $modelName }}) any)
    {{- if hasMsgComment .Model "@hidden" }}
    {{ $define }}.Hidden = append(
        {{ $define }}.Hidden,
        {{- range .Fields }}
            {{- if hasComment .Comment "@hidden" }}
            "{{ .JSONName }}",
            {{- end }}
        {{- end }}
     )
    {{- end }}

    {{- if hasMsgComment .Model "@with" }}
    {{ $define }}.With = append(
        {{ $define }}.With,
        {{- range .Relations }}
            {{- if hasComment .Comment "@with" }}
             {{ $rawName }}{{ .Name }}Relation,
            {{- end }}
        {{- end }}
     )
    {{- end }}

    {{- if hasMsgComment .Model "@index" }}
    {{ $define }}.Indexes = append(
        {{ $define }}.Indexes,
        {{- range .Fields }}
            {{- if hasComment .Comment "@index" }}
             "index;{{ getIndexComment .Comment "@index" 0 (join .JSONName "_idx") }};{{ replace (getIndexComment .Comment "@index" 1 (join "(" .JSONName ")")) ";" "," }}",
            {{- end }}
        {{- end }}
     )
    {{- end }}

    {{- if hasMsgComment .Model "@unique" }}
    {{ $define }}.Indexes = append(
        {{ $define }}.Indexes,
        {{- range .Fields }}
            {{- if hasComment .Comment "@unique" }}
             "unique index;{{ getIndexComment .Comment "@unique" 0 (join .JSONName "_idx") }};{{ replace (getIndexComment .Comment "@unique" 1 (join "(" .JSONName ")")) ";" "," }}",
            {{- end }}
        {{- end }}
     )
    {{- end }}
}

func New{{ $modelName }}(fields contracts.Fields) *{{ $modelName }} {
  var model = {{ $modelName }}{
    _raw: fields,
  }
  model.Set(fields)
  return &model
}

func {{ $modelName }}SingleRelationSetter[T any](key contracts.RelationType) func(item *{{ $modelName }}, value []any) {
    return func(item *{{ $modelName }}, values []any) {
        var value T
        if len(values) > 0 {
            value = values[0].(T)
        }
        item.Set(contracts.Fields{
            string(key): value,
        })
    }
}
func {{ $modelName }}MultiRelationSetter[T any](key contracts.RelationType) func(item *{{ $modelName }}, value []any) {
    return func(model *{{ $modelName }}, value []any) {
        var results []T
        for _, item := range value {
            results = append(results, item.(T))
        }
        model.Set(contracts.Fields{ string(key): results })
    }
}

func {{ $modelName }}LocalKeyGetter(key string) func(item *{{ $modelName }}) any {
    return func(item *{{ $modelName }}) any {
        return item.Get(key)
    }
}

func {{ $modelName }}RelationGetter[T any](query func() *table.Table[T], foreignKey string) func(keys []any) map[string][]any {
    return func(keys []any) map[string][]any {
        var results = map[string][]any{}
        for key, values := range query().WhereIn(foreignKey, keys).Get().GroupBy(foreignKey) {
            results[key] = collection.New(values).ToAnyArray()
        }
        return results
    }
}

func {{ $modelName }}ThroughRelationGetter[T any](query func() *table.Table[T], midTable, firstKey, secondKey, secondLocalKey string) func(keys []any) map[string][]any {
    return func(keys []any) map[string][]any {
        var results = map[string][]any{}
        groupKey := fmt.Sprintf("%s.%s", midTable, firstKey)
        for key, values := range query().
            AddSelect(fmt.Sprintf("(%s) as _group_key", groupKey)).
            WhereIn(groupKey, keys).
            Join(midTable, fmt.Sprintf("%s.%s", midTable, secondLocalKey), "=", fmt.Sprintf("%s.%s", query().GetTableName(), secondKey)).
            Get().GroupBy("_group_key") {
            results[key] = collection.New(values).ToAnyArray()
        }
        return results
    }
 }

{{- $queryName := replace .Model.Name "Model" "Query" }}
func {{ $queryName }}WithExecutor(executor contracts.SqlExecutor) *table.Table[{{ $modelName }}] {
    return {{ $queryName }}().SetExecutor(executor)
}

func {{ $queryName }}() *table.Table[{{ $modelName }}] {
  return table.NewQuery({{ $define }}.TableName, New{{ $modelName }}).
    SetPrimaryKey("{{ $primaryKey }}").
    {{- if hasMsgComment .Model "@timestamps" }}
    SetCreatedTimeColumn("{{ getIndexComment .Model.Comment "@timestamps" 0 "created_at" }}").
    SetUpdatedTimeColumn("{{ getIndexComment .Model.Comment "@timestamps" 1 "updated_at" }}").
    {{- end }}
    {{- range $index, $item := .Relations }}
        {{- $relationType := join $rawName  .Name "Relation" }}
        {{- $relationItemType := substring (goType .) 1 }}
        {{- $relationQuery := replace $relationItemType "Model" "Query"}}

        {{- if .Repeated }}
        {{- $relationItemType = substring (goType .) 2 }}
        {{- $relationQuery = substring $relationQuery 2 }}
        {{- end }}


        {{- if hasComment .Comment "@belongsTo" }}
            {{- $ownerKey := getIndexComment .Comment "@belongsTo" 0 "id" }}
            {{- $localKey := getIndexComment .Comment "@belongsTo" 1 (join .JSONName "_id") }}
            SetRelation( // belongsTo: {{ .Name }}
            {{ $rawName }}{{ .Name }}Relation,
                        {{ $modelName }}LocalKeyGetter("{{ $localKey }}"),
                        {{ $modelName }}RelationGetter({{ $relationQuery }}, "{{ $ownerKey }}"),
                        {{ $modelName }}SingleRelationSetter[*{{ $relationItemType }}]({{ $relationType }}),
            ).
        {{- else if hasComment .Comment "@hasOneThrough" }}

         {{- $midTable := getIndexComment .Comment "@hasOneThrough" 0 "mid_table" }}
         {{- $firstKey := getIndexComment .Comment "@hasOneThrough" 1 (join (toLower $rawName) "_id") }}
         {{- $secondKey := getIndexComment .Comment "@hasOneThrough" 2 "id" }}
         {{- $localKey := getIndexComment .Comment "@hasOneThrough" 3 "id" }}
         {{- $secondLocalKey := getIndexComment .Comment "@hasOneThrough" 4 (join $midTable "_id") }}

                    SetRelation( // hasOneThrough: {{ .Name }}
                    {{ $rawName }}{{ .Name }}Relation,
                        {{ $modelName }}LocalKeyGetter("{{ $localKey }}"),
                        {{ $modelName }}ThroughRelationGetter({{ $relationQuery }}, "{{ $midTable }}", "{{ $firstKey }}", "{{ $secondKey }}", "{{ $secondLocalKey }}"),
                        {{ $modelName }}SingleRelationSetter[*{{ $relationItemType }}]({{ $relationType }}),
                    ).
        {{- else if hasComment .Comment "@hasOne" }}
         {{- $localKey := getIndexComment .Comment "@hasOne" 0 "id" }}
         {{- $foreignKey := getIndexComment .Comment "@hasOne" 1 (join (toLower $rawName) "_id") }}
                    SetRelation( // hasOne: {{ .Name }}
                    {{ $rawName }}{{ .Name }}Relation,
                        {{ $modelName }}LocalKeyGetter("{{ $localKey }}"),
                        {{ $modelName }}RelationGetter({{ $relationQuery }}, "{{ $foreignKey }}"),
                        {{ $modelName }}SingleRelationSetter[*{{ $relationItemType }}]({{ $relationType }}),
                    ).
        {{- else if or (hasComment .Comment "@hasManyThrough") (hasComment .Comment "@belongsToMany") }}

            {{- $relationName := "hasManyThrough" }}
            {{- if (hasComment .Comment "@belongsToMany") }}
            {{- $relationName = "belongsToMany" }}
            {{- end }}

         {{- $midTable := getIndexComment .Comment (join "@" $relationName) 0 "mid_table" }}
         {{- $firstKey := getIndexComment .Comment (join "@" $relationName) 1 (join (toLower $rawName) "_id") }}
         {{- $secondKey := getIndexComment .Comment (join "@" $relationName) 2 "id" }}
         {{- $localKey := getIndexComment .Comment (join "@" $relationName) 3 "id" }}
         {{- $secondLocalKey := getIndexComment .Comment (join "@" $relationName) 4 (join $midTable "_id") }}

                    SetRelation( // {{- $relationName }}: {{ .Name }}
                    {{ $rawName }}{{ .Name }}Relation,
                        {{ $modelName }}LocalKeyGetter("{{ $localKey }}"),
                        {{ $modelName }}ThroughRelationGetter({{ $relationQuery }}, "{{ $midTable }}", "{{ $firstKey }}", "{{ $secondKey }}", "{{ $secondLocalKey }}"),
                        {{ $modelName }}MultiRelationSetter[{{ $relationItemType }}]({{ $relationType }}),
                    ).
        {{- else if hasComment .Comment "@hasMany" }}
         {{- $relationItemType := substring (goType .) 2 }}
         {{- $relationQuery := replace (substring (goType .) 3) "Model" "Query"}}
         {{- $foreignKey := getIndexComment .Comment "@hasMany" 0 (join (toLower $rawName) "_id") }}
         {{- $localKey := getIndexComment .Comment "@hasMany" 1 "id" }}
                    SetRelation( // hasMany: {{ .Name }}
                    {{ $rawName }}{{ .Name }}Relation,
                        {{ $modelName }}LocalKeyGetter("{{ $localKey }}"),
                        {{ $modelName }}RelationGetter({{ $relationQuery }}, "{{ $foreignKey }}"),
                        {{ $modelName }}MultiRelationSetter[{{ $relationItemType }}]({{ $relationType }}),
                    ).
        {{- end }}

    {{- end }}
     SetWiths({{ $define }}.With...)
}

func (model *{{ $modelName }}) Hidden(fields ...string) *{{ $modelName }} {
    for _, field := range fields {
        if model._hidden == nil {
            model._hidden = map[string]struct{}{
                field: struct{}{},
            }
        } else {
            model._hidden[field] = struct{}{}
        }

    }

    return model
}

func (model *{{ $modelName }}) Exists() bool {
  return {{ .Model.RawName }}Query().Where("{{ $primaryKey }}", model.GetPrimaryKey()).Count() > 0
}

func (model *{{ $modelName }}) Save() contracts.Exception {
  if model._update == nil {
    return nil
  }
  if {{ $define }}.Saving != nil {
    if err := {{ $define }}.Saving(model); err != nil {
      return err
    }
  }
var err contracts.Exception
var pk = model. GetPrimaryKey()
if cast.ToUint64(pk) == 0 {
    pk, err = {{ .Model.RawName }}Query().Where("{{ $primaryKey }}", model.GetPrimaryKey()).InsertGetIdE(model._update)
    if err == nil {
        {{- range .Fields }}
        {{- if eq .JSONName $primaryKey }}
        model.Set{{.Name}}(cast.{{ convertFunc (goType .) }}(pk))
        {{- end }}
        {{- end }}
    }
} else {
  _, err = {{ .Model.RawName }}Query().Where("{{ $primaryKey }}", model.GetPrimaryKey()).UpdateE(model._update)
}
  if err == nil {
    model._update = nil
    if {{ $define }}.Saved != nil {
      {{ $define }}.Saved(model)
    }
  }

  return err
}

func (model *{{ $modelName }}) Set(fields contracts.Fields) {
  for key, value := range fields {

    switch key {
  {{- range .Fields }}
      case "{{ .JSONName }}":
        switch v := value.(type) {
                case {{ goType . }}:
                  model.Set{{ .Name }}(v)
                case func() {{ goType . }}:
                  model.Set{{ .Name }}(v())
                  {{- $type := goType . }}
                  {{- if ne $type "string"}}
                case string:
                  {{- if eq $type "[]byte" }}
                  model.Set{{ .Name }}([]byte(v))
                  {{else}}
                  var vd {{ goType . }}
                  err := json.Unmarshal([]byte(v), &vd)
                  if err != nil {
                      logs.Default().Warn("Failed to Parse field "+key)
                      continue
                  }
                  model.Set{{ .Name }}(vd)
                  {{end}}
                  {{end}}
                  {{- if ne $type "[]byte"}}
                case []byte:
                  {{- if eq $type "string" }}
                  model.Set{{ .Name }}(string(v))
                  {{else}}
                  var vd {{ goType . }}
                  err := json.Unmarshal(v, &vd)
                  if err != nil {
                      logs.Default().Warn("Failed to Parse field "+key)
                      continue
                  }
                  model.Set{{ .Name }}(vd)
                  {{end}}
                  {{end}}
                {{- if isBasicType . }}
                default:
                    model.Set{{ .Name }}(cast.{{ convertFunc (goType .) }}(v))
                {{- end }}
                }
    {{- end }}
    {{- range .Relations }}
    {{- $relationType := join $rawName  .Name "Relation" }}
    case string({{ $relationType }}):
        model.Set{{ .Name }}(value.({{ goType . }}))
    {{- end }}
    }

  }
}

func (model *{{ $modelName }}) Only(key ...string) contracts.Fields {
  var fields = make(contracts.Fields)
  for _, k := range key {
  {{- range .Fields }}
    if k == "{{ .JSONName }}" {
      fields[k] = model.Get{{ .Name }}()
      continue
    }
  {{- end }}

    if {{ $define }}.Appends[k] != nil {
     fields[k] = {{ $define }}.Appends[k](model)
    }
  }
  return fields
}

func (model *{{ $modelName }}) Get(key string) any {
    switch key {
        {{- range $index, $item := .Fields }}
            case "{{ .JSONName }}":
              return model.Get{{ .Name }}()
        {{- end }}
    }

    if value, exists := model._append[key]; exists {
      return value
    }

    if fn, exists := {{ $define }}.Appends[key]; exists {
        model._append[key] = fn(model)
      return model._append[key]
    }

     switch contracts.RelationType(key) {
            {{- range $index, $item := .Relations }}
            {{- $relationType := join $rawName  .Name "Relation" }}
                case {{ $relationType }}:
                  return model.{{ .Name }}()
            {{- end }}
        }

  return nil
}

func (model *{{ $modelName }}) Except(keys ...string) contracts.Fields {
  var excepts = map[string]struct{}{}
  for _, k := range keys {
    excepts[k] = struct{}{}
  }
  var fields = make(contracts.Fields)
  for key, value := range model.ToFields() {
    if _, ok := excepts[key]; ok {
      continue
    }
    fields[key] = value
  }
  return fields
}

func (model *{{ $modelName }}) ToFields() contracts.Fields {
    if model == nil {
        return nil
    }

  model.Hidden({{ $define }}.Hidden...)

  fields := contracts.Fields{}

    {{- range .Fields }}
    if _,exists := model._hidden["{{ .JSONName }}"]; !exists {
        fields["{{ .JSONName }}"] = model.Get{{ .Name }}()
    }
    {{- end }}

  for key := range {{ $define }}.Appends {
    value := model.Get(key)
    if fieldsProvider, ok := value.(contracts.FieldsProvider); ok {
        fields[key] = fieldsProvider.ToFields()
    } else {
        fields[key] = value
    }
  }

  for key := range model._relation_loaded {
    switch key {
    {{- range .Relations }}
    {{- $relationType := join $rawName  .Name "Relation" }}
    case {{ $relationType }}:
        {{- if .Repeated }}
        var results []contracts.Fields
        for _, item := range model._{{ .Name }} {
            results = append(results, item.ToFields())
        }
        fields[string(key)] = results
        {{- else }}
        fields[string(key)] = model._{{ .Name }}.ToFields()
        {{- end }}
    {{- end }}
    }
  }

  for key, value := range model._raw {
    _, hidden := model._hidden[key]
    if _, exists := fields[key]; !exists && !hidden {
        fields[key] = value
    }
  }

  return fields
}

func (model *{{ $modelName }}) Update(fields contracts.Fields) contracts.Exception {

  if {{ $define }}.Updating != nil {
    if err := {{ $define }}.Updating(model, fields); err != nil {
      return err
    }
  }

  if model._update != nil {
    utils.MergeFields(model._update, fields)
  }


  _, err := {{ .Model.RawName }}Query().Where("{{ $primaryKey }}", model.GetPrimaryKey()).UpdateE(fields)

  if err == nil {
    model.Set(fields)
    model._update = nil
    if {{ $define }}.Updated != nil {
      {{ $define }}.Updated(model, fields)
    }
  }

  return err
}

func (model *{{ $modelName }}) Refresh() contracts.Exception {
  fields, err := table.ArrayQuery("{{ $tableName }}").Where("{{ $primaryKey }}", model.GetPrimaryKey()).FirstE()
  if err != nil {
    return err
  }

  model.Set(*fields)
  return nil
}

func (model *{{ $modelName }}) Delete() contracts.Exception {

  if {{ $define }}.Deleting != nil {
    if err := {{ $define }}.Deleting(model); err != nil {
      return err
    }
  }

  _, err := {{ .Model.RawName }}Query().Where("{{ $primaryKey }}", model.GetPrimaryKey()).DeleteE()
  if err == nil && {{ $define }}.Deleted != nil {
    {{ $define }}.Deleted(model)
  }

  return err
}


func (model *{{ $modelName }}) GetPrimaryKey() any {
  if {{ $define }}.PrimaryKeyGetter != nil {
    return {{ $define }}.PrimaryKeyGetter(model)
  }

  return model.{{ toCamelCase $primaryKey }}
}

{{- if .Model.Authenticatable }}
func (model *{{ $modelName }}) GetAuthenticatableKey() string {
  return 
Download .txt
gitextract_fxwyv0x_/

├── .github/
│   └── ISSUE_TEMPLATE.MD
├── .gitignore
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── app/
│   ├── console/
│   │   ├── commands/
│   │   │   └── runner.go
│   │   └── kernel.go
│   ├── controllers/
│   │   ├── helloworld.go
│   │   ├── kernel.go
│   │   ├── project/
│   │   │   └── Project_gen.go
│   │   └── user/
│   │       └── Auth_gen.go
│   ├── enums/
│   │   └── Code_gen.go
│   ├── exceptions/
│   │   └── handler.go
│   ├── http/
│   │   ├── middlewares/
│   │   │   └── example.go
│   │   └── sse/
│   │       └── demo.go
│   ├── jobs/
│   │   └── demo.go
│   ├── listeners/
│   │   └── debug_query.go
│   ├── models/
│   │   ├── Article_gen.go
│   │   ├── Project_gen.go
│   │   ├── User_gen.go
│   │   ├── project/
│   │   │   └── GetProjectRessult_gen.go
│   │   ├── project.go
│   │   └── user/
│   │       └── WechatInfoData_gen.go
│   ├── providers/
│   │   ├── app.go
│   │   ├── console.go
│   │   └── events.go
│   ├── requests/
│   │   ├── project/
│   │   │   ├── CreateProject_gen.go
│   │   │   ├── DeleteProject_gen.go
│   │   │   ├── GetProject_gen.go
│   │   │   ├── ListProjects_gen.go
│   │   │   └── UpdateProject_gen.go
│   │   └── user/
│   │       ├── LoginByWxCode_gen.go
│   │       └── LoginByWxInfo_gen.go
│   ├── response/
│   │   └── utils.go
│   ├── results/
│   │   ├── ResponseResult_gen.go
│   │   ├── project/
│   │   │   ├── CreateProjectResult_gen.go
│   │   │   ├── DeleteProjectResult_gen.go
│   │   │   ├── GetProjectResult_gen.go
│   │   │   ├── ListProjectsResult_gen.go
│   │   │   └── UpdateProjectResult_gen.go
│   │   └── user/
│   │       └── LoginByWxResult_gen.go
│   ├── services/
│   │   ├── project/
│   │   │   ├── Project_gen.go
│   │   │   └── project.go
│   │   └── user/
│   │       └── Auth_gen.go
│   └── websocket/
│       └── demo.go
├── bootstrap/
│   ├── console/
│   │   └── main.go
│   ├── core/
│   │   └── application.go
│   ├── queue/
│   │   └── main.go
│   └── schedule/
│       └── main.go
├── config/
│   ├── README_cache_config.md
│   ├── app.go
│   ├── auth.go
│   ├── bloomfilter.go
│   ├── cache.go
│   ├── cache_example.toml
│   ├── database.go
│   ├── encryption.go
│   ├── filesystem.go
│   ├── http.go
│   ├── mail.go
│   ├── queue.go
│   ├── redis.go
│   ├── serialization.go
│   ├── session.go
│   ├── views.go
│   └── websocket.go
├── database/
│   ├── .gitignore
│   └── migrations/
│       ├── 2024_05_09_141932_create_articles.down.sql
│       └── 2024_05_09_141932_create_articles.sql
├── env.toml
├── go.mod
├── go.sum
├── main.go
├── pro/
│   ├── Article.proto
│   ├── Project.proto
│   ├── common.proto
│   ├── goal-cli.go
│   └── user.proto
├── routes/
│   ├── api.go
│   ├── sse.go
│   └── ws.go
├── sdk.tmpl
├── server.conf
├── storage/
│   ├── app/
│   │   └── .gitignore
│   ├── framework/
│   │   ├── bloomfilter/
│   │   │   └── .gitignore
│   │   ├── cache/
│   │   │   └── .gitignore
│   │   └── sessions/
│   │       └── .gitignore
│   └── logs/
│       └── .gitignore
├── supervisor.conf
├── template.tmpl
├── tests/
│   ├── bootstrap.go
│   ├── bootstrap_test.go
│   ├── db_test.go
│   └── env.toml
└── views/
    └── view.html
Download .txt
SYMBOL INDEX (266 symbols across 68 files)

FILE: app/console/commands/runner.go
  type runner (line 11) | type runner struct
    method Handle (line 23) | func (runner *runner) Handle() any {
  function Runner (line 16) | func Runner() (contracts.Command, contracts.CommandHandlerProvider) {

FILE: app/console/kernel.go
  function Schedule (line 15) | func Schedule(schedule contracts.Schedule) {

FILE: app/controllers/helloworld.go
  function HelloWorld (line 10) | func HelloWorld() any {
  function createProject (line 20) | func createProject() {
  function getProjectOne (line 41) | func getProjectOne() any {
  function getProjectList (line 49) | func getProjectList() any {
  function updateProject (line 58) | func updateProject() {
  function deleteProject (line 70) | func deleteProject() {

FILE: app/controllers/kernel.go
  function Register (line 10) | func Register(router contracts.HttpRouter) {

FILE: app/controllers/project/Project_gen.go
  function ProjectServiceRouter (line 19) | func ProjectServiceRouter(router contracts.HttpRouter) {
  function ProjectServiceCreateProject (line 27) | func ProjectServiceCreateProject(request contracts.HttpRequest) any {
  function ProjectServiceGetProject (line 45) | func ProjectServiceGetProject(request contracts.HttpRequest) any {
  function ProjectServiceListProjects (line 63) | func ProjectServiceListProjects(request contracts.HttpRequest) any {
  function ProjectServiceUpdateProject (line 81) | func ProjectServiceUpdateProject(request contracts.HttpRequest) any {
  function ProjectServiceDeleteProject (line 99) | func ProjectServiceDeleteProject(request contracts.HttpRequest) any {

FILE: app/controllers/user/Auth_gen.go
  function AuthServiceRouter (line 19) | func AuthServiceRouter(router contracts.HttpRouter) {
  function AuthServiceLoginByWxAppCode (line 24) | func AuthServiceLoginByWxAppCode(request contracts.HttpRequest) any {
  function AuthServiceLoginByWxAppInfo (line 42) | func AuthServiceLoginByWxAppInfo(request contracts.HttpRequest) any {

FILE: app/enums/Code_gen.go
  type Code (line 11) | type Code
    method String (line 41) | func (item Code) String() string {
    method Message (line 60) | func (item Code) Message() string {
  constant CodeSuccess (line 17) | CodeSuccess Code = 0
  constant CodeParseReqErr (line 21) | CodeParseReqErr Code = 10400
  constant CodeUnauthorized (line 25) | CodeUnauthorized Code = 10401
  constant CodeForbidden (line 29) | CodeForbidden Code = 100403
  constant CodeNotFound (line 33) | CodeNotFound Code = 100404
  constant CodeBizErr (line 37) | CodeBizErr  Code = 10201
  constant CodeUnknown (line 38) | CodeUnknown Code = -1000
  function ParseCodeFromString (line 79) | func ParseCodeFromString(msg string) Code {

FILE: app/exceptions/handler.go
  type ExceptionHandler (line 15) | type ExceptionHandler struct
    method Handle (line 23) | func (handler *ExceptionHandler) Handle(exception contracts.Exception)...
    method handleHttpException (line 49) | func (handler *ExceptionHandler) handleHttpException(exception http.Ex...
    method renderValidationException (line 65) | func (handler *ExceptionHandler) renderValidationException(exception *...
    method Report (line 73) | func (handler *ExceptionHandler) Report(exception contracts.Exception) {
    method ShouldReport (line 75) | func (handler *ExceptionHandler) ShouldReport(exception contracts.Exce...
  function NewHandler (line 19) | func NewHandler() contracts.ExceptionHandler {

FILE: app/http/middlewares/example.go
  function Example (line 9) | func Example(request contracts.HttpRequest, next contracts.Pipe) any {

FILE: app/http/sse/demo.go
  type DemoController (line 8) | type DemoController struct
    method OnConnect (line 11) | func (d DemoController) OnConnect(request contracts.HttpRequest, fd ui...
    method OnClose (line 22) | func (d DemoController) OnClose(fd uint64) {

FILE: app/jobs/demo.go
  type Demo (line 14) | type Demo struct
    method Handle (line 34) | func (demo *Demo) Handle() {
  function NewDemo (line 19) | func NewDemo(info string) contracts.Job {

FILE: app/listeners/debug_query.go
  type DebugQuery (line 9) | type DebugQuery struct
    method Handle (line 12) | func (d DebugQuery) Handle(event contracts.Event) {

FILE: app/models/Article_gen.go
  type ArticleModel (line 27) | type ArticleModel struct
    method Hidden (line 152) | func (model *ArticleModel) Hidden(fields ...string) *ArticleModel {
    method Exists (line 167) | func (model *ArticleModel) Exists() bool {
    method Save (line 171) | func (model *ArticleModel) Save() contracts.Exception {
    method Set (line 200) | func (model *ArticleModel) Set(fields contracts.Fields) {
    method Only (line 272) | func (model *ArticleModel) Only(key ...string) contracts.Fields {
    method Get (line 299) | func (model *ArticleModel) Get(key string) any {
    method Except (line 326) | func (model *ArticleModel) Except(keys ...string) contracts.Fields {
    method ToFields (line 341) | func (model *ArticleModel) ToFields() contracts.Fields {
    method Update (line 386) | func (model *ArticleModel) Update(fields contracts.Fields) contracts.E...
    method Refresh (line 411) | func (model *ArticleModel) Refresh() contracts.Exception {
    method Delete (line 421) | func (model *ArticleModel) Delete() contracts.Exception {
    method GetPrimaryKey (line 437) | func (model *ArticleModel) GetPrimaryKey() any {
    method GetId (line 445) | func (model *ArticleModel) GetId() uint32 {
    method SetId (line 452) | func (model *ArticleModel) SetId(value uint32) {
    method GetTitle (line 465) | func (model *ArticleModel) GetTitle() string {
    method SetTitle (line 472) | func (model *ArticleModel) SetTitle(value string) {
    method GetCreatedAt (line 485) | func (model *ArticleModel) GetCreatedAt() string {
    method SetCreatedAt (line 492) | func (model *ArticleModel) SetCreatedAt(value string) {
    method GetUpdatedAt (line 505) | func (model *ArticleModel) GetUpdatedAt() string {
    method SetUpdatedAt (line 512) | func (model *ArticleModel) SetUpdatedAt(value string) {
  type ArticleStatic (line 46) | type ArticleStatic struct
  function ArticleMigrator (line 70) | func ArticleMigrator() migrate.Migrator {
  function init (line 76) | func init() {
  function NewArticleModel (line 81) | func NewArticleModel(fields contracts.Fields) *ArticleModel {
  function ArticleModelSingleRelationSetter (line 89) | func ArticleModelSingleRelationSetter[T any](key contracts.RelationType)...
  function ArticleModelMultiRelationSetter (line 100) | func ArticleModelMultiRelationSetter[T any](key contracts.RelationType) ...
  function ArticleModelLocalKeyGetter (line 110) | func ArticleModelLocalKeyGetter(key string) func(item *ArticleModel) any {
  function ArticleModelRelationGetter (line 116) | func ArticleModelRelationGetter[T any](query func() *table.Table[T], for...
  function ArticleModelThroughRelationGetter (line 126) | func ArticleModelThroughRelationGetter[T any](query func() *table.Table[...
  function ArticleQueryWithExecutor (line 140) | func ArticleQueryWithExecutor(executor contracts.SqlExecutor) *table.Tab...
  function ArticleQuery (line 144) | func ArticleQuery() *table.Table[ArticleModel] {

FILE: app/models/Project_gen.go
  type ProjectModel (line 27) | type ProjectModel struct
    method Hidden (line 184) | func (model *ProjectModel) Hidden(fields ...string) *ProjectModel {
    method Exists (line 199) | func (model *ProjectModel) Exists() bool {
    method Save (line 203) | func (model *ProjectModel) Save() contracts.Exception {
    method Set (line 232) | func (model *ProjectModel) Set(fields contracts.Fields) {
    method Only (line 445) | func (model *ProjectModel) Only(key ...string) contracts.Fields {
    method Get (line 504) | func (model *ProjectModel) Get(key string) any {
    method Except (line 547) | func (model *ProjectModel) Except(keys ...string) contracts.Fields {
    method ToFields (line 562) | func (model *ProjectModel) ToFields() contracts.Fields {
    method Update (line 631) | func (model *ProjectModel) Update(fields contracts.Fields) contracts.E...
    method Refresh (line 656) | func (model *ProjectModel) Refresh() contracts.Exception {
    method Delete (line 666) | func (model *ProjectModel) Delete() contracts.Exception {
    method GetPrimaryKey (line 682) | func (model *ProjectModel) GetPrimaryKey() any {
    method GetId (line 690) | func (model *ProjectModel) GetId() int64 {
    method SetId (line 697) | func (model *ProjectModel) SetId(value int64) {
    method GetUuid (line 710) | func (model *ProjectModel) GetUuid() string {
    method SetUuid (line 717) | func (model *ProjectModel) SetUuid(value string) {
    method GetName (line 730) | func (model *ProjectModel) GetName() string {
    method SetName (line 737) | func (model *ProjectModel) SetName(value string) {
    method GetCreatorId (line 750) | func (model *ProjectModel) GetCreatorId() int64 {
    method SetCreatorId (line 757) | func (model *ProjectModel) SetCreatorId(value int64) {
    method GetGroupId (line 770) | func (model *ProjectModel) GetGroupId() int64 {
    method SetGroupId (line 777) | func (model *ProjectModel) SetGroupId(value int64) {
    method GetKeyId (line 790) | func (model *ProjectModel) GetKeyId() int64 {
    method SetKeyId (line 797) | func (model *ProjectModel) SetKeyId(value int64) {
    method GetRepoAddress (line 810) | func (model *ProjectModel) GetRepoAddress() string {
    method SetRepoAddress (line 817) | func (model *ProjectModel) SetRepoAddress(value string) {
    method GetProjectPath (line 830) | func (model *ProjectModel) GetProjectPath() string {
    method SetProjectPath (line 837) | func (model *ProjectModel) SetProjectPath(value string) {
    method GetDefaultBranch (line 850) | func (model *ProjectModel) GetDefaultBranch() string {
    method SetDefaultBranch (line 857) | func (model *ProjectModel) SetDefaultBranch(value string) {
    method GetSettings (line 870) | func (model *ProjectModel) GetSettings() string {
    method SetSettings (line 877) | func (model *ProjectModel) SetSettings(value string) {
    method GetCreatedAt (line 890) | func (model *ProjectModel) GetCreatedAt() string {
    method SetCreatedAt (line 897) | func (model *ProjectModel) SetCreatedAt(value string) {
    method GetUpdatedAt (line 910) | func (model *ProjectModel) GetUpdatedAt() string {
    method SetUpdatedAt (line 917) | func (model *ProjectModel) SetUpdatedAt(value string) {
  type ProjectStatic (line 62) | type ProjectStatic struct
  function ProjectMigrator (line 102) | func ProjectMigrator() migrate.Migrator {
  function init (line 108) | func init() {
  function NewProjectModel (line 113) | func NewProjectModel(fields contracts.Fields) *ProjectModel {
  function ProjectModelSingleRelationSetter (line 121) | func ProjectModelSingleRelationSetter[T any](key contracts.RelationType)...
  function ProjectModelMultiRelationSetter (line 132) | func ProjectModelMultiRelationSetter[T any](key contracts.RelationType) ...
  function ProjectModelLocalKeyGetter (line 142) | func ProjectModelLocalKeyGetter(key string) func(item *ProjectModel) any {
  function ProjectModelRelationGetter (line 148) | func ProjectModelRelationGetter[T any](query func() *table.Table[T], for...
  function ProjectModelThroughRelationGetter (line 158) | func ProjectModelThroughRelationGetter[T any](query func() *table.Table[...
  function ProjectQueryWithExecutor (line 172) | func ProjectQueryWithExecutor(executor contracts.SqlExecutor) *table.Tab...
  function ProjectQuery (line 176) | func ProjectQuery() *table.Table[ProjectModel] {

FILE: app/models/User_gen.go
  type UserModel (line 30) | type UserModel struct
    method Hidden (line 184) | func (model *UserModel) Hidden(fields ...string) *UserModel {
    method Exists (line 199) | func (model *UserModel) Exists() bool {
    method Save (line 203) | func (model *UserModel) Save() contracts.Exception {
    method Set (line 232) | func (model *UserModel) Set(fields contracts.Fields) {
    method Only (line 377) | func (model *UserModel) Only(key ...string) contracts.Fields {
    method Get (line 424) | func (model *UserModel) Get(key string) any {
    method Except (line 461) | func (model *UserModel) Except(keys ...string) contracts.Fields {
    method ToFields (line 476) | func (model *UserModel) ToFields() contracts.Fields {
    method Update (line 536) | func (model *UserModel) Update(fields contracts.Fields) contracts.Exce...
    method Refresh (line 561) | func (model *UserModel) Refresh() contracts.Exception {
    method Delete (line 571) | func (model *UserModel) Delete() contracts.Exception {
    method GetPrimaryKey (line 587) | func (model *UserModel) GetPrimaryKey() any {
    method GetAuthenticatableKey (line 594) | func (model *UserModel) GetAuthenticatableKey() string {
    method GetId (line 602) | func (model *UserModel) GetId() int64 {
    method SetId (line 609) | func (model *UserModel) SetId(value int64) {
    method GetName (line 622) | func (model *UserModel) GetName() string {
    method SetName (line 629) | func (model *UserModel) SetName(value string) {
    method GetAvatar (line 642) | func (model *UserModel) GetAvatar() string {
    method SetAvatar (line 649) | func (model *UserModel) SetAvatar(value string) {
    method GetOpenId (line 662) | func (model *UserModel) GetOpenId() string {
    method SetOpenId (line 669) | func (model *UserModel) SetOpenId(value string) {
    method GetWechatInfo (line 682) | func (model *UserModel) GetWechatInfo() *user.WechatInfoData {
    method SetWechatInfo (line 689) | func (model *UserModel) SetWechatInfo(value *user.WechatInfoData) {
    method GetChannel (line 702) | func (model *UserModel) GetChannel() string {
    method SetChannel (line 709) | func (model *UserModel) SetChannel(value string) {
    method GetPassword (line 722) | func (model *UserModel) GetPassword() string {
    method SetPassword (line 729) | func (model *UserModel) SetPassword(value string) {
    method GetCreatedAt (line 742) | func (model *UserModel) GetCreatedAt() string {
    method SetCreatedAt (line 749) | func (model *UserModel) SetCreatedAt(value string) {
    method GetUpdatedAt (line 762) | func (model *UserModel) GetUpdatedAt() string {
    method SetUpdatedAt (line 769) | func (model *UserModel) SetUpdatedAt(value string) {
  type UserStatic (line 60) | type UserStatic struct
  function UserMigrator (line 94) | func UserMigrator() migrate.Migrator {
  function init (line 100) | func init() {
  function NewUserModel (line 113) | func NewUserModel(fields contracts.Fields) *UserModel {
  function UserModelSingleRelationSetter (line 121) | func UserModelSingleRelationSetter[T any](key contracts.RelationType) fu...
  function UserModelMultiRelationSetter (line 132) | func UserModelMultiRelationSetter[T any](key contracts.RelationType) fun...
  function UserModelLocalKeyGetter (line 142) | func UserModelLocalKeyGetter(key string) func(item *UserModel) any {
  function UserModelRelationGetter (line 148) | func UserModelRelationGetter[T any](query func() *table.Table[T], foreig...
  function UserModelThroughRelationGetter (line 158) | func UserModelThroughRelationGetter[T any](query func() *table.Table[T],...
  function UserQueryWithExecutor (line 172) | func UserQueryWithExecutor(executor contracts.SqlExecutor) *table.Table[...
  function UserQuery (line 176) | func UserQuery() *table.Table[UserModel] {
  function UserAuthProvider (line 598) | func UserAuthProvider(identify string) contracts.Authenticatable {

FILE: app/models/project.go
  function init (line 3) | func init() {

FILE: app/models/project/GetProjectRessult_gen.go
  type GetProjectRessult (line 15) | type GetProjectRessult struct

FILE: app/models/user/WechatInfoData_gen.go
  type WechatInfoData (line 13) | type WechatInfoData struct

FILE: app/providers/app.go
  type appServiceProvider (line 12) | type appServiceProvider struct
    method Register (line 27) | func (app appServiceProvider) Register(instance contracts.Application) {
    method Start (line 44) | func (app appServiceProvider) Start() error {
    method Stop (line 48) | func (app appServiceProvider) Stop() {
  function NewApp (line 16) | func NewApp() contracts.ServiceProvider {

FILE: app/providers/console.go
  type Console (line 7) | type Console struct
    method Register (line 19) | func (c Console) Register(application contracts.Application) {
    method Start (line 29) | func (c Console) Start() error {
    method Stop (line 33) | func (c Console) Stop() {
  function NewConsoleService (line 12) | func NewConsoleService(commands []contracts.CommandProvider, schedule fu...

FILE: app/providers/events.go
  type EventsServiceProvider (line 9) | type EventsServiceProvider struct
    method Stop (line 21) | func (provider EventsServiceProvider) Stop() {
    method Start (line 25) | func (provider EventsServiceProvider) Start() error {
    method Register (line 29) | func (provider EventsServiceProvider) Register(container contracts.App...
  function NewEvents (line 13) | func NewEvents() contracts.ServiceProvider {

FILE: app/requests/project/CreateProject_gen.go
  type CreateProjectReq (line 15) | type CreateProjectReq struct
    method ToFields (line 27) | func (model *CreateProjectReq) ToFields() contracts.Fields {

FILE: app/requests/project/DeleteProject_gen.go
  type DeleteProjectReq (line 15) | type DeleteProjectReq struct
    method ToFields (line 19) | func (model *DeleteProjectReq) ToFields() contracts.Fields {

FILE: app/requests/project/GetProject_gen.go
  type GetProjectReq (line 15) | type GetProjectReq struct
    method ToFields (line 19) | func (model *GetProjectReq) ToFields() contracts.Fields {

FILE: app/requests/project/ListProjects_gen.go
  type ListProjectsReq (line 15) | type ListProjectsReq struct
    method ToFields (line 20) | func (model *ListProjectsReq) ToFields() contracts.Fields {

FILE: app/requests/project/UpdateProject_gen.go
  type UpdateProjectReq (line 15) | type UpdateProjectReq struct
    method ToFields (line 28) | func (model *UpdateProjectReq) ToFields() contracts.Fields {

FILE: app/requests/user/LoginByWxCode_gen.go
  type LoginByWxCodeReq (line 15) | type LoginByWxCodeReq struct
    method ToFields (line 19) | func (model *LoginByWxCodeReq) ToFields() contracts.Fields {

FILE: app/requests/user/LoginByWxInfo_gen.go
  type LoginByWxInfoReq (line 15) | type LoginByWxInfoReq struct
    method ToFields (line 21) | func (model *LoginByWxInfoReq) ToFields() contracts.Fields {

FILE: app/response/utils.go
  function ParseReqErr (line 9) | func ParseReqErr(err error) any {
  function InvalidReq (line 18) | func InvalidReq(err error) any {
  function BizErr (line 27) | func BizErr(err error) any {
  function Success (line 36) | func Success(data any) any {

FILE: app/results/ResponseResult_gen.go
  type ResponseResult (line 15) | type ResponseResult struct
    method ToFields (line 22) | func (result *ResponseResult) ToFields() contracts.Fields {

FILE: app/results/project/CreateProjectResult_gen.go
  type CreateProjectResult (line 15) | type CreateProjectResult struct
    method ToFields (line 19) | func (result *CreateProjectResult) ToFields() contracts.Fields {

FILE: app/results/project/DeleteProjectResult_gen.go
  type DeleteProjectResult (line 15) | type DeleteProjectResult struct
    method ToFields (line 19) | func (result *DeleteProjectResult) ToFields() contracts.Fields {

FILE: app/results/project/GetProjectResult_gen.go
  type GetProjectResult (line 16) | type GetProjectResult struct
    method ToFields (line 20) | func (result *GetProjectResult) ToFields() contracts.Fields {

FILE: app/results/project/ListProjectsResult_gen.go
  type ListProjectsResult (line 16) | type ListProjectsResult struct
    method ToFields (line 21) | func (result *ListProjectsResult) ToFields() contracts.Fields {

FILE: app/results/project/UpdateProjectResult_gen.go
  type UpdateProjectResult (line 15) | type UpdateProjectResult struct
    method ToFields (line 19) | func (result *UpdateProjectResult) ToFields() contracts.Fields {

FILE: app/results/user/LoginByWxResult_gen.go
  type LoginByWxResult (line 16) | type LoginByWxResult struct
    method ToFields (line 22) | func (result *LoginByWxResult) ToFields() contracts.Fields {

FILE: app/services/project/Project_gen.go
  type ProjectServiceStatic (line 19) | type ProjectServiceStatic struct
  function ProjectServiceCreateProject (line 27) | func ProjectServiceCreateProject(req *project.CreateProjectReq, ctx cont...
  function ProjectServiceGetProject (line 34) | func ProjectServiceGetProject(req *project.GetProjectReq, ctx contracts....
  function ProjectServiceListProjects (line 41) | func ProjectServiceListProjects(req *project.ListProjectsReq, ctx contra...
  function ProjectServiceUpdateProject (line 48) | func ProjectServiceUpdateProject(req *project.UpdateProjectReq, ctx cont...
  function ProjectServiceDeleteProject (line 55) | func ProjectServiceDeleteProject(req *project.DeleteProjectReq, ctx cont...

FILE: app/services/project/project.go
  function init (line 9) | func init() {

FILE: app/services/user/Auth_gen.go
  type AuthServiceStatic (line 19) | type AuthServiceStatic struct
  function AuthServiceLoginByWxAppCode (line 24) | func AuthServiceLoginByWxAppCode(req *user.LoginByWxCodeReq, ctx contrac...
  function AuthServiceLoginByWxAppInfo (line 31) | func AuthServiceLoginByWxAppInfo(req *user.LoginByWxInfoReq, ctx contrac...

FILE: app/websocket/demo.go
  type DemoController (line 8) | type DemoController struct
    method OnConnect (line 11) | func (d DemoController) OnConnect(request contracts.HttpRequest, fd ui...
    method OnMessage (line 16) | func (d DemoController) OnMessage(frame contracts.WebSocketFrame) {
    method OnClose (line 20) | func (d DemoController) OnClose(fd uint64) {

FILE: bootstrap/console/main.go
  function main (line 8) | func main() {

FILE: bootstrap/core/application.go
  type App (line 33) | type App struct
  function Application (line 38) | func Application(c ...App) contracts.Application {

FILE: bootstrap/queue/main.go
  function main (line 8) | func main() {

FILE: bootstrap/schedule/main.go
  function main (line 8) | func main() {

FILE: config/app.go
  function GetConfigProviders (line 10) | func GetConfigProviders() map[string]contracts.ConfigProvider {
  function init (line 14) | func init() {

FILE: config/auth.go
  function init (line 11) | func init() {

FILE: config/bloomfilter.go
  function init (line 8) | func init() {

FILE: config/cache.go
  function init (line 11) | func init() {

FILE: config/database.go
  function init (line 9) | func init() {

FILE: config/encryption.go
  function init (line 8) | func init() {

FILE: config/filesystem.go
  function init (line 9) | func init() {

FILE: config/http.go
  function init (line 8) | func init() {

FILE: config/mail.go
  function init (line 8) | func init() {

FILE: config/queue.go
  function init (line 10) | func init() {

FILE: config/redis.go
  function init (line 9) | func init() {

FILE: config/serialization.go
  function init (line 9) | func init() {

FILE: config/session.go
  function init (line 9) | func init() {

FILE: config/views.go
  function init (line 8) | func init() {

FILE: config/websocket.go
  function init (line 9) | func init() {

FILE: database/migrations/2024_05_09_141932_create_articles.sql
  type articles (line 1) | CREATE TABLE IF NOT EXISTS articles

FILE: main.go
  function main (line 19) | func main() {

FILE: pro/goal-cli.go
  function main (line 12) | func main() {
  function scanProtoFiles (line 47) | func scanProtoFiles(root string) ([]string, error) {

FILE: routes/api.go
  function Api (line 8) | func Api(router contracts.HttpRouter) {

FILE: routes/sse.go
  function Sse (line 9) | func Sse(router contracts.HttpRouter) {

FILE: routes/ws.go
  function WebSocket (line 10) | func WebSocket(router contracts.HttpRouter) {

FILE: tests/bootstrap.go
  function initApp (line 8) | func initApp() contracts.Application {

FILE: tests/bootstrap_test.go
  function TestBootstrap (line 5) | func TestBootstrap(t *testing.T) {

FILE: tests/db_test.go
  function TestModel (line 7) | func TestModel(t *testing.T) {
Condensed preview — 96 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (224K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE.MD",
    "chars": 892,
    "preview": "<!-- Please answer these questions before submitting your issue. Thanks! -->\n\n<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小"
  },
  {
    "path": ".gitignore",
    "chars": 58,
    "preview": ".idea\ndatabase/*.sqlite\n*.pid\n\n/bin*\n\n\ngo.work\ngo.work.sum"
  },
  {
    "path": "Dockerfile",
    "chars": 327,
    "preview": "FROM golang:1.20 as builder\nLABEL maintainer=\"qbhy <qbhy0715@qq.com>\"\n\nWORKDIR /app\n\nCOPY . /app\nENV CGO_ENABLED=0\nENV G"
  },
  {
    "path": "LICENSE",
    "chars": 1061,
    "preview": "MIT License\n\nCopyright (c) 2021 桥边红药\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof th"
  },
  {
    "path": "Makefile",
    "chars": 595,
    "preview": "DOCKER_TAG=goal\n\ngen:\n\tgo run pro/goal-cli.go --template template.tmpl\n\nrun:\n\tgo run main.go run\n\nbuild:\n\tgo build -o ./"
  },
  {
    "path": "README.md",
    "chars": 2720,
    "preview": "# Goal Framework\n[![codecov](https://codecov.io/gh/goal-web/goal/branch/master/graph/badge.svg)](https://codecov.io/gh/g"
  },
  {
    "path": "app/console/commands/runner.go",
    "chars": 809,
    "preview": "package commands\n\nimport (\n\t\"fmt\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/supports/commands\"\n\t\"github.com"
  },
  {
    "path": "app/console/kernel.go",
    "chars": 426,
    "preview": "package console\n\nimport (\n\t\"github.com/goal-web/config\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/"
  },
  {
    "path": "app/controllers/helloworld.go",
    "chars": 1524,
    "preview": "package controllers\n\nimport (\n\t\"fmt\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/models\"\n\t\"github.co"
  },
  {
    "path": "app/controllers/kernel.go",
    "chars": 322,
    "preview": "package controllers\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/controllers/project\"\n\t\"git"
  },
  {
    "path": "app/controllers/project/Project_gen.go",
    "chars": 2915,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/controllers/user/Auth_gen.go",
    "chars": 1482,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/enums/Code_gen.go",
    "chars": 1582,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/exceptions/handler.go",
    "chars": 1996,
    "preview": "package exceptions\n\nimport (\n\t\"reflect\"\n\t\"runtime/debug\"\n\t\"strings\"\n\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-"
  },
  {
    "path": "app/http/middlewares/example.go",
    "chars": 344,
    "preview": "package middlewares\n\nimport (\n\t\"fmt\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/http\"\n)\n\nfunc Example(reques"
  },
  {
    "path": "app/http/sse/demo.go",
    "chars": 363,
    "preview": "package sse\n\nimport (\n\t\"errors\"\n\t\"github.com/goal-web/contracts\"\n)\n\ntype DemoController struct {\n}\n\nfunc (d DemoControll"
  },
  {
    "path": "app/jobs/demo.go",
    "chars": 672,
    "preview": "package jobs\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/queue\"\n\t\"github.com/goal-web/supports/clas"
  },
  {
    "path": "app/listeners/debug_query.go",
    "chars": 446,
    "preview": "package listeners\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/database/events\"\n\t\"github.com/goal-we"
  },
  {
    "path": "app/models/Article_gen.go",
    "chars": 12968,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/models/Project_gen.go",
    "chars": 23752,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/models/User_gen.go",
    "chars": 19373,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/models/project/GetProjectRessult_gen.go",
    "chars": 357,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/models/project.go",
    "chars": 177,
    "preview": "package models\n\nfunc init() {\n\tProjectDefine.Appends = map[string]func(model *ProjectModel) any{\n\t\t\"id-plus-1\": func(mod"
  },
  {
    "path": "app/models/user/WechatInfoData_gen.go",
    "chars": 758,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/providers/app.go",
    "chars": 1157,
    "preview": "package providers\n\nimport (\n\t\"github.com/goal-web/application\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/go"
  },
  {
    "path": "app/providers/console.go",
    "chars": 704,
    "preview": "package providers\n\nimport (\n\t\"github.com/goal-web/contracts\"\n)\n\ntype Console struct {\n\tCommands []contracts.CommandProvi"
  },
  {
    "path": "app/providers/events.go",
    "chars": 864,
    "preview": "package providers\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\tevents2 \"github.com/goal-web/database/events\"\n\t\"github.com"
  },
  {
    "path": "app/requests/project/CreateProject_gen.go",
    "chars": 1411,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/requests/project/DeleteProject_gen.go",
    "chars": 474,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/requests/project/GetProject_gen.go",
    "chars": 468,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/requests/project/ListProjects_gen.go",
    "chars": 585,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/requests/project/UpdateProject_gen.go",
    "chars": 1496,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/requests/user/LoginByWxCode_gen.go",
    "chars": 480,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/requests/user/LoginByWxInfo_gen.go",
    "chars": 734,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/response/utils.go",
    "chars": 1079,
    "preview": "package response\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/enums\"\n\t\"github.com/goal-web/"
  },
  {
    "path": "app/results/ResponseResult_gen.go",
    "chars": 766,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/results/project/CreateProjectResult_gen.go",
    "chars": 461,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/results/project/DeleteProjectResult_gen.go",
    "chars": 461,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/results/project/GetProjectResult_gen.go",
    "chars": 532,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/results/project/ListProjectsResult_gen.go",
    "chars": 826,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/results/project/UpdateProjectResult_gen.go",
    "chars": 461,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/results/user/LoginByWxResult_gen.go",
    "chars": 740,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/services/project/Project_gen.go",
    "chars": 2233,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/services/project/project.go",
    "chars": 376,
    "preview": "package project\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/requests/project\"\n\tproject0 \"g"
  },
  {
    "path": "app/services/user/Auth_gen.go",
    "chars": 1102,
    "preview": "// Code generated by goal-cli. DO NOT EDIT.\n// versions:\n// \tgoal-cli v0.5.24\n// \tgo       go1.24.0\n//\n// updated_at: 20"
  },
  {
    "path": "app/websocket/demo.go",
    "chars": 457,
    "preview": "package websocket\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/supports/logs\"\n)\n\ntype DemoController"
  },
  {
    "path": "bootstrap/console/main.go",
    "chars": 247,
    "preview": "package main\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/bootstrap/core\"\n)\n\nfunc main() {\n\tapp"
  },
  {
    "path": "bootstrap/core/application.go",
    "chars": 2257,
    "preview": "package core\n\nimport (\n\t\"github.com/goal-web/application\"\n\t\"github.com/goal-web/bloomfilter\"\n\t\"github.com/goal-web/cache"
  },
  {
    "path": "bootstrap/queue/main.go",
    "chars": 328,
    "preview": "package main\n\nimport (\n\t\"github.com/goal-web/goal/bootstrap/core\"\n\t\"github.com/goal-web/supports/logs\"\n)\n\nfunc main() {\n"
  },
  {
    "path": "bootstrap/schedule/main.go",
    "chars": 333,
    "preview": "package main\n\nimport (\n\t\"github.com/goal-web/goal/bootstrap/core\"\n\t\"github.com/goal-web/supports/logs\"\n)\n\nfunc main() {\n"
  },
  {
    "path": "config/README_cache_config.md",
    "chars": 3882,
    "preview": "# 缓存配置说明\n\n## 概述\n\n本文档说明了Goal Web框架中缓存组件的配置选项和使用方法。\n\n## 配置结构\n\n缓存配置支持三种驱动:\n- **memory**: 内存缓存(RAM驱动)\n- **file**: 文件缓存\n- **r"
  },
  {
    "path": "config/app.go",
    "chars": 579,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/application\"\n\t\"github.com/goal-web/contracts\"\n)\n\nvar configs = make(map[s"
  },
  {
    "path": "config/auth.go",
    "chars": 933,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/auth\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/mod"
  },
  {
    "path": "config/bloomfilter.go",
    "chars": 703,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/bloomfilter\"\n\t\"github.com/goal-web/contracts\"\n)\n\nfunc init() {\n\tconfigs[\""
  },
  {
    "path": "config/cache.go",
    "chars": 879,
    "preview": "package config\n\nimport (\n\t\"time\"\n\n\t\"github.com/goal-web/cache\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/su"
  },
  {
    "path": "config/cache_example.toml",
    "chars": 361,
    "preview": "# 缓存配置示例\n# Cache Configuration Example\n\n# 默认缓存驱动\ncache.default = \"memory\"\n\n# 缓存键前缀\ncache.prefix = \"goal_\"\n\n# 默认缓存TTL(秒)\n"
  },
  {
    "path": "config/database.go",
    "chars": 2626,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/database\"\n\t\"strings\"\n)\n\nfunc init() {\n\tc"
  },
  {
    "path": "config/encryption.go",
    "chars": 270,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/encryption\"\n)\n\nfunc init() {\n\tconfigs[\"e"
  },
  {
    "path": "config/filesystem.go",
    "chars": 851,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/filesystem\"\n\t\"os\"\n)\n\nfunc init() {\n\tconf"
  },
  {
    "path": "config/http.go",
    "chars": 463,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/http\"\n)\n\nfunc init() {\n\tconfigs[\"http\"] "
  },
  {
    "path": "config/mail.go",
    "chars": 595,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/email\"\n)\n\nfunc init() {\n\tconfigs[\"mail\"]"
  },
  {
    "path": "config/queue.go",
    "chars": 1773,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/queue\"\n\t\"github.com/nsqio/go-nsq\"\n\t\"stri"
  },
  {
    "path": "config/redis.go",
    "chars": 1093,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/redis\"\n\t\"github.com/goal-web/supports/ut"
  },
  {
    "path": "config/serialization.go",
    "chars": 358,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/jobs\"\n\t\"github.com/goal-web/ser"
  },
  {
    "path": "config/session.go",
    "chars": 593,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/session\"\n\t\"time\"\n)\n\nfunc init() {\n\tconfi"
  },
  {
    "path": "config/views.go",
    "chars": 238,
    "preview": "package config\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/views\"\n)\n\nfunc init() {\n\tconfigs[\"views\""
  },
  {
    "path": "config/websocket.go",
    "chars": 528,
    "preview": "package config\n\nimport (\n\twebsocket2 \"github.com/fasthttp/websocket\"\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-"
  },
  {
    "path": "database/.gitignore",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "database/migrations/2024_05_09_141932_create_articles.down.sql",
    "chars": 29,
    "preview": "drop table if exists articles"
  },
  {
    "path": "database/migrations/2024_05_09_141932_create_articles.sql",
    "chars": 240,
    "preview": "CREATE TABLE IF NOT EXISTS articles\n(\n    `id`       INT UNSIGNED AUTO_INCREMENT,\n    title      varchar(20) not null,\n "
  },
  {
    "path": "env.toml",
    "chars": 1078,
    "preview": "[app]\nname = \"goal\"\nkey = \"dQcxsKvBZKNfWivwnhKlDwvseguknBZPEiiDRQlIatjKLLpbzK\"\nenv = \"local\"\ndebug = true\n\n[http]\nhost ="
  },
  {
    "path": "go.mod",
    "chars": 4151,
    "preview": "module github.com/goal-web/goal\n\ngo 1.25.0\n\nreplace github.com/goal-web/goal-cli => ../goal-cli\n\nrequire (\n\tgithub.com/a"
  },
  {
    "path": "go.sum",
    "chars": 38556,
    "preview": "github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=\ngithub.com/BurntSushi/toml v1.4.0/go.m"
  },
  {
    "path": "main.go",
    "chars": 940,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/controllers\"\n\t"
  },
  {
    "path": "pro/Article.proto",
    "chars": 174,
    "preview": "syntax = \"proto3\";\n\n\n//@table: articles\n//@timestamps\nmessage ArticleModel {\n    uint32 id = 1;\n    string title = 2;\n  "
  },
  {
    "path": "pro/Project.proto",
    "chars": 1789,
    "preview": "syntax = \"proto3\";\n\noption go_package = \"project\";\n\n//@timestamps\n//@table: projects\nmessage ProjectModel {\n  int64 id ="
  },
  {
    "path": "pro/common.proto",
    "chars": 395,
    "preview": "syntax = \"proto3\";\n\noption go_package = \".\";\n\nenum Code {\n  //@msg:成功\n  Success = 0;\n\n  //@msg:参数解析失败\n  ParseReqErr = 10"
  },
  {
    "path": "pro/goal-cli.go",
    "chars": 1445,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/goal-web/goal-cli/app/gen\"\n)\n\nfunc main() {\n\t"
  },
  {
    "path": "pro/user.proto",
    "chars": 1409,
    "preview": "syntax = \"proto3\";\n\noption go_package = \"user\";\n\nmessage WechatInfoData {\n  string city = 1;\n  int64 gender = 2;\n  strin"
  },
  {
    "path": "routes/api.go",
    "chars": 388,
    "preview": "package routes\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/app/controllers\"\n)\n\nfunc Api(router"
  },
  {
    "path": "routes/sse.go",
    "chars": 611,
    "preview": "package routes\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\tsse2 \"github.com/goal-web/goal/app/http/sse\"\n\t\"github.com/goa"
  },
  {
    "path": "routes/ws.go",
    "chars": 500,
    "preview": "package routes\n\nimport (\n\t\"fmt\"\n\t\"github.com/goal-web/contracts\"\n\twebsocket2 \"github.com/goal-web/goal/app/websocket\"\n\t\""
  },
  {
    "path": "sdk.tmpl",
    "chars": 2718,
    "preview": "{{- define \"request\" -}}\n{{- range .Imports }}\nimport {{ .Alias }} from \"{{ .Pkg }}\"\n{{- end }}\n\nexport default interfac"
  },
  {
    "path": "server.conf",
    "chars": 411,
    "preview": "server {\n    listen 80;\n\n    server_name example.com;\n\n    location = /favicon.ico { access_log off; log_not_found off; "
  },
  {
    "path": "storage/app/.gitignore",
    "chars": 21,
    "preview": "*\n!.gitignore\n!public"
  },
  {
    "path": "storage/framework/bloomfilter/.gitignore",
    "chars": 23,
    "preview": ".gitignore\n!.gitignore\n"
  },
  {
    "path": "storage/framework/cache/.gitignore",
    "chars": 23,
    "preview": ".gitignore\n!.gitignore\n"
  },
  {
    "path": "storage/framework/sessions/.gitignore",
    "chars": 23,
    "preview": ".gitignore\n!.gitignore\n"
  },
  {
    "path": "storage/logs/.gitignore",
    "chars": 14,
    "preview": "*\n!.gitignore\n"
  },
  {
    "path": "supervisor.conf",
    "chars": 164,
    "preview": "[program:goal-server]\ncommand=/opt/app/goal\nautostart=true\nautorestart=true\nuser=root\nnumprocs=1\nredirect_stderr=true\nst"
  },
  {
    "path": "template.tmpl",
    "chars": 29122,
    "preview": "{{- define \"model\" -}}\npackage {{ .Package }}\n\nimport (\n    \"encoding/json\"\n    \"github.com/goal-web/supports/logs\"\n    "
  },
  {
    "path": "tests/bootstrap.go",
    "chars": 250,
    "preview": "package tests\n\nimport (\n\t\"github.com/goal-web/contracts\"\n\t\"github.com/goal-web/goal/bootstrap/core\"\n)\n\nfunc initApp() co"
  },
  {
    "path": "tests/bootstrap_test.go",
    "chars": 81,
    "preview": "package tests\n\nimport \"testing\"\n\nfunc TestBootstrap(t *testing.T) {\n\tinitApp()\n}\n"
  },
  {
    "path": "tests/db_test.go",
    "chars": 82,
    "preview": "package tests\n\nimport (\n\t\"testing\"\n)\n\nfunc TestModel(t *testing.T) {\n\tinitApp()\n}\n"
  },
  {
    "path": "tests/env.toml",
    "chars": 1078,
    "preview": "[app]\nname = \"goal\"\nkey = \"dQcxsKvBZKNfWivwnhKlDwvseguknBZPEiiDRQlIatjKLLpbzK\"\nenv = \"local\"\ndebug = true\n\n[http]\nhost ="
  },
  {
    "path": "views/view.html",
    "chars": 213,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width"
  }
]

About this extraction

This page contains the full source code of the goal-web/goal GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 96 files (194.9 KB), approximately 68.3k tokens, and a symbol index with 266 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!