diff --git a/backend/go.mod b/backend/go.mod index 64eedf6..e8bbe56 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,18 +1,16 @@ module code-review-go -go 1.23.0 - -toolchain go1.23.11 +go 1.24.0 require ( - github.com/gin-contrib/cors v1.6.0 - github.com/gin-gonic/gin v1.10.1 - github.com/gorilla/websocket v1.5.1 + github.com/gin-contrib/cors v1.7.6 + github.com/gin-gonic/gin v1.11.0 + github.com/gorilla/websocket v1.5.3 github.com/joho/godotenv v1.5.1 github.com/swaggo/files v1.0.1 - github.com/swaggo/gin-swagger v1.6.0 - gorm.io/driver/mysql v1.5.1 - gorm.io/gorm v1.25.4 + github.com/swaggo/gin-swagger v1.6.1 + gorm.io/driver/mysql v1.6.0 + gorm.io/gorm v1.31.1 ) require github.com/golang-jwt/jwt/v4 v4.5.2 @@ -20,55 +18,65 @@ require github.com/golang-jwt/jwt/v4 v4.5.2 require github.com/hashicorp/golang-lru/v2 v2.0.7 require ( - github.com/bytedance/sonic/loader v0.1.1 // indirect - github.com/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic/loader v0.4.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect + github.com/goccy/go-yaml v1.19.0 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.57.1 // indirect + go.uber.org/mock v0.6.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/sync v0.19.0 // indirect ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 ) require ( github.com/KyleBanks/depth v1.2.1 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/bytedance/sonic v1.11.6 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect - github.com/go-openapi/spec v0.20.4 // indirect - github.com/go-openapi/swag v0.19.15 // indirect + github.com/bytedance/sonic v1.14.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.11 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/spec v0.22.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.20.0 // indirect - github.com/go-sql-driver/mysql v1.7.1 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/golang-jwt/jwt/v5 v5.2.2 + github.com/go-playground/validator/v10 v10.28.0 // indirect + github.com/go-sql-driver/mysql v1.9.3 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/golang-jwt/jwt/v5 v5.3.0 github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/swaggo/swag v1.16.3 + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/swaggo/swag v1.16.6 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/protobuf v1.34.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + github.com/ugorji/go/codec v1.3.1 // indirect + golang.org/x/arch v0.23.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect + golang.org/x/tools v0.40.0 // indirect + google.golang.org/protobuf v1.36.10 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/backend/go.sum b/backend/go.sum index 994c972..2ab7248 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -1,63 +1,79 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= -github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= -github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= -github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE= +github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980= +github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o= +github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= 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/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= -github.com/gin-contrib/cors v1.6.0 h1:0Z7D/bVhE6ja07lI8CTjTonp6SB07o8bNuFyRbsBUQg= -github.com/gin-contrib/cors v1.6.0/go.mod h1:cI+h6iOAyxKRtUtC6iF/Si1KSFvGm/gK+kshxlCi8ro= +github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik= +github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/gin-contrib/cors v1.7.6 h1:3gQ8GMzs1Ylpf70y8bMw4fVpycXIeX1ZemuSQIsnQQY= +github.com/gin-contrib/cors v1.7.6/go.mod h1:Ulcl+xN4jel9t1Ry8vqph23a60FwH9xVLd+3ykmTjOk= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= -github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/spec v0.22.2 h1:KEU4Fb+Lp1qg0V4MxrSCPv403ZjBl8Lx1a83gIPU8Qc= +github.com/go-openapi/spec v0.22.2/go.mod h1:iIImLODL2loCh3Vnox8TY2YWYJZjMAKYyLH2Mu8lOZs= github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= -github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688= +github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.19.0 h1:EmkZ9RIsX+Uq4DYFowegAuJo8+xdX3T/2dwNPXbxEYE= +github.com/goccy/go-yaml v1.19.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -66,27 +82,16 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -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/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -94,103 +99,96 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= 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/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10= +github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 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.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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= -github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= -github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= -github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= -github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= +github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY= +github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw= +github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI= +github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= -github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= +github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= -golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg= +golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 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-20200227125254-8fa46927fb4f/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/yaml.v2 v2.2.2/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-20200615113413-eeeca48fe776/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= -gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= -gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= -gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= -gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= +gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= +gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= +gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/backend/internal/dto/ai_check.go b/backend/internal/dto/ai_check.go index 3b370de..8803a24 100644 --- a/backend/internal/dto/ai_check.go +++ b/backend/internal/dto/ai_check.go @@ -1,12 +1,23 @@ package dto type ProjectInfo struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - PathWithNamespace string `json:"path_with_namespace"` + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebUrl string `json:"web_url"` + AvatarUrl interface{} `json:"avatar_url"` + GitSshUrl string `json:"git_ssh_url"` + GitHttpUrl string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CiConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + Url string `json:"url"` + SshUrl string `json:"ssh_url"` + HttpUrl string `json:"http_url"` } - type ObjectAttributes struct { IID int `json:"iid"` URL string `json:"url"` @@ -28,6 +39,13 @@ type WebhookBody struct { Project ProjectInfo `json:"project"` ObjectAttributes ObjectAttributes `json:"object_attributes"` MergeRequest MergeRequest `json:"merge_request,omitempty"` + User struct { + Id int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + AvatarUrl string `json:"avatar_url"` + Email string `json:"email"` + } `json:"user"` // Push 事件专用字段 Ref string `json:"ref,omitempty"` // 分支引用 diff --git a/backend/internal/model/ai_check.go b/backend/internal/model/ai_check.go index d65ce07..5e72813 100644 --- a/backend/internal/model/ai_check.go +++ b/backend/internal/model/ai_check.go @@ -19,6 +19,7 @@ type MergeRequestInfo struct { UpdatedAt string `json:"updated_at"` SourceBranch string `json:"source_branch"` TargetBranch string `json:"target_branch"` + Sha string `json:"sha"` User struct { ID int `json:"id"` Name string `json:"name"` diff --git a/backend/internal/service/ai/ai_message_service.go b/backend/internal/service/ai/ai_message_service.go index a9eed44..21d56b3 100644 --- a/backend/internal/service/ai/ai_message_service.go +++ b/backend/internal/service/ai/ai_message_service.go @@ -2,6 +2,7 @@ package ai import ( "bytes" + "encoding/json" "fmt" "io" "net/http" @@ -12,7 +13,6 @@ import ( dto "code-review-go/internal/dto" "code-review-go/internal/model" - "code-review-go/internal/pkg/utils" ) // AIMessageService AI消息服务 @@ -164,15 +164,28 @@ func (s *AIMessageService) CreateAIMessage(data *model.AIMessage) (uint, error) // SendMarkdownToWechatBot 向企业微信机器人发送 Markdown 消息 func SendMarkdownToWechatBot(webhookURL, markdownContent string) error { // 构造请求体 + + if len(markdownContent) > 3800 { + // 按rune截取,避免截断字符 + runes := []rune(markdownContent) + if len(runes) > 3800 { + markdownContent = string(runes[:3800]) + markdownContent += "......" + } + } payload := map[string]interface{}{ - "msgtype": "markdown", - "markdown": map[string]string{ + "msgtype": "markdown_v2", + "markdown_v2": map[string]string{ "content": markdownContent, }, } + marshal, err := json.Marshal(payload) + if err != nil { + fmt.Errorf(" json.Marsha error: %v", err) + } // 发送 POST 请求 - resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(utils.MustMarshal(payload))) + resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(marshal)) if err != nil { return fmt.Errorf("发送失败: %v", err) } diff --git a/backend/internal/service/ai/ai_service.go b/backend/internal/service/ai/ai_service.go index b499786..4157227 100644 --- a/backend/internal/service/ai/ai_service.go +++ b/backend/internal/service/ai/ai_service.go @@ -45,7 +45,7 @@ func (a *AIServiceImpl) Initialize() error { } // CallAI 调用AI服务 -func (a *AIServiceImpl) CallAI(prompt string) (string, error) { +func (a *AIServiceImpl) CallAI(prompt []map[string]string) (string, error) { a.mu.RLock() if !a.initialized { a.mu.RUnlock() diff --git a/backend/internal/service/ai/providers/deepseek_provider.go b/backend/internal/service/ai/providers/deepseek_provider.go index 19fb104..fd61802 100644 --- a/backend/internal/service/ai/providers/deepseek_provider.go +++ b/backend/internal/service/ai/providers/deepseek_provider.go @@ -22,15 +22,12 @@ func NewDeepSeekProvider(config *model.AIConfig) *DeepSeekProvider { } // CallAI 调用DeepSeek接口 -func (p *DeepSeekProvider) CallAI(prompt string) (string, error) { +func (p *DeepSeekProvider) CallAI(prompt []map[string]string) (string, error) { fmt.Println("p.config.APIURL", p.config) requestBody := map[string]interface{}{ - "model": p.config.Model, - "messages": []map[string]string{ - {"role": "system", "content": "你是一个专业的代码审核机器人,请仔细检查代码并提供详细的改进建议。"}, - {"role": "user", "content": prompt}, - }, - "stream": false, + "model": p.config.Model, + "messages": prompt, + "stream": false, } fmt.Println("requestBody", requestBody) diff --git a/backend/internal/service/ai/providers/factory.go b/backend/internal/service/ai/providers/factory.go index 237976c..f3691c3 100644 --- a/backend/internal/service/ai/providers/factory.go +++ b/backend/internal/service/ai/providers/factory.go @@ -7,7 +7,7 @@ import ( // AIProvider AI提供者接口 type AIProvider interface { - CallAI(prompt string) (string, error) + CallAI([]map[string]string) (string, error) } // AIProviderFactory AI提供者工厂 diff --git a/backend/internal/service/ai/providers/qwen_provider.go b/backend/internal/service/ai/providers/qwen_provider.go index 61fa44c..eada085 100644 --- a/backend/internal/service/ai/providers/qwen_provider.go +++ b/backend/internal/service/ai/providers/qwen_provider.go @@ -22,16 +22,21 @@ func NewQwenProvider(config *model.AIConfig) *QwenProvider { } // CallAI 调用通义千问接口 -func (p *QwenProvider) CallAI(prompt string) (string, error) { +func (p *QwenProvider) CallAI(prompt []map[string]string) (string, error) { fmt.Printf("通义千问配置: URL=%s, Model=%s, Type=%s\n", p.config.APIURL, p.config.Model, p.config.Type) - requestBody := map[string]interface{}{ - "model": p.config.Model, - "messages": []map[string]string{ + /** + []map[string]string{ {"role": "system", "content": "你是一个专业的代码审核机器人,请仔细检查代码并提供详细的改进建议。"}, {"role": "user", "content": prompt}, - }, - "stream": false, + } + */ + requestBody := map[string]interface{}{ + "model": p.config.Model, + "messages": prompt, + "stream": false, + "temperature": 0.1, + "top_p": 0.8, } fmt.Printf("请求体: %+v\n", requestBody) @@ -58,8 +63,8 @@ func (p *QwenProvider) CallAI(prompt string) (string, error) { // 读取响应体用于错误调试 body, _ := io.ReadAll(resp.Body) - // fmt.Printf("响应状态码: %d\n", resp.StatusCode) - // fmt.Printf("响应体: %s\n", string(body)) + fmt.Printf("响应状态码: %d\n", resp.StatusCode) + fmt.Printf("响应体: %s\n", string(body)) if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("通义千问 API返回错误: %s, 状态码: %d", string(body), resp.StatusCode) diff --git a/backend/internal/service/ai/providers/ucai_provider.go b/backend/internal/service/ai/providers/ucai_provider.go index e6015cf..a43c943 100644 --- a/backend/internal/service/ai/providers/ucai_provider.go +++ b/backend/internal/service/ai/providers/ucai_provider.go @@ -22,13 +22,10 @@ func NewUCAIProvider(config *model.AIConfig) *UCAIProvider { } // CallAI 调用UCAI接口 -func (p *UCAIProvider) CallAI(prompt string) (string, error) { +func (p *UCAIProvider) CallAI(prompt []map[string]string) (string, error) { requestBody := map[string]interface{}{ - "model": p.config.Model, - "messages": []map[string]string{ - {"role": "system", "content": "你是一个专业的代码审核机器人,请仔细检查代码并提供详细的改进建议。"}, - {"role": "user", "content": prompt}, - }, + "model": p.config.Model, + "messages": prompt, "temperature": 0.7, "max_tokens": 2000, } diff --git a/backend/internal/service/common/interfaces.go b/backend/internal/service/common/interfaces.go index eefde78..ce554e9 100644 --- a/backend/internal/service/common/interfaces.go +++ b/backend/internal/service/common/interfaces.go @@ -34,7 +34,7 @@ type AIService interface { // 初始化AI服务 Initialize() error // 调用AI服务 - CallAI(prompt string) (string, error) + CallAI(prompt []map[string]string) (string, error) // 检查是否已初始化 IsInitialized() bool } @@ -50,7 +50,7 @@ type NotificationService interface { // 发送增强通知 SendEnhancedNotification(api, token string, projectID, mergeRequestID int, comments string, commentType int8, diff []model.Change) error // 发送Webhook通知 - SendWebhookNotification(webhookURL string, status int, projectNamespace, mergeURL, comments string, aiMessageID uint, mergeRequest *model.MergeRequestInfo) error + SendWebhookNotification(webhookURL string, dto dto.WebhookBody, comments string, mergeRequest *model.MergeRequestInfo) error // 发送Push事件评论 SendPushEventComment(api, token string, projectID int, commitSHA, title, comments string, commentType int8) error // 为多个commit发送Push事件评论 diff --git a/backend/internal/service/gitlab_service/gitlab_service.go b/backend/internal/service/gitlab_service/gitlab_service.go index a368448..304b8f8 100644 --- a/backend/internal/service/gitlab_service/gitlab_service.go +++ b/backend/internal/service/gitlab_service/gitlab_service.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "net/http" + "os" "strconv" "strings" "time" @@ -443,7 +444,25 @@ func GetMergeRequestDiff(gitlabAPI, projectID, mergeRequestID, gitlabToken strin return nil, fmt.Errorf("解析响应失败: %v", err) } - return diff.Changes, nil + var changes []model.Change + for _, item := range diff.Changes { + //过滤一下 + if strings.HasPrefix(item.Diff, "Binary files") { + fmt.Printf("过滤掉二进制文件:%v\n", item.NewPath) + continue + } + if item.Diff == "" { + fmt.Printf("过滤掉空文件变更:%v\n", item.NewPath) + continue + } + + if !isCodeFile(item.NewPath) { + fmt.Printf("过滤掉非代码文件或忽略文件:%v\n", item.NewPath) + continue + } + changes = append(changes, item) + } + return changes, nil } // CommentResponse GitLab评论响应 @@ -800,7 +819,7 @@ func PostLineComments(gitlabAPI string, projectID, mergeRequestID int, gitlabTok return failedComments, nil } -// 通过id获取Gitlab Token 详情,不返回token +// GetGitlabTokenDetail 通过id获取Gitlab Token 详情,不返回token func (s *GitlabService) GetGitlabTokenDetail(id uint) (*model.GitlabInfo, error) { var gitlabInfo model.GitlabInfo if err := s.db.First(&gitlabInfo, id).Error; err != nil { @@ -863,6 +882,10 @@ func GetCommitCodeContent(gitlabAPI string, projectID int, commitSHA, gitlabToke var codeFiles []string for _, item := range treeResponse { if item.Type == "blob" && isCodeFile(item.Name) { + if strings.HasPrefix(item.Name, ".") || strings.HasPrefix(item.Path, ".") { + fmt.Printf("❌ 文件/目录以.开头忽略 %s: \n", item.Path) + continue + } codeFiles = append(codeFiles, item.Path) } } @@ -920,6 +943,10 @@ func GetBranchCodeContent(gitlabAPI string, projectID int, branchName, gitlabTok // 过滤出代码文件(排除目录和二进制文件) var codeFiles []string for _, item := range treeResponse { + if strings.HasPrefix(item.Name, ".") || strings.HasPrefix(item.Path, ".") { + fmt.Printf("❌ 文件/目录以.开头忽略 %s: \n", item.Path) + continue + } if item.Type == "blob" && isCodeFile(item.Name) { codeFiles = append(codeFiles, item.Path) fmt.Printf("✅ 识别为代码文件: %s\n", item.Path) @@ -976,6 +1003,7 @@ func getFileContent(gitlabAPI string, projectID int, commitSHA, filePath, gitlab // isCodeFile 判断是否为代码文件 func isCodeFile(filename string) bool { // 定义代码文件扩展名 + codeExtensions := map[string]bool{ ".go": true, ".js": true, @@ -1010,10 +1038,20 @@ func isCodeFile(filename string) bool { ".makefile": true, } + value := os.Getenv("IGNORE_EXT") + if value != "" { + extArray := strings.Split(value, ",") + for _, ext := range extArray { + if codeExtensions[ext] == true { + codeExtensions[ext] = false + } + } + } + // 检查文件扩展名 for ext := range codeExtensions { if strings.HasSuffix(strings.ToLower(filename), ext) { - return true + return codeExtensions[ext] } } diff --git a/backend/internal/service/gitlab_service/notification_service.go b/backend/internal/service/gitlab_service/notification_service.go index 232b84a..ddea92d 100644 --- a/backend/internal/service/gitlab_service/notification_service.go +++ b/backend/internal/service/gitlab_service/notification_service.go @@ -9,6 +9,7 @@ import ( "fmt" "strings" "sync" + "time" ) // NotificationServiceImpl 通知服务实现 @@ -48,18 +49,20 @@ func (n *NotificationServiceImpl) SendLineComments(api, token string, projectID, } // SendWebhookNotification 发送Webhook通知 -func (n *NotificationServiceImpl) SendWebhookNotification(webhookURL string, status int, projectNamespace, mergeURL, comments string, aiMessageID uint, mergeRequest *model.MergeRequestInfo) error { - pushWebhookIfNeeded(webhookURL, int8(status), projectNamespace, mergeURL, comments, aiMessageID, mergeRequest) - return nil -} - -// pushWebhookIfNeeded 推送webhook通知 -func pushWebhookIfNeeded(webhookURL string, webhookStatus int8, pathWithNamespace, mergeURL, comments string, aiMessageId uint, mergeRequest *model.MergeRequestInfo) { - if webhookURL != "" && webhookStatus == 1 { - webhookContent := pushWeChatInfo(pathWithNamespace, mergeURL, comments, aiMessageId) - _ = ai.SendMarkdownToWechatBot(webhookURL, webhookContent) - fmt.Println("推送webhook成功", mergeRequest) - } +func (n *NotificationServiceImpl) SendWebhookNotification(webhookURL string, dto dto.WebhookBody, comments string, mergeRequest *model.MergeRequestInfo) (error error) { + + parse, _ := time.Parse(time.RFC3339, mergeRequest.UpdatedAt) + upTime := parse.Add(time.Hour * 8) + webUrl := strings.Replace(mergeRequest.WebURL, "http://", "https://", -1) + webhookContent := fmt.Sprintf( + "**项目**: ["+dto.Project.PathWithNamespace+"]("+webUrl+")\n"+ + "**标题**: "+mergeRequest.Title+"\n"+ + "**MR**:: "+dto.ObjectAttributes.SourceBranch+" ➡️ "+dto.ObjectAttributes.TargetBranch+"\n"+ + "**更新时间**::"+upTime.Format(time.DateTime)+"\n"+ + "**提交人**::"+dto.User.Name+"\n"+ + "%s", comments) + + return ai.SendMarkdownToWechatBot(webhookURL, webhookContent) } // pushWeChatInfo 构建企业微信推送信息 diff --git a/backend/internal/service/gitlab_service/rag_client.go b/backend/internal/service/gitlab_service/rag_client.go index 8e30bf1..23fa337 100644 --- a/backend/internal/service/gitlab_service/rag_client.go +++ b/backend/internal/service/gitlab_service/rag_client.go @@ -7,6 +7,7 @@ import ( "context" "encoding/json" "fmt" + "io" "net/http" "sync" "time" @@ -263,7 +264,8 @@ func (c *RAGClient) performRequest(req *dto.CodeReviewRequest) (*dto.CodeAnalysi // 检查状态码 if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("RAG服务返回错误状态码: %d", resp.StatusCode) + all, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("RAG服务返回错误 code: %d, info: %s", resp.StatusCode, string(all)) } // 解析响应 diff --git a/backend/internal/service/webhook/manager/managers.go b/backend/internal/service/webhook/manager/managers.go index 074d275..4b00c73 100644 --- a/backend/internal/service/webhook/manager/managers.go +++ b/backend/internal/service/webhook/manager/managers.go @@ -62,7 +62,7 @@ type RAGServiceManagerImpl struct { // NewRAGServiceManagerImpl 创建RAG服务管理器实现 func NewRAGServiceManagerImpl() *RAGServiceManagerImpl { - service, _ := gitlab_service.CreateRAGClient("") + service, _ := gitlab_service.NewOptimizedRAGClient(nil) return &RAGServiceManagerImpl{ service: service, } diff --git a/backend/internal/service/webhook/processors/merge_request_service.go b/backend/internal/service/webhook/processors/merge_request_service.go index 37c851a..085091e 100644 --- a/backend/internal/service/webhook/processors/merge_request_service.go +++ b/backend/internal/service/webhook/processors/merge_request_service.go @@ -77,15 +77,15 @@ func CheckMergeRequestWithAI(body dto.WebhookBody) (string, error) { } // 生成提示词 // 读取gitlab中的评论类型,然后选择不同的提示词 - if data.GitlabInfo.CommentType == utils.CommentTypeCommon { - prompt = utils.GenerateAICheckCommonPrompt(gitlabPrompt, data.MergeRequest.Title, data.MergeRequest.Description, data.DiffStr) - } else { + if data.GitlabInfo.CommentType == utils.CommentTypeInline { prompt = utils.GenerateAICheckInlinePrompt(gitlabPrompt, data.MergeRequest.Title, data.MergeRequest.Description, data.DiffStr) + } else { + prompt = data.FinalRule } // fmt.Printf("AI CodeReview分析的提示词: %s\n", prompt) } // AI检查 - result, err := manager.PerformAIEnhancement(prompt, data) + result, err := manager.PerformAIEnhancement(data) if err != nil { sendFailureNotification(manager, body, fmt.Sprintf("AI CodeReview分析失败: %v", err)) return "", err diff --git a/backend/internal/service/webhook/processors/rag_service.go b/backend/internal/service/webhook/processors/rag_service.go index 459a570..614b001 100644 --- a/backend/internal/service/webhook/processors/rag_service.go +++ b/backend/internal/service/webhook/processors/rag_service.go @@ -12,6 +12,7 @@ import ( "code-review-go/internal/service/webhook/helpers" "code-review-go/internal/service/webhook/manager" "context" + "encoding/json" "fmt" "strconv" "strings" @@ -37,6 +38,7 @@ type AnalysisData struct { GitURL string DiffStr string CommentType int8 + DiffCtx map[string]string } var ( @@ -223,6 +225,11 @@ func (m *MainServiceManager) PrepareData(body dto.WebhookBody) (*AnalysisData, e // 获取差异信息 diff := helpers.GetMergeDiff(gitlabInfo.Config.API, body.Project.ID, body.ObjectAttributes.IID, gitlabToken) + // 获取提交代码内容 + commitCode, err := gitlab_service.GetCommitCodeContent(gitlabInfo.Config.API, body.Project.ID, mergeRequest.Sha, gitlabToken) + if err != nil { + return nil, fmt.Errorf("获取提交代码内容失败: %v", err) + } // 获取AI配置 aiConfig, _ := cache.GetAIConfigCache() @@ -236,7 +243,7 @@ func (m *MainServiceManager) PrepareData(body dto.WebhookBody) (*AnalysisData, e gitURL := m.buildGitURL(mergeRequest.WebURL) // 构建差异字符串 - diffStr := m.buildDiffString(diff) + diffStr := m.buildDiffPrompt(diff, commitCode) return &AnalysisData{ GitlabInfo: &gitlabInfo, @@ -327,6 +334,30 @@ func (m *MainServiceManager) buildDiffString(diff []model.Change) string { return diffStr.String() } +// buildDiffString 构建差异字符串 +func (m *MainServiceManager) buildDiffPrompt(diff []model.Change, contentCtx []model.Change) string { + var diffStr strings.Builder + for _, change := range diff { + diffStr.WriteString(fmt.Sprintf("旧文件路径:%s\n", change.OldPath)) + diffStr.WriteString(fmt.Sprintf("新文件路径:%s\n", change.NewPath)) + diffStr.WriteString(fmt.Sprintf("是否为新文件:%v\n", change.NewFile)) + diffStr.WriteString(fmt.Sprintf("是否重命名:%v\n", change.RenamedFile)) + diffStr.WriteString(fmt.Sprintf("是否删除:%v\n", change.DeletedFile)) + diffStr.WriteString("差异:") + diffStr.WriteString(change.Diff) + diffStr.WriteString("\n") + for _, ctx := range contentCtx { + if ctx.NewPath == change.NewPath && change.NewFile == false { + diffStr.WriteString("上下文:\n") + diffStr.WriteString(ctx.Diff) + break + } + } + diffStr.WriteString("\n") + } + return diffStr.String() +} + // PerformRAGAnalysis 执行RAG分析 func (m *MainServiceManager) PerformRAGAnalysis(data *AnalysisData) (string, error) { // 准备RAG服务请求 @@ -337,6 +368,9 @@ func (m *MainServiceManager) PerformRAGAnalysis(data *AnalysisData) (string, err Query: data.FinalRule, GitlabToken: data.GitlabToken, } + marshal, _ := json.Marshal(req) + + fmt.Println("RAG Req:", string(marshal)) // 调用RAG服务 ragService := m.coordinator.GetRAGService() @@ -377,10 +411,15 @@ func (m *MainServiceManager) GenerateEnhancedPrompt(ragResult string, data *Anal } // PerformAIEnhancement 执行AI增强分析 -func (m *MainServiceManager) PerformAIEnhancement(prompt string, data *AnalysisData) (string, error) { +func (m *MainServiceManager) PerformAIEnhancement(data *AnalysisData) (string, error) { // 调用AI服务 aiService := m.coordinator.GetAIService() - comments, err := aiService.CallAI(prompt) + + rules := []map[string]string{ + {"role": "system", "content": data.FinalRule}, + {"role": "user", "content": data.DiffStr}, + } + comments, err := aiService.CallAI(rules) if err != nil { return "", fmt.Errorf("调用AI服务失败: %v", err) } @@ -467,18 +506,18 @@ func (m *MainServiceManager) SendNotifications(body dto.WebhookBody, comments st } // 推送webhook通知 - err = notificationService.SendWebhookNotification( - data.GitlabInfo.Config.WebhookURL, - int(data.GitlabInfo.Config.WebhookStatus), - body.Project.PathWithNamespace, - body.ObjectAttributes.MergeURL, - comments, - aiMessageID, - data.MergeRequest, - ) - if err != nil { - fmt.Printf("发送Webhook通知失败: %v\n", err) + if data.GitlabInfo.Config.WebhookURL != "" && data.GitlabInfo.Config.WebhookStatus == 1 { + err = notificationService.SendWebhookNotification( + data.GitlabInfo.Config.WebhookURL, + body, + comments, + data.MergeRequest, + ) + if err != nil { + fmt.Printf("发送Webhook通知失败: %v\n", err) + } } + case "push": // Push 事件:发送 GitLab 评论和 webhook 通知 fmt.Printf("Push事件:开始发送GitLab评论和webhook通知\n") @@ -521,20 +560,18 @@ func (m *MainServiceManager) SendNotifications(body dto.WebhookBody, comments st } // 2. 发送 webhook 通知 - pushWebhookURL := fmt.Sprintf("%s/-/commits/%s", data.GitlabInfo.Config.WebhookURL, body.After) - - err := notificationService.SendWebhookNotification( - data.GitlabInfo.Config.WebhookURL, - int(data.GitlabInfo.Config.WebhookStatus), - body.Project.PathWithNamespace, - pushWebhookURL, - comments, - aiMessageID, - data.MergeRequest, - ) - if err != nil { - fmt.Printf("发送Push事件Webhook通知失败: %v\n", err) + if data.GitlabInfo.Config.WebhookURL != "" && data.GitlabInfo.Config.WebhookStatus == 1 { + err := notificationService.SendWebhookNotification( + data.GitlabInfo.Config.WebhookURL, + body, + comments, + data.MergeRequest, + ) + if err != nil { + fmt.Printf("发送Push事件Webhook通知失败: %v\n", err) + } } + default: fmt.Printf("未知的事件类型: %s,跳过通知发送\n", body.ObjectKind) } diff --git a/frontend/src/pages/aicodecheck/GitlabToken/CreateToken.tsx b/frontend/src/pages/aicodecheck/GitlabToken/CreateToken.tsx index fbd482e..be8227f 100644 --- a/frontend/src/pages/aicodecheck/GitlabToken/CreateToken.tsx +++ b/frontend/src/pages/aicodecheck/GitlabToken/CreateToken.tsx @@ -13,7 +13,7 @@ const { TextArea } = Input; const { Sider, Content } = Layout; const { Panel } = Collapse; -const MAX_PROMPT_LENGTH = 1000; +const MAX_PROMPT_LENGTH = 10000; // 禁用3天内的日期 const disabledDate = (current: dayjs.Dayjs) => { @@ -28,12 +28,12 @@ interface AIConfigPageProps { onSubmitLoading?: boolean; } -const AIConfigPage: React.FC = ({ - initialValues = {}, - visible = false, +const AIConfigPage: React.FC = ({ + initialValues = {}, + visible = false, setVisible, onSubmit: externalOnSubmit, - onSubmitLoading = false + onSubmitLoading = false }) => { const context = useContext(BasicContext) as any; const { i18nLocale } = context.storeContext; @@ -84,10 +84,10 @@ const AIConfigPage: React.FC = ({ message.error('自定义提示词最多1000字'); return; } - onSubmit({ - ...values, + onSubmit({ + ...values, comment_type: commentType, - prompt, + prompt, expired: values.expired?.unix(), status: 1 }, form); @@ -110,17 +110,17 @@ const AIConfigPage: React.FC = ({ .then((response) => { // form.resetFields(); message.success(values.id ? t('app.global.tip.update.success') : t('app.global.tip.create.success')); - + // 获取创建的 token ID,用于轮询 const tokenId = response.data?.id || updateData.id; - + // 跳转到GitlabToken列表页,带上轮询参数 if (tokenId) { navigate(`/aicodecheck/GitlabToken?pollingTokenId=${tokenId}`); } else { navigate('/aicodecheck/GitlabToken'); } - + setCreateSubmitLoading(false); }) .catch(() => { @@ -178,9 +178,9 @@ const AIConfigPage: React.FC = ({ } ]} > - @@ -248,7 +248,7 @@ const AIConfigPage: React.FC = ({