Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ jobs:
go-version-file: backend/go.mod
check-latest: false
cache: true
cache-dependency-path: backend/go.sum
- name: Verify Go version
run: |
go version | grep -q 'go1.25.7'
go version | grep -q 'go1.26.0'
- name: Unit tests
working-directory: backend
run: make test-unit
Expand All @@ -36,12 +37,14 @@ jobs:
go-version-file: backend/go.mod
check-latest: false
cache: true
cache-dependency-path: backend/go.sum
- name: Verify Go version
run: |
go version | grep -q 'go1.25.7'
go version | grep -q 'go1.26.0'
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.7
version: v2.7.2
install-mode: goinstall
args: --timeout=5m
working-directory: backend
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:

- name: Verify Go version
run: |
go version | grep -q 'go1.25.7'
go version | grep -q 'go1.26.0'

# Docker setup for GoReleaser
- name: Set up QEMU
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
cache-dependency-path: backend/go.sum
- name: Verify Go version
run: |
go version | grep -q 'go1.25.7'
go version | grep -q 'go1.26.0'
- name: Run govulncheck
working-directory: backend
run: |
Expand Down
2 changes: 1 addition & 1 deletion DEV_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ npm install -g pnpm

### CI 要求

- Go 版本必须是 **1.25.7**
- Go 版本必须是 **1.26.0**
- 前端使用 `pnpm install --frozen-lockfile`,必须提交 `pnpm-lock.yaml`

### 本地测试命令
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# =============================================================================

ARG NODE_IMAGE=node:24-alpine
ARG GOLANG_IMAGE=golang:1.25.7-alpine
ARG GOLANG_IMAGE=golang:1.26.0-alpine
ARG ALPINE_IMAGE=alpine:3.20
ARG GOPROXY=https://goproxy.cn,direct
ARG GOSUMDB=sum.golang.google.cn
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<div align="center">

[![Go](https://img.shields.io/badge/Go-1.25.7-00ADD8.svg)](https://golang.org/)
[![Go](https://img.shields.io/badge/Go-1.26.0-00ADD8.svg)](https://golang.org/)
[![Vue](https://img.shields.io/badge/Vue-3.4+-4FC08D.svg)](https://vuejs.org/)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-15+-336791.svg)](https://www.postgresql.org/)
[![Redis](https://img.shields.io/badge/Redis-7+-DC382D.svg)](https://redis.io/)
Expand Down Expand Up @@ -44,7 +44,7 @@ Sub2API is an AI API gateway platform designed to distribute and manage API quot

| Component | Technology |
|-----------|------------|
| Backend | Go 1.25.7, Gin, Ent |
| Backend | Go 1.26.0, Gin, Ent |
| Frontend | Vue 3.4+, Vite 5+, TailwindCSS |
| Database | PostgreSQL 15+ |
| Cache/Queue | Redis 7+ |
Expand Down Expand Up @@ -298,7 +298,7 @@ Build and run from source code for development or customization.

#### Prerequisites

- Go 1.21+
- Go 1.26.0
- Node.js 18+
- PostgreSQL 15+
- Redis 7+
Expand Down
6 changes: 3 additions & 3 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<div align="center">

[![Go](https://img.shields.io/badge/Go-1.25.7-00ADD8.svg)](https://golang.org/)
[![Go](https://img.shields.io/badge/Go-1.26.0-00ADD8.svg)](https://golang.org/)
[![Vue](https://img.shields.io/badge/Vue-3.4+-4FC08D.svg)](https://vuejs.org/)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-15+-336791.svg)](https://www.postgresql.org/)
[![Redis](https://img.shields.io/badge/Redis-7+-DC382D.svg)](https://redis.io/)
Expand Down Expand Up @@ -44,7 +44,7 @@ Sub2API 是一个 AI API 网关平台,用于分发和管理 AI 产品订阅(

| 组件 | 技术 |
|------|------|
| 后端 | Go 1.25.7, Gin, Ent |
| 后端 | Go 1.26.0, Gin, Ent |
| 前端 | Vue 3.4+, Vite 5+, TailwindCSS |
| 数据库 | PostgreSQL 15+ |
| 缓存/队列 | Redis 7+ |
Expand Down Expand Up @@ -305,7 +305,7 @@ rm -rf data/ postgres_data/ redis_data/

#### 前置条件

- Go 1.21+
- Go 1.26.0
- Node.js 18+
- PostgreSQL 15+
- Redis 7+
Expand Down
11 changes: 5 additions & 6 deletions backend/.golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ linters:
# Default: false
check-escaping-errors: true
staticcheck:
# https://staticcheck.dev/docs/configuration/options/#dot_import_whitelist
# Default: ["github.com/mmcloughlin/avo/build", "github.com/mmcloughlin/avo/operand", "github.com/mmcloughlin/avo/reg"]
dot-import-whitelist:
- fmt
# https://staticcheck.dev/docs/configuration/options/#initialisms
# Default: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"]
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ]
Expand All @@ -94,6 +90,7 @@ linters:
- all
- -ST1000 # Package comment format
- -ST1003 # Poorly chosen identifier (ApiKey vs APIKey)
- -ST1016 # Methods on the same type should have the same receiver name
- -ST1020 # Comment on exported method format
- -ST1021 # Comment on exported type format
- -ST1022 # Comment on exported variable format
Expand Down Expand Up @@ -225,7 +222,8 @@ linters:
- SA4005
# A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?.
# https://staticcheck.dev/docs/checks/#SA4006
- SA4006
# Go 1.26 的 new(value) 语法会触发 staticcheck 的误报(SA4006),先临时关闭。
- -SA4006
# The variable in the loop condition never changes, are you incrementing the wrong variable?.
# https://staticcheck.dev/docs/checks/#SA4008
- SA4008
Expand Down Expand Up @@ -255,7 +253,8 @@ linters:
- SA4016
# Discarding the return values of a function without side effects, making the call pointless.
# https://staticcheck.dev/docs/checks/#SA4017
- SA4017
# Go 1.26 的 new(value) 语法会触发 staticcheck 的误报(SA4017),先临时关闭。
- -SA4017
# Self-assignment of variables.
# https://staticcheck.dev/docs/checks/#SA4018
- SA4018
Expand Down
2 changes: 1 addition & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.25.7-alpine
FROM golang:1.26.0-alpine

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion backend/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/Wei-Shaw/sub2api

go 1.25.7
go 1.26.0

require (
entgo.io/ent v0.14.5
Expand Down
3 changes: 1 addition & 2 deletions backend/internal/handler/admin/account_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ func (h *AccountHandler) ExportData(c *gin.Context) {
}
var expiresAt *int64
if acc.ExpiresAt != nil {
v := acc.ExpiresAt.Unix()
expiresAt = &v
expiresAt = new(acc.ExpiresAt.Unix())
}
dataAccounts = append(dataAccounts, DataAccount{
Name: acc.Name,
Expand Down
6 changes: 2 additions & 4 deletions backend/internal/handler/admin/account_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,7 @@ func (h *AccountHandler) Create(c *gin.Context) {
})
if err != nil {
// 检查是否为混合渠道错误
var mixedErr *service.MixedChannelError
if errors.As(err, &mixedErr) {
if mixedErr, ok := errors.AsType[*service.MixedChannelError](err); ok {
// 返回特殊错误码要求确认
c.JSON(409, gin.H{
"error": "mixed_channel_warning",
Expand Down Expand Up @@ -376,8 +375,7 @@ func (h *AccountHandler) Update(c *gin.Context) {
})
if err != nil {
// 检查是否为混合渠道错误
var mixedErr *service.MixedChannelError
if errors.As(err, &mixedErr) {
if mixedErr, ok := errors.AsType[*service.MixedChannelError](err); ok {
// 返回特殊错误码要求确认
c.JSON(409, gin.H{
"error": "mixed_channel_warning",
Expand Down
12 changes: 4 additions & 8 deletions backend/internal/handler/admin/announcement_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,10 @@ func (h *AnnouncementHandler) Create(c *gin.Context) {
}

if req.StartsAt != nil && *req.StartsAt > 0 {
t := time.Unix(*req.StartsAt, 0)
input.StartsAt = &t
input.StartsAt = new(time.Unix(*req.StartsAt, 0))
}
if req.EndsAt != nil && *req.EndsAt > 0 {
t := time.Unix(*req.EndsAt, 0)
input.EndsAt = &t
input.EndsAt = new(time.Unix(*req.EndsAt, 0))
}

created, err := h.announcementService.Create(c.Request.Context(), input)
Expand Down Expand Up @@ -169,8 +167,7 @@ func (h *AnnouncementHandler) Update(c *gin.Context) {
var cleared *time.Time = nil
input.StartsAt = &cleared
} else {
t := time.Unix(*req.StartsAt, 0)
ptr := &t
ptr := new(time.Unix(*req.StartsAt, 0))
input.StartsAt = &ptr
}
}
Expand All @@ -180,8 +177,7 @@ func (h *AnnouncementHandler) Update(c *gin.Context) {
var cleared *time.Time = nil
input.EndsAt = &cleared
} else {
t := time.Unix(*req.EndsAt, 0)
ptr := &t
ptr := new(time.Unix(*req.EndsAt, 0))
input.EndsAt = &ptr
}
}
Expand Down
6 changes: 2 additions & 4 deletions backend/internal/handler/admin/dashboard_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,7 @@ func (h *DashboardHandler) GetUsageTrend(c *gin.Context) {
}
if billingTypeStr := c.Query("billing_type"); billingTypeStr != "" {
if v, err := strconv.ParseInt(billingTypeStr, 10, 8); err == nil {
bt := int8(v)
billingType = &bt
billingType = new(int8(v))
} else {
response.BadRequest(c, "Invalid billing_type")
return
Expand Down Expand Up @@ -287,8 +286,7 @@ func (h *DashboardHandler) GetModelStats(c *gin.Context) {
}
if billingTypeStr := c.Query("billing_type"); billingTypeStr != "" {
if v, err := strconv.ParseInt(billingTypeStr, 10, 8); err == nil {
bt := int8(v)
billingType = &bt
billingType = new(int8(v))
} else {
response.BadRequest(c, "Invalid billing_type")
return
Expand Down
3 changes: 1 addition & 2 deletions backend/internal/handler/admin/group_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ func (h *GroupHandler) List(c *gin.Context) {

var isExclusive *bool
if isExclusiveStr != "" {
val := isExclusiveStr == "true"
isExclusive = &val
isExclusive = new(isExclusiveStr == "true")
}

groups, total, err := h.adminService.ListGroups(c.Request.Context(), page, pageSize, platform, status, search, isExclusive)
Expand Down
12 changes: 4 additions & 8 deletions backend/internal/handler/admin/ops_alerts_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,7 @@ func (h *OpsHandler) UpdateAlertEventStatus(c *gin.Context) {

var resolvedAt *time.Time
if payload.Status == service.OpsAlertStatusResolved || payload.Status == service.OpsAlertStatusManualResolved {
now := time.Now().UTC()
resolvedAt = &now
resolvedAt = new(time.Now().UTC())
}
if err := h.opsService.UpdateAlertEventStatus(c.Request.Context(), id, payload.Status, resolvedAt); err != nil {
response.ErrorFrom(c, err)
Expand Down Expand Up @@ -479,8 +478,7 @@ func (h *OpsHandler) CreateAlertSilence(c *gin.Context) {

createdBy := (*int64)(nil)
if subject, ok := middleware.GetAuthSubjectFromContext(c); ok {
uid := subject.UserID
createdBy = &uid
createdBy = new(subject.UserID)
}

silence := &service.OpsAlertSilence{
Expand Down Expand Up @@ -531,11 +529,9 @@ func (h *OpsHandler) ListAlertEvents(c *gin.Context) {
vv := strings.ToLower(v)
switch vv {
case "true", "1":
b := true
filter.EmailSent = &b
filter.EmailSent = new(true)
case "false", "0":
b := false
filter.EmailSent = &b
filter.EmailSent = new(false)
default:
response.BadRequest(c, "Invalid email_sent")
return
Expand Down
21 changes: 7 additions & 14 deletions backend/internal/handler/admin/ops_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,9 @@ func (h *OpsHandler) GetErrorLogs(c *gin.Context) {
if v := strings.TrimSpace(c.Query("resolved")); v != "" {
switch strings.ToLower(v) {
case "1", "true", "yes":
b := true
filter.Resolved = &b
filter.Resolved = new(true)
case "0", "false", "no":
b := false
filter.Resolved = &b
filter.Resolved = new(false)
default:
response.BadRequest(c, "Invalid resolved")
return
Expand Down Expand Up @@ -243,11 +241,9 @@ func (h *OpsHandler) ListRequestErrors(c *gin.Context) {
if v := strings.TrimSpace(c.Query("resolved")); v != "" {
switch strings.ToLower(v) {
case "1", "true", "yes":
b := true
filter.Resolved = &b
filter.Resolved = new(true)
case "0", "false", "no":
b := false
filter.Resolved = &b
filter.Resolved = new(false)
default:
response.BadRequest(c, "Invalid resolved")
return
Expand Down Expand Up @@ -522,11 +518,9 @@ func (h *OpsHandler) ListUpstreamErrors(c *gin.Context) {
if v := strings.TrimSpace(c.Query("resolved")); v != "" {
switch strings.ToLower(v) {
case "1", "true", "yes":
b := true
filter.Resolved = &b
filter.Resolved = new(true)
case "0", "false", "no":
b := false
filter.Resolved = &b
filter.Resolved = new(false)
default:
response.BadRequest(c, "Invalid resolved")
return
Expand Down Expand Up @@ -836,8 +830,7 @@ func (h *OpsHandler) UpdateErrorResolution(c *gin.Context) {
response.BadRequest(c, "Invalid request: "+err.Error())
return
}
uid := subject.UserID
if err := h.opsService.UpdateErrorResolution(c.Request.Context(), id, req.Resolved, &uid, nil); err != nil {
if err := h.opsService.UpdateErrorResolution(c.Request.Context(), id, req.Resolved, new(subject.UserID), nil); err != nil {
response.ErrorFrom(c, err)
return
}
Expand Down
6 changes: 2 additions & 4 deletions backend/internal/handler/admin/promo_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ func (h *PromoHandler) Create(c *gin.Context) {
}

if req.ExpiresAt != nil {
t := time.Unix(*req.ExpiresAt, 0)
input.ExpiresAt = &t
input.ExpiresAt = new(time.Unix(*req.ExpiresAt, 0))
}

code, err := h.promoService.Create(c.Request.Context(), input)
Expand Down Expand Up @@ -148,8 +147,7 @@ func (h *PromoHandler) Update(c *gin.Context) {
// 0 表示清除过期时间
input.ExpiresAt = nil
} else {
t := time.Unix(*req.ExpiresAt, 0)
input.ExpiresAt = &t
input.ExpiresAt = new(time.Unix(*req.ExpiresAt, 0))
}
}

Expand Down
3 changes: 1 addition & 2 deletions backend/internal/handler/admin/usage_cleanup_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ func (s *cleanupRepoStub) CreateTask(ctx context.Context, task *service.UsageCle
task.CreatedAt = time.Now().UTC()
}
task.UpdatedAt = task.CreatedAt
clone := *task
s.created = append(s.created, &clone)
s.created = append(s.created, new(*task))
return nil
}

Expand Down
Loading