"backend/internal/vscode:/vscode.git/clone" did not exist on "152d0cdec65d81cf9fcf00e060e77b468044de9d"
Commit c7abfe67 authored by song's avatar song
Browse files

Merge remote-tracking branch 'upstream/main'

parents 4e3476a6 db6f53e2
version: 1
exceptions:
- package: xlsx
advisory: "GHSA-4r6h-8v6p-xvw6"
severity: high
reason: "Admin export only; switched to dynamic import to reduce exposure (CVE-2023-30533)"
mitigation: "Load only on export; restrict export permissions and data scope"
expires_on: "2026-04-05"
owner: "security@your-domain"
- package: xlsx
advisory: "GHSA-5pgg-2g8v-p4x9"
severity: high
reason: "Admin export only; switched to dynamic import to reduce exposure (CVE-2024-22363)"
mitigation: "Load only on export; restrict export permissions and data scope"
expires_on: "2026-04-05"
owner: "security@your-domain"
...@@ -15,8 +15,11 @@ jobs: ...@@ -15,8 +15,11 @@ jobs:
- uses: actions/setup-go@v5 - uses: actions/setup-go@v5
with: with:
go-version-file: backend/go.mod go-version-file: backend/go.mod
check-latest: true check-latest: false
cache: true cache: true
- name: Verify Go version
run: |
go version | grep -q 'go1.25.5'
- name: Unit tests - name: Unit tests
working-directory: backend working-directory: backend
run: make test-unit run: make test-unit
...@@ -31,8 +34,11 @@ jobs: ...@@ -31,8 +34,11 @@ jobs:
- uses: actions/setup-go@v5 - uses: actions/setup-go@v5
with: with:
go-version-file: backend/go.mod go-version-file: backend/go.mod
check-latest: true check-latest: false
cache: true cache: true
- name: Verify Go version
run: |
go version | grep -q 'go1.25.5'
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v9 uses: golangci/golangci-lint-action@v9
with: with:
......
...@@ -109,9 +109,14 @@ jobs: ...@@ -109,9 +109,14 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.24' go-version-file: backend/go.mod
check-latest: false
cache-dependency-path: backend/go.sum cache-dependency-path: backend/go.sum
- name: Verify Go version
run: |
go version | grep -q 'go1.25.5'
# Docker setup for GoReleaser # Docker setup for GoReleaser
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
......
name: Security Scan
on:
push:
pull_request:
schedule:
- cron: '0 3 * * 1'
permissions:
contents: read
jobs:
backend-security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: backend/go.mod
check-latest: false
cache-dependency-path: backend/go.sum
- name: Verify Go version
run: |
go version | grep -q 'go1.25.5'
- name: Run govulncheck
working-directory: backend
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
- name: Run gosec
working-directory: backend
run: |
go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec -severity high -confidence high ./...
frontend-security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
cache-dependency-path: frontend/pnpm-lock.yaml
- name: Install dependencies
working-directory: frontend
run: pnpm install --frozen-lockfile
- name: Run pnpm audit
working-directory: frontend
run: |
pnpm audit --prod --audit-level=high --json > audit.json || true
- name: Check audit exceptions
run: |
python tools/check_pnpm_audit_exceptions.py \
--audit frontend/audit.json \
--exceptions .github/audit-exceptions.yml
...@@ -123,3 +123,6 @@ backend/cmd/server/server ...@@ -123,3 +123,6 @@ backend/cmd/server/server
deploy/docker-compose.override.yml deploy/docker-compose.override.yml
.gocache/ .gocache/
vite.config.js vite.config.js
!docs/
docs/*
!docs/dependency-security.md
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
# ============================================================================= # =============================================================================
ARG NODE_IMAGE=node:24-alpine ARG NODE_IMAGE=node:24-alpine
ARG GOLANG_IMAGE=golang:1.25-alpine ARG GOLANG_IMAGE=golang:1.25.5-alpine
ARG ALPINE_IMAGE=alpine:3.19 ARG ALPINE_IMAGE=alpine:3.20
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.cn,direct
ARG GOSUMDB=sum.golang.google.cn ARG GOSUMDB=sum.golang.google.cn
......
...@@ -9,7 +9,7 @@ build-backend: ...@@ -9,7 +9,7 @@ build-backend:
# 编译前端(需要已安装依赖) # 编译前端(需要已安装依赖)
build-frontend: build-frontend:
@npm --prefix frontend run build @pnpm --dir frontend run build
# 运行测试(后端 + 前端) # 运行测试(后端 + 前端)
test: test-backend test-frontend test: test-backend test-frontend
...@@ -18,5 +18,5 @@ test-backend: ...@@ -18,5 +18,5 @@ test-backend:
@$(MAKE) -C backend test @$(MAKE) -C backend test
test-frontend: test-frontend:
@npm --prefix frontend run lint:check @pnpm --dir frontend run lint:check
@npm --prefix frontend run typecheck @pnpm --dir frontend run typecheck
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div align="center"> <div align="center">
[![Go](https://img.shields.io/badge/Go-1.21+-00ADD8.svg)](https://golang.org/) [![Go](https://img.shields.io/badge/Go-1.25.5-00ADD8.svg)](https://golang.org/)
[![Vue](https://img.shields.io/badge/Vue-3.4+-4FC08D.svg)](https://vuejs.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/) [![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/) [![Redis](https://img.shields.io/badge/Redis-7+-DC382D.svg)](https://redis.io/)
...@@ -44,13 +44,19 @@ Sub2API is an AI API gateway platform designed to distribute and manage API quot ...@@ -44,13 +44,19 @@ Sub2API is an AI API gateway platform designed to distribute and manage API quot
| Component | Technology | | Component | Technology |
|-----------|------------| |-----------|------------|
| Backend | Go 1.21+, Gin, GORM | | Backend | Go 1.25.5, Gin, Ent |
| Frontend | Vue 3.4+, Vite 5+, TailwindCSS | | Frontend | Vue 3.4+, Vite 5+, TailwindCSS |
| Database | PostgreSQL 15+ | | Database | PostgreSQL 15+ |
| Cache/Queue | Redis 7+ | | Cache/Queue | Redis 7+ |
--- ---
## Documentation
- Dependency Security: `docs/dependency-security.md`
---
## Deployment ## Deployment
### Method 1: Script Installation (Recommended) ### Method 1: Script Installation (Recommended)
...@@ -160,6 +166,22 @@ ADMIN_PASSWORD=your_admin_password ...@@ -160,6 +166,22 @@ ADMIN_PASSWORD=your_admin_password
# Optional: Custom port # Optional: Custom port
SERVER_PORT=8080 SERVER_PORT=8080
# Optional: Security configuration
# Enable URL allowlist validation (false to skip allowlist checks, only basic format validation)
SECURITY_URL_ALLOWLIST_ENABLED=false
# Allow insecure HTTP URLs when allowlist is disabled (default: false, requires https)
# ⚠️ WARNING: Enabling this allows HTTP (plaintext) URLs which can expose API keys
# Only recommended for:
# - Development/testing environments
# - Internal networks with trusted endpoints
# - When using local test servers (http://localhost)
# PRODUCTION: Keep this false or use HTTPS URLs only
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=false
# Allow private IP addresses for upstream/pricing/CRS (for internal deployments)
SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=false
``` ```
```bash ```bash
...@@ -276,13 +298,48 @@ Additional security-related options are available in `config.yaml`: ...@@ -276,13 +298,48 @@ Additional security-related options are available in `config.yaml`:
- `cors.allowed_origins` for CORS allowlist - `cors.allowed_origins` for CORS allowlist
- `security.url_allowlist` for upstream/pricing/CRS host allowlists - `security.url_allowlist` for upstream/pricing/CRS host allowlists
- `security.url_allowlist.enabled` to disable URL validation (use with caution) - `security.url_allowlist.enabled` to disable URL validation (use with caution)
- `security.url_allowlist.allow_insecure_http` to allow http URLs when validation is disabled - `security.url_allowlist.allow_insecure_http` to allow HTTP URLs when validation is disabled
- `security.url_allowlist.allow_private_hosts` to allow private/local IP addresses
- `security.response_headers.enabled` to enable configurable response header filtering (disabled uses default allowlist) - `security.response_headers.enabled` to enable configurable response header filtering (disabled uses default allowlist)
- `security.csp` to control Content-Security-Policy headers - `security.csp` to control Content-Security-Policy headers
- `billing.circuit_breaker` to fail closed on billing errors - `billing.circuit_breaker` to fail closed on billing errors
- `server.trusted_proxies` to enable X-Forwarded-For parsing - `server.trusted_proxies` to enable X-Forwarded-For parsing
- `turnstile.required` to require Turnstile in release mode - `turnstile.required` to require Turnstile in release mode
**⚠️ Security Warning: HTTP URL Configuration**
When `security.url_allowlist.enabled=false`, the system performs minimal URL validation by default, **rejecting HTTP URLs** and only allowing HTTPS. To allow HTTP URLs (e.g., for development or internal testing), you must explicitly set:
```yaml
security:
url_allowlist:
enabled: false # Disable allowlist checks
allow_insecure_http: true # Allow HTTP URLs (⚠️ INSECURE)
```
**Or via environment variable:**
```bash
SECURITY_URL_ALLOWLIST_ENABLED=false
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
```
**Risks of allowing HTTP:**
- API keys and data transmitted in **plaintext** (vulnerable to interception)
- Susceptible to **man-in-the-middle (MITM) attacks**
- **NOT suitable for production** environments
**When to use HTTP:**
- ✅ Development/testing with local servers (http://localhost)
- ✅ Internal networks with trusted endpoints
- ✅ Testing account connectivity before obtaining HTTPS
- ❌ Production environments (use HTTPS only)
**Example error without this setting:**
```
Invalid base URL: invalid url scheme: http
```
If you disable URL validation or response header filtering, harden your network layer: If you disable URL validation or response header filtering, harden your network layer:
- Enforce an egress allowlist for upstream domains/IPs - Enforce an egress allowlist for upstream domains/IPs
- Block private/loopback/link-local ranges - Block private/loopback/link-local ranges
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div align="center"> <div align="center">
[![Go](https://img.shields.io/badge/Go-1.21+-00ADD8.svg)](https://golang.org/) [![Go](https://img.shields.io/badge/Go-1.25.5-00ADD8.svg)](https://golang.org/)
[![Vue](https://img.shields.io/badge/Vue-3.4+-4FC08D.svg)](https://vuejs.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/) [![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/) [![Redis](https://img.shields.io/badge/Redis-7+-DC382D.svg)](https://redis.io/)
...@@ -44,13 +44,19 @@ Sub2API 是一个 AI API 网关平台,用于分发和管理 AI 产品订阅( ...@@ -44,13 +44,19 @@ Sub2API 是一个 AI API 网关平台,用于分发和管理 AI 产品订阅(
| 组件 | 技术 | | 组件 | 技术 |
|------|------| |------|------|
| 后端 | Go 1.21+, Gin, GORM | | 后端 | Go 1.25.5, Gin, Ent |
| 前端 | Vue 3.4+, Vite 5+, TailwindCSS | | 前端 | Vue 3.4+, Vite 5+, TailwindCSS |
| 数据库 | PostgreSQL 15+ | | 数据库 | PostgreSQL 15+ |
| 缓存/队列 | Redis 7+ | | 缓存/队列 | Redis 7+ |
--- ---
## 文档
- 依赖安全:`docs/dependency-security.md`
---
## 部署方式 ## 部署方式
### 方式一:脚本安装(推荐) ### 方式一:脚本安装(推荐)
...@@ -160,6 +166,22 @@ ADMIN_PASSWORD=your_admin_password ...@@ -160,6 +166,22 @@ ADMIN_PASSWORD=your_admin_password
# 可选:自定义端口 # 可选:自定义端口
SERVER_PORT=8080 SERVER_PORT=8080
# 可选:安全配置
# 启用 URL 白名单验证(false 则跳过白名单检查,仅做基本格式校验)
SECURITY_URL_ALLOWLIST_ENABLED=false
# 关闭白名单时,是否允许 http:// URL(默认 false,只允许 https://)
# ⚠️ 警告:允许 HTTP 会暴露 API 密钥(明文传输)
# 仅建议在以下场景使用:
# - 开发/测试环境
# - 内部可信网络
# - 本地测试服务器(http://localhost)
# 生产环境:保持 false 或仅使用 HTTPS URL
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=false
# 是否允许私有 IP 地址用于上游/定价/CRS(内网部署时使用)
SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=false
``` ```
```bash ```bash
...@@ -276,13 +298,48 @@ default: ...@@ -276,13 +298,48 @@ default:
- `cors.allowed_origins` 配置 CORS 白名单 - `cors.allowed_origins` 配置 CORS 白名单
- `security.url_allowlist` 配置上游/价格数据/CRS 主机白名单 - `security.url_allowlist` 配置上游/价格数据/CRS 主机白名单
- `security.url_allowlist.enabled` 可关闭 URL 校验(慎用) - `security.url_allowlist.enabled` 可关闭 URL 校验(慎用)
- `security.url_allowlist.allow_insecure_http` 关闭校验时允许 http URL - `security.url_allowlist.allow_insecure_http` 关闭校验时允许 HTTP URL
- `security.url_allowlist.allow_private_hosts` 允许私有/本地 IP 地址
- `security.response_headers.enabled` 可启用可配置响应头过滤(关闭时使用默认白名单) - `security.response_headers.enabled` 可启用可配置响应头过滤(关闭时使用默认白名单)
- `security.csp` 配置 Content-Security-Policy - `security.csp` 配置 Content-Security-Policy
- `billing.circuit_breaker` 计费异常时 fail-closed - `billing.circuit_breaker` 计费异常时 fail-closed
- `server.trusted_proxies` 启用可信代理解析 X-Forwarded-For - `server.trusted_proxies` 启用可信代理解析 X-Forwarded-For
- `turnstile.required` 在 release 模式强制启用 Turnstile - `turnstile.required` 在 release 模式强制启用 Turnstile
**⚠️ 安全警告:HTTP URL 配置**
`security.url_allowlist.enabled=false` 时,系统默认执行最小 URL 校验,**拒绝 HTTP URL**,仅允许 HTTPS。要允许 HTTP URL(例如用于开发或内网测试),必须显式设置:
```yaml
security:
url_allowlist:
enabled: false # 禁用白名单检查
allow_insecure_http: true # 允许 HTTP URL(⚠️ 不安全)
```
**或通过环境变量:**
```bash
SECURITY_URL_ALLOWLIST_ENABLED=false
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
```
**允许 HTTP 的风险:**
- API 密钥和数据以**明文传输**(可被截获)
- 易受**中间人攻击 (MITM)**
- **不适合生产环境**
**适用场景:**
- ✅ 开发/测试环境的本地服务器(http://localhost)
- ✅ 内网可信端点
- ✅ 获取 HTTPS 前测试账号连通性
- ❌ 生产环境(仅使用 HTTPS)
**未设置此项时的错误示例:**
```
Invalid base URL: invalid url scheme: http
```
如关闭 URL 校验或响应头过滤,请加强网络层防护: 如关闭 URL 校验或响应头过滤,请加强网络层防护:
- 出站访问白名单限制上游域名/IP - 出站访问白名单限制上游域名/IP
- 阻断私网/回环/链路本地地址 - 阻断私网/回环/链路本地地址
......
FROM golang:1.21-alpine FROM golang:1.25.5-alpine
WORKDIR /app WORKDIR /app
......
...@@ -63,6 +63,7 @@ func provideCleanup( ...@@ -63,6 +63,7 @@ func provideCleanup(
entClient *ent.Client, entClient *ent.Client,
rdb *redis.Client, rdb *redis.Client,
tokenRefresh *service.TokenRefreshService, tokenRefresh *service.TokenRefreshService,
accountExpiry *service.AccountExpiryService,
pricing *service.PricingService, pricing *service.PricingService,
emailQueue *service.EmailQueueService, emailQueue *service.EmailQueueService,
billingCache *service.BillingCacheService, billingCache *service.BillingCacheService,
...@@ -84,6 +85,10 @@ func provideCleanup( ...@@ -84,6 +85,10 @@ func provideCleanup(
tokenRefresh.Stop() tokenRefresh.Stop()
return nil return nil
}}, }},
{"AccountExpiryService", func() error {
accountExpiry.Stop()
return nil
}},
{"PricingService", func() error { {"PricingService", func() error {
pricing.Stop() pricing.Stop()
return nil return nil
......
...@@ -87,6 +87,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { ...@@ -87,6 +87,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
geminiOAuthClient := repository.NewGeminiOAuthClient(configConfig) geminiOAuthClient := repository.NewGeminiOAuthClient(configConfig)
geminiCliCodeAssistClient := repository.NewGeminiCliCodeAssistClient() geminiCliCodeAssistClient := repository.NewGeminiCliCodeAssistClient()
geminiOAuthService := service.NewGeminiOAuthService(proxyRepository, geminiOAuthClient, geminiCliCodeAssistClient, configConfig) geminiOAuthService := service.NewGeminiOAuthService(proxyRepository, geminiOAuthClient, geminiCliCodeAssistClient, configConfig)
antigravityOAuthService := service.NewAntigravityOAuthService(proxyRepository)
geminiQuotaService := service.NewGeminiQuotaService(configConfig, settingRepository) geminiQuotaService := service.NewGeminiQuotaService(configConfig, settingRepository)
tempUnschedCache := repository.NewTempUnschedCache(redisClient) tempUnschedCache := repository.NewTempUnschedCache(redisClient)
rateLimitService := service.NewRateLimitService(accountRepository, usageLogRepository, configConfig, geminiQuotaService, tempUnschedCache) rateLimitService := service.NewRateLimitService(accountRepository, usageLogRepository, configConfig, geminiQuotaService, tempUnschedCache)
...@@ -97,13 +98,12 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { ...@@ -97,13 +98,12 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
geminiTokenCache := repository.NewGeminiTokenCache(redisClient) geminiTokenCache := repository.NewGeminiTokenCache(redisClient)
geminiTokenProvider := service.NewGeminiTokenProvider(accountRepository, geminiTokenCache, geminiOAuthService) geminiTokenProvider := service.NewGeminiTokenProvider(accountRepository, geminiTokenCache, geminiOAuthService)
gatewayCache := repository.NewGatewayCache(redisClient) gatewayCache := repository.NewGatewayCache(redisClient)
antigravityOAuthService := service.NewAntigravityOAuthService(proxyRepository)
antigravityTokenProvider := service.NewAntigravityTokenProvider(accountRepository, geminiTokenCache, antigravityOAuthService) antigravityTokenProvider := service.NewAntigravityTokenProvider(accountRepository, geminiTokenCache, antigravityOAuthService)
httpUpstream := repository.NewHTTPUpstream(configConfig) httpUpstream := repository.NewHTTPUpstream(configConfig)
antigravityGatewayService := service.NewAntigravityGatewayService(accountRepository, gatewayCache, antigravityTokenProvider, rateLimitService, httpUpstream, settingService) antigravityGatewayService := service.NewAntigravityGatewayService(accountRepository, gatewayCache, antigravityTokenProvider, rateLimitService, httpUpstream, settingService)
accountTestService := service.NewAccountTestService(accountRepository, geminiTokenProvider, antigravityGatewayService, httpUpstream, configConfig) accountTestService := service.NewAccountTestService(accountRepository, geminiTokenProvider, antigravityGatewayService, httpUpstream, configConfig)
concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig) concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig)
concurrencyService := service.NewConcurrencyService(concurrencyCache) concurrencyService := service.ProvideConcurrencyService(concurrencyCache, accountRepository, configConfig)
crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig) crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig)
accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService) accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService)
oAuthHandler := admin.NewOAuthHandler(oAuthService) oAuthHandler := admin.NewOAuthHandler(oAuthService)
...@@ -114,7 +114,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { ...@@ -114,7 +114,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
adminRedeemHandler := admin.NewRedeemHandler(adminService) adminRedeemHandler := admin.NewRedeemHandler(adminService)
settingHandler := admin.NewSettingHandler(settingService, emailService, turnstileService) settingHandler := admin.NewSettingHandler(settingService, emailService, turnstileService)
updateCache := repository.NewUpdateCache(redisClient) updateCache := repository.NewUpdateCache(redisClient)
gitHubReleaseClient := repository.NewGitHubReleaseClient() gitHubReleaseClient := repository.ProvideGitHubReleaseClient(configConfig)
serviceBuildInfo := provideServiceBuildInfo(buildInfo) serviceBuildInfo := provideServiceBuildInfo(buildInfo)
updateService := service.ProvideUpdateService(updateCache, gitHubReleaseClient, serviceBuildInfo) updateService := service.ProvideUpdateService(updateCache, gitHubReleaseClient, serviceBuildInfo)
systemHandler := handler.ProvideSystemHandler(updateService) systemHandler := handler.ProvideSystemHandler(updateService)
...@@ -125,7 +125,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { ...@@ -125,7 +125,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
userAttributeService := service.NewUserAttributeService(userAttributeDefinitionRepository, userAttributeValueRepository) userAttributeService := service.NewUserAttributeService(userAttributeDefinitionRepository, userAttributeValueRepository)
userAttributeHandler := admin.NewUserAttributeHandler(userAttributeService) userAttributeHandler := admin.NewUserAttributeHandler(userAttributeService)
adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, settingHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler) adminHandlers := handler.ProvideAdminHandlers(dashboardHandler, adminUserHandler, groupHandler, accountHandler, oAuthHandler, openAIOAuthHandler, geminiOAuthHandler, antigravityOAuthHandler, proxyHandler, adminRedeemHandler, settingHandler, systemHandler, adminSubscriptionHandler, adminUsageHandler, userAttributeHandler)
pricingRemoteClient := repository.NewPricingRemoteClient(configConfig) pricingRemoteClient := repository.ProvidePricingRemoteClient(configConfig)
pricingService, err := service.ProvidePricingService(configConfig, pricingRemoteClient) pricingService, err := service.ProvidePricingService(configConfig, pricingRemoteClient)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -148,7 +148,8 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) { ...@@ -148,7 +148,8 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
engine := server.ProvideRouter(configConfig, handlers, jwtAuthMiddleware, adminAuthMiddleware, apiKeyAuthMiddleware, apiKeyService, subscriptionService) engine := server.ProvideRouter(configConfig, handlers, jwtAuthMiddleware, adminAuthMiddleware, apiKeyAuthMiddleware, apiKeyService, subscriptionService)
httpServer := server.ProvideHTTPServer(configConfig, engine) httpServer := server.ProvideHTTPServer(configConfig, engine)
tokenRefreshService := service.ProvideTokenRefreshService(accountRepository, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, configConfig) tokenRefreshService := service.ProvideTokenRefreshService(accountRepository, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, configConfig)
v := provideCleanup(client, redisClient, tokenRefreshService, pricingService, emailQueueService, billingCacheService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService) accountExpiryService := service.ProvideAccountExpiryService(accountRepository)
v := provideCleanup(client, redisClient, tokenRefreshService, accountExpiryService, pricingService, emailQueueService, billingCacheService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService)
application := &Application{ application := &Application{
Server: httpServer, Server: httpServer,
Cleanup: v, Cleanup: v,
...@@ -174,6 +175,7 @@ func provideCleanup( ...@@ -174,6 +175,7 @@ func provideCleanup(
entClient *ent.Client, entClient *ent.Client,
rdb *redis.Client, rdb *redis.Client,
tokenRefresh *service.TokenRefreshService, tokenRefresh *service.TokenRefreshService,
accountExpiry *service.AccountExpiryService,
pricing *service.PricingService, pricing *service.PricingService,
emailQueue *service.EmailQueueService, emailQueue *service.EmailQueueService,
billingCache *service.BillingCacheService, billingCache *service.BillingCacheService,
...@@ -194,6 +196,10 @@ func provideCleanup( ...@@ -194,6 +196,10 @@ func provideCleanup(
tokenRefresh.Stop() tokenRefresh.Stop()
return nil return nil
}}, }},
{"AccountExpiryService", func() error {
accountExpiry.Stop()
return nil
}},
{"PricingService", func() error { {"PricingService", func() error {
pricing.Stop() pricing.Stop()
return nil return nil
......
...@@ -49,6 +49,10 @@ type Account struct { ...@@ -49,6 +49,10 @@ type Account struct {
ErrorMessage *string `json:"error_message,omitempty"` ErrorMessage *string `json:"error_message,omitempty"`
// LastUsedAt holds the value of the "last_used_at" field. // LastUsedAt holds the value of the "last_used_at" field.
LastUsedAt *time.Time `json:"last_used_at,omitempty"` LastUsedAt *time.Time `json:"last_used_at,omitempty"`
// Account expiration time (NULL means no expiration).
ExpiresAt *time.Time `json:"expires_at,omitempty"`
// Auto pause scheduling when account expires.
AutoPauseOnExpired bool `json:"auto_pause_on_expired,omitempty"`
// Schedulable holds the value of the "schedulable" field. // Schedulable holds the value of the "schedulable" field.
Schedulable bool `json:"schedulable,omitempty"` Schedulable bool `json:"schedulable,omitempty"`
// RateLimitedAt holds the value of the "rate_limited_at" field. // RateLimitedAt holds the value of the "rate_limited_at" field.
...@@ -129,13 +133,13 @@ func (*Account) scanValues(columns []string) ([]any, error) { ...@@ -129,13 +133,13 @@ func (*Account) scanValues(columns []string) ([]any, error) {
switch columns[i] { switch columns[i] {
case account.FieldCredentials, account.FieldExtra: case account.FieldCredentials, account.FieldExtra:
values[i] = new([]byte) values[i] = new([]byte)
case account.FieldSchedulable: case account.FieldAutoPauseOnExpired, account.FieldSchedulable:
values[i] = new(sql.NullBool) values[i] = new(sql.NullBool)
case account.FieldID, account.FieldProxyID, account.FieldConcurrency, account.FieldPriority: case account.FieldID, account.FieldProxyID, account.FieldConcurrency, account.FieldPriority:
values[i] = new(sql.NullInt64) values[i] = new(sql.NullInt64)
case account.FieldName, account.FieldNotes, account.FieldPlatform, account.FieldType, account.FieldStatus, account.FieldErrorMessage, account.FieldSessionWindowStatus: case account.FieldName, account.FieldNotes, account.FieldPlatform, account.FieldType, account.FieldStatus, account.FieldErrorMessage, account.FieldSessionWindowStatus:
values[i] = new(sql.NullString) values[i] = new(sql.NullString)
case account.FieldCreatedAt, account.FieldUpdatedAt, account.FieldDeletedAt, account.FieldLastUsedAt, account.FieldRateLimitedAt, account.FieldRateLimitResetAt, account.FieldOverloadUntil, account.FieldSessionWindowStart, account.FieldSessionWindowEnd: case account.FieldCreatedAt, account.FieldUpdatedAt, account.FieldDeletedAt, account.FieldLastUsedAt, account.FieldExpiresAt, account.FieldRateLimitedAt, account.FieldRateLimitResetAt, account.FieldOverloadUntil, account.FieldSessionWindowStart, account.FieldSessionWindowEnd:
values[i] = new(sql.NullTime) values[i] = new(sql.NullTime)
default: default:
values[i] = new(sql.UnknownType) values[i] = new(sql.UnknownType)
...@@ -257,6 +261,19 @@ func (_m *Account) assignValues(columns []string, values []any) error { ...@@ -257,6 +261,19 @@ func (_m *Account) assignValues(columns []string, values []any) error {
_m.LastUsedAt = new(time.Time) _m.LastUsedAt = new(time.Time)
*_m.LastUsedAt = value.Time *_m.LastUsedAt = value.Time
} }
case account.FieldExpiresAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field expires_at", values[i])
} else if value.Valid {
_m.ExpiresAt = new(time.Time)
*_m.ExpiresAt = value.Time
}
case account.FieldAutoPauseOnExpired:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field auto_pause_on_expired", values[i])
} else if value.Valid {
_m.AutoPauseOnExpired = value.Bool
}
case account.FieldSchedulable: case account.FieldSchedulable:
if value, ok := values[i].(*sql.NullBool); !ok { if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field schedulable", values[i]) return fmt.Errorf("unexpected type %T for field schedulable", values[i])
...@@ -416,6 +433,14 @@ func (_m *Account) String() string { ...@@ -416,6 +433,14 @@ func (_m *Account) String() string {
builder.WriteString(v.Format(time.ANSIC)) builder.WriteString(v.Format(time.ANSIC))
} }
builder.WriteString(", ") builder.WriteString(", ")
if v := _m.ExpiresAt; v != nil {
builder.WriteString("expires_at=")
builder.WriteString(v.Format(time.ANSIC))
}
builder.WriteString(", ")
builder.WriteString("auto_pause_on_expired=")
builder.WriteString(fmt.Sprintf("%v", _m.AutoPauseOnExpired))
builder.WriteString(", ")
builder.WriteString("schedulable=") builder.WriteString("schedulable=")
builder.WriteString(fmt.Sprintf("%v", _m.Schedulable)) builder.WriteString(fmt.Sprintf("%v", _m.Schedulable))
builder.WriteString(", ") builder.WriteString(", ")
......
...@@ -45,6 +45,10 @@ const ( ...@@ -45,6 +45,10 @@ const (
FieldErrorMessage = "error_message" FieldErrorMessage = "error_message"
// FieldLastUsedAt holds the string denoting the last_used_at field in the database. // FieldLastUsedAt holds the string denoting the last_used_at field in the database.
FieldLastUsedAt = "last_used_at" FieldLastUsedAt = "last_used_at"
// FieldExpiresAt holds the string denoting the expires_at field in the database.
FieldExpiresAt = "expires_at"
// FieldAutoPauseOnExpired holds the string denoting the auto_pause_on_expired field in the database.
FieldAutoPauseOnExpired = "auto_pause_on_expired"
// FieldSchedulable holds the string denoting the schedulable field in the database. // FieldSchedulable holds the string denoting the schedulable field in the database.
FieldSchedulable = "schedulable" FieldSchedulable = "schedulable"
// FieldRateLimitedAt holds the string denoting the rate_limited_at field in the database. // FieldRateLimitedAt holds the string denoting the rate_limited_at field in the database.
...@@ -115,6 +119,8 @@ var Columns = []string{ ...@@ -115,6 +119,8 @@ var Columns = []string{
FieldStatus, FieldStatus,
FieldErrorMessage, FieldErrorMessage,
FieldLastUsedAt, FieldLastUsedAt,
FieldExpiresAt,
FieldAutoPauseOnExpired,
FieldSchedulable, FieldSchedulable,
FieldRateLimitedAt, FieldRateLimitedAt,
FieldRateLimitResetAt, FieldRateLimitResetAt,
...@@ -172,6 +178,8 @@ var ( ...@@ -172,6 +178,8 @@ var (
DefaultStatus string DefaultStatus string
// StatusValidator is a validator for the "status" field. It is called by the builders before save. // StatusValidator is a validator for the "status" field. It is called by the builders before save.
StatusValidator func(string) error StatusValidator func(string) error
// DefaultAutoPauseOnExpired holds the default value on creation for the "auto_pause_on_expired" field.
DefaultAutoPauseOnExpired bool
// DefaultSchedulable holds the default value on creation for the "schedulable" field. // DefaultSchedulable holds the default value on creation for the "schedulable" field.
DefaultSchedulable bool DefaultSchedulable bool
// SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save. // SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
...@@ -251,6 +259,16 @@ func ByLastUsedAt(opts ...sql.OrderTermOption) OrderOption { ...@@ -251,6 +259,16 @@ func ByLastUsedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldLastUsedAt, opts...).ToFunc() return sql.OrderByField(FieldLastUsedAt, opts...).ToFunc()
} }
// ByExpiresAt orders the results by the expires_at field.
func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldExpiresAt, opts...).ToFunc()
}
// ByAutoPauseOnExpired orders the results by the auto_pause_on_expired field.
func ByAutoPauseOnExpired(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldAutoPauseOnExpired, opts...).ToFunc()
}
// BySchedulable orders the results by the schedulable field. // BySchedulable orders the results by the schedulable field.
func BySchedulable(opts ...sql.OrderTermOption) OrderOption { func BySchedulable(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldSchedulable, opts...).ToFunc() return sql.OrderByField(FieldSchedulable, opts...).ToFunc()
......
...@@ -120,6 +120,16 @@ func LastUsedAt(v time.Time) predicate.Account { ...@@ -120,6 +120,16 @@ func LastUsedAt(v time.Time) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldLastUsedAt, v)) return predicate.Account(sql.FieldEQ(FieldLastUsedAt, v))
} }
// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ.
func ExpiresAt(v time.Time) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldExpiresAt, v))
}
// AutoPauseOnExpired applies equality check predicate on the "auto_pause_on_expired" field. It's identical to AutoPauseOnExpiredEQ.
func AutoPauseOnExpired(v bool) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldAutoPauseOnExpired, v))
}
// Schedulable applies equality check predicate on the "schedulable" field. It's identical to SchedulableEQ. // Schedulable applies equality check predicate on the "schedulable" field. It's identical to SchedulableEQ.
func Schedulable(v bool) predicate.Account { func Schedulable(v bool) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldSchedulable, v)) return predicate.Account(sql.FieldEQ(FieldSchedulable, v))
...@@ -855,6 +865,66 @@ func LastUsedAtNotNil() predicate.Account { ...@@ -855,6 +865,66 @@ func LastUsedAtNotNil() predicate.Account {
return predicate.Account(sql.FieldNotNull(FieldLastUsedAt)) return predicate.Account(sql.FieldNotNull(FieldLastUsedAt))
} }
// ExpiresAtEQ applies the EQ predicate on the "expires_at" field.
func ExpiresAtEQ(v time.Time) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldExpiresAt, v))
}
// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field.
func ExpiresAtNEQ(v time.Time) predicate.Account {
return predicate.Account(sql.FieldNEQ(FieldExpiresAt, v))
}
// ExpiresAtIn applies the In predicate on the "expires_at" field.
func ExpiresAtIn(vs ...time.Time) predicate.Account {
return predicate.Account(sql.FieldIn(FieldExpiresAt, vs...))
}
// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field.
func ExpiresAtNotIn(vs ...time.Time) predicate.Account {
return predicate.Account(sql.FieldNotIn(FieldExpiresAt, vs...))
}
// ExpiresAtGT applies the GT predicate on the "expires_at" field.
func ExpiresAtGT(v time.Time) predicate.Account {
return predicate.Account(sql.FieldGT(FieldExpiresAt, v))
}
// ExpiresAtGTE applies the GTE predicate on the "expires_at" field.
func ExpiresAtGTE(v time.Time) predicate.Account {
return predicate.Account(sql.FieldGTE(FieldExpiresAt, v))
}
// ExpiresAtLT applies the LT predicate on the "expires_at" field.
func ExpiresAtLT(v time.Time) predicate.Account {
return predicate.Account(sql.FieldLT(FieldExpiresAt, v))
}
// ExpiresAtLTE applies the LTE predicate on the "expires_at" field.
func ExpiresAtLTE(v time.Time) predicate.Account {
return predicate.Account(sql.FieldLTE(FieldExpiresAt, v))
}
// ExpiresAtIsNil applies the IsNil predicate on the "expires_at" field.
func ExpiresAtIsNil() predicate.Account {
return predicate.Account(sql.FieldIsNull(FieldExpiresAt))
}
// ExpiresAtNotNil applies the NotNil predicate on the "expires_at" field.
func ExpiresAtNotNil() predicate.Account {
return predicate.Account(sql.FieldNotNull(FieldExpiresAt))
}
// AutoPauseOnExpiredEQ applies the EQ predicate on the "auto_pause_on_expired" field.
func AutoPauseOnExpiredEQ(v bool) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldAutoPauseOnExpired, v))
}
// AutoPauseOnExpiredNEQ applies the NEQ predicate on the "auto_pause_on_expired" field.
func AutoPauseOnExpiredNEQ(v bool) predicate.Account {
return predicate.Account(sql.FieldNEQ(FieldAutoPauseOnExpired, v))
}
// SchedulableEQ applies the EQ predicate on the "schedulable" field. // SchedulableEQ applies the EQ predicate on the "schedulable" field.
func SchedulableEQ(v bool) predicate.Account { func SchedulableEQ(v bool) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldSchedulable, v)) return predicate.Account(sql.FieldEQ(FieldSchedulable, v))
......
...@@ -195,6 +195,34 @@ func (_c *AccountCreate) SetNillableLastUsedAt(v *time.Time) *AccountCreate { ...@@ -195,6 +195,34 @@ func (_c *AccountCreate) SetNillableLastUsedAt(v *time.Time) *AccountCreate {
return _c return _c
} }
// SetExpiresAt sets the "expires_at" field.
func (_c *AccountCreate) SetExpiresAt(v time.Time) *AccountCreate {
_c.mutation.SetExpiresAt(v)
return _c
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func (_c *AccountCreate) SetNillableExpiresAt(v *time.Time) *AccountCreate {
if v != nil {
_c.SetExpiresAt(*v)
}
return _c
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func (_c *AccountCreate) SetAutoPauseOnExpired(v bool) *AccountCreate {
_c.mutation.SetAutoPauseOnExpired(v)
return _c
}
// SetNillableAutoPauseOnExpired sets the "auto_pause_on_expired" field if the given value is not nil.
func (_c *AccountCreate) SetNillableAutoPauseOnExpired(v *bool) *AccountCreate {
if v != nil {
_c.SetAutoPauseOnExpired(*v)
}
return _c
}
// SetSchedulable sets the "schedulable" field. // SetSchedulable sets the "schedulable" field.
func (_c *AccountCreate) SetSchedulable(v bool) *AccountCreate { func (_c *AccountCreate) SetSchedulable(v bool) *AccountCreate {
_c.mutation.SetSchedulable(v) _c.mutation.SetSchedulable(v)
...@@ -405,6 +433,10 @@ func (_c *AccountCreate) defaults() error { ...@@ -405,6 +433,10 @@ func (_c *AccountCreate) defaults() error {
v := account.DefaultStatus v := account.DefaultStatus
_c.mutation.SetStatus(v) _c.mutation.SetStatus(v)
} }
if _, ok := _c.mutation.AutoPauseOnExpired(); !ok {
v := account.DefaultAutoPauseOnExpired
_c.mutation.SetAutoPauseOnExpired(v)
}
if _, ok := _c.mutation.Schedulable(); !ok { if _, ok := _c.mutation.Schedulable(); !ok {
v := account.DefaultSchedulable v := account.DefaultSchedulable
_c.mutation.SetSchedulable(v) _c.mutation.SetSchedulable(v)
...@@ -464,6 +496,9 @@ func (_c *AccountCreate) check() error { ...@@ -464,6 +496,9 @@ func (_c *AccountCreate) check() error {
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Account.status": %w`, err)} return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Account.status": %w`, err)}
} }
} }
if _, ok := _c.mutation.AutoPauseOnExpired(); !ok {
return &ValidationError{Name: "auto_pause_on_expired", err: errors.New(`ent: missing required field "Account.auto_pause_on_expired"`)}
}
if _, ok := _c.mutation.Schedulable(); !ok { if _, ok := _c.mutation.Schedulable(); !ok {
return &ValidationError{Name: "schedulable", err: errors.New(`ent: missing required field "Account.schedulable"`)} return &ValidationError{Name: "schedulable", err: errors.New(`ent: missing required field "Account.schedulable"`)}
} }
...@@ -555,6 +590,14 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) { ...@@ -555,6 +590,14 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
_spec.SetField(account.FieldLastUsedAt, field.TypeTime, value) _spec.SetField(account.FieldLastUsedAt, field.TypeTime, value)
_node.LastUsedAt = &value _node.LastUsedAt = &value
} }
if value, ok := _c.mutation.ExpiresAt(); ok {
_spec.SetField(account.FieldExpiresAt, field.TypeTime, value)
_node.ExpiresAt = &value
}
if value, ok := _c.mutation.AutoPauseOnExpired(); ok {
_spec.SetField(account.FieldAutoPauseOnExpired, field.TypeBool, value)
_node.AutoPauseOnExpired = value
}
if value, ok := _c.mutation.Schedulable(); ok { if value, ok := _c.mutation.Schedulable(); ok {
_spec.SetField(account.FieldSchedulable, field.TypeBool, value) _spec.SetField(account.FieldSchedulable, field.TypeBool, value)
_node.Schedulable = value _node.Schedulable = value
...@@ -898,6 +941,36 @@ func (u *AccountUpsert) ClearLastUsedAt() *AccountUpsert { ...@@ -898,6 +941,36 @@ func (u *AccountUpsert) ClearLastUsedAt() *AccountUpsert {
return u return u
} }
// SetExpiresAt sets the "expires_at" field.
func (u *AccountUpsert) SetExpiresAt(v time.Time) *AccountUpsert {
u.Set(account.FieldExpiresAt, v)
return u
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func (u *AccountUpsert) UpdateExpiresAt() *AccountUpsert {
u.SetExcluded(account.FieldExpiresAt)
return u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func (u *AccountUpsert) ClearExpiresAt() *AccountUpsert {
u.SetNull(account.FieldExpiresAt)
return u
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func (u *AccountUpsert) SetAutoPauseOnExpired(v bool) *AccountUpsert {
u.Set(account.FieldAutoPauseOnExpired, v)
return u
}
// UpdateAutoPauseOnExpired sets the "auto_pause_on_expired" field to the value that was provided on create.
func (u *AccountUpsert) UpdateAutoPauseOnExpired() *AccountUpsert {
u.SetExcluded(account.FieldAutoPauseOnExpired)
return u
}
// SetSchedulable sets the "schedulable" field. // SetSchedulable sets the "schedulable" field.
func (u *AccountUpsert) SetSchedulable(v bool) *AccountUpsert { func (u *AccountUpsert) SetSchedulable(v bool) *AccountUpsert {
u.Set(account.FieldSchedulable, v) u.Set(account.FieldSchedulable, v)
...@@ -1308,6 +1381,41 @@ func (u *AccountUpsertOne) ClearLastUsedAt() *AccountUpsertOne { ...@@ -1308,6 +1381,41 @@ func (u *AccountUpsertOne) ClearLastUsedAt() *AccountUpsertOne {
}) })
} }
// SetExpiresAt sets the "expires_at" field.
func (u *AccountUpsertOne) SetExpiresAt(v time.Time) *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.SetExpiresAt(v)
})
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func (u *AccountUpsertOne) UpdateExpiresAt() *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.UpdateExpiresAt()
})
}
// ClearExpiresAt clears the value of the "expires_at" field.
func (u *AccountUpsertOne) ClearExpiresAt() *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.ClearExpiresAt()
})
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func (u *AccountUpsertOne) SetAutoPauseOnExpired(v bool) *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.SetAutoPauseOnExpired(v)
})
}
// UpdateAutoPauseOnExpired sets the "auto_pause_on_expired" field to the value that was provided on create.
func (u *AccountUpsertOne) UpdateAutoPauseOnExpired() *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.UpdateAutoPauseOnExpired()
})
}
// SetSchedulable sets the "schedulable" field. // SetSchedulable sets the "schedulable" field.
func (u *AccountUpsertOne) SetSchedulable(v bool) *AccountUpsertOne { func (u *AccountUpsertOne) SetSchedulable(v bool) *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) { return u.Update(func(s *AccountUpsert) {
...@@ -1904,6 +2012,41 @@ func (u *AccountUpsertBulk) ClearLastUsedAt() *AccountUpsertBulk { ...@@ -1904,6 +2012,41 @@ func (u *AccountUpsertBulk) ClearLastUsedAt() *AccountUpsertBulk {
}) })
} }
// SetExpiresAt sets the "expires_at" field.
func (u *AccountUpsertBulk) SetExpiresAt(v time.Time) *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.SetExpiresAt(v)
})
}
// UpdateExpiresAt sets the "expires_at" field to the value that was provided on create.
func (u *AccountUpsertBulk) UpdateExpiresAt() *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.UpdateExpiresAt()
})
}
// ClearExpiresAt clears the value of the "expires_at" field.
func (u *AccountUpsertBulk) ClearExpiresAt() *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.ClearExpiresAt()
})
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func (u *AccountUpsertBulk) SetAutoPauseOnExpired(v bool) *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.SetAutoPauseOnExpired(v)
})
}
// UpdateAutoPauseOnExpired sets the "auto_pause_on_expired" field to the value that was provided on create.
func (u *AccountUpsertBulk) UpdateAutoPauseOnExpired() *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.UpdateAutoPauseOnExpired()
})
}
// SetSchedulable sets the "schedulable" field. // SetSchedulable sets the "schedulable" field.
func (u *AccountUpsertBulk) SetSchedulable(v bool) *AccountUpsertBulk { func (u *AccountUpsertBulk) SetSchedulable(v bool) *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) { return u.Update(func(s *AccountUpsert) {
......
...@@ -247,6 +247,40 @@ func (_u *AccountUpdate) ClearLastUsedAt() *AccountUpdate { ...@@ -247,6 +247,40 @@ func (_u *AccountUpdate) ClearLastUsedAt() *AccountUpdate {
return _u return _u
} }
// SetExpiresAt sets the "expires_at" field.
func (_u *AccountUpdate) SetExpiresAt(v time.Time) *AccountUpdate {
_u.mutation.SetExpiresAt(v)
return _u
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func (_u *AccountUpdate) SetNillableExpiresAt(v *time.Time) *AccountUpdate {
if v != nil {
_u.SetExpiresAt(*v)
}
return _u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func (_u *AccountUpdate) ClearExpiresAt() *AccountUpdate {
_u.mutation.ClearExpiresAt()
return _u
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func (_u *AccountUpdate) SetAutoPauseOnExpired(v bool) *AccountUpdate {
_u.mutation.SetAutoPauseOnExpired(v)
return _u
}
// SetNillableAutoPauseOnExpired sets the "auto_pause_on_expired" field if the given value is not nil.
func (_u *AccountUpdate) SetNillableAutoPauseOnExpired(v *bool) *AccountUpdate {
if v != nil {
_u.SetAutoPauseOnExpired(*v)
}
return _u
}
// SetSchedulable sets the "schedulable" field. // SetSchedulable sets the "schedulable" field.
func (_u *AccountUpdate) SetSchedulable(v bool) *AccountUpdate { func (_u *AccountUpdate) SetSchedulable(v bool) *AccountUpdate {
_u.mutation.SetSchedulable(v) _u.mutation.SetSchedulable(v)
...@@ -610,6 +644,15 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) { ...@@ -610,6 +644,15 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if _u.mutation.LastUsedAtCleared() { if _u.mutation.LastUsedAtCleared() {
_spec.ClearField(account.FieldLastUsedAt, field.TypeTime) _spec.ClearField(account.FieldLastUsedAt, field.TypeTime)
} }
if value, ok := _u.mutation.ExpiresAt(); ok {
_spec.SetField(account.FieldExpiresAt, field.TypeTime, value)
}
if _u.mutation.ExpiresAtCleared() {
_spec.ClearField(account.FieldExpiresAt, field.TypeTime)
}
if value, ok := _u.mutation.AutoPauseOnExpired(); ok {
_spec.SetField(account.FieldAutoPauseOnExpired, field.TypeBool, value)
}
if value, ok := _u.mutation.Schedulable(); ok { if value, ok := _u.mutation.Schedulable(); ok {
_spec.SetField(account.FieldSchedulable, field.TypeBool, value) _spec.SetField(account.FieldSchedulable, field.TypeBool, value)
} }
...@@ -1016,6 +1059,40 @@ func (_u *AccountUpdateOne) ClearLastUsedAt() *AccountUpdateOne { ...@@ -1016,6 +1059,40 @@ func (_u *AccountUpdateOne) ClearLastUsedAt() *AccountUpdateOne {
return _u return _u
} }
// SetExpiresAt sets the "expires_at" field.
func (_u *AccountUpdateOne) SetExpiresAt(v time.Time) *AccountUpdateOne {
_u.mutation.SetExpiresAt(v)
return _u
}
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
func (_u *AccountUpdateOne) SetNillableExpiresAt(v *time.Time) *AccountUpdateOne {
if v != nil {
_u.SetExpiresAt(*v)
}
return _u
}
// ClearExpiresAt clears the value of the "expires_at" field.
func (_u *AccountUpdateOne) ClearExpiresAt() *AccountUpdateOne {
_u.mutation.ClearExpiresAt()
return _u
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func (_u *AccountUpdateOne) SetAutoPauseOnExpired(v bool) *AccountUpdateOne {
_u.mutation.SetAutoPauseOnExpired(v)
return _u
}
// SetNillableAutoPauseOnExpired sets the "auto_pause_on_expired" field if the given value is not nil.
func (_u *AccountUpdateOne) SetNillableAutoPauseOnExpired(v *bool) *AccountUpdateOne {
if v != nil {
_u.SetAutoPauseOnExpired(*v)
}
return _u
}
// SetSchedulable sets the "schedulable" field. // SetSchedulable sets the "schedulable" field.
func (_u *AccountUpdateOne) SetSchedulable(v bool) *AccountUpdateOne { func (_u *AccountUpdateOne) SetSchedulable(v bool) *AccountUpdateOne {
_u.mutation.SetSchedulable(v) _u.mutation.SetSchedulable(v)
...@@ -1409,6 +1486,15 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er ...@@ -1409,6 +1486,15 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
if _u.mutation.LastUsedAtCleared() { if _u.mutation.LastUsedAtCleared() {
_spec.ClearField(account.FieldLastUsedAt, field.TypeTime) _spec.ClearField(account.FieldLastUsedAt, field.TypeTime)
} }
if value, ok := _u.mutation.ExpiresAt(); ok {
_spec.SetField(account.FieldExpiresAt, field.TypeTime, value)
}
if _u.mutation.ExpiresAtCleared() {
_spec.ClearField(account.FieldExpiresAt, field.TypeTime)
}
if value, ok := _u.mutation.AutoPauseOnExpired(); ok {
_spec.SetField(account.FieldAutoPauseOnExpired, field.TypeBool, value)
}
if value, ok := _u.mutation.Schedulable(); ok { if value, ok := _u.mutation.Schedulable(); ok {
_spec.SetField(account.FieldSchedulable, field.TypeBool, value) _spec.SetField(account.FieldSchedulable, field.TypeBool, value)
} }
......
...@@ -80,6 +80,8 @@ var ( ...@@ -80,6 +80,8 @@ var (
{Name: "status", Type: field.TypeString, Size: 20, Default: "active"}, {Name: "status", Type: field.TypeString, Size: 20, Default: "active"},
{Name: "error_message", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}}, {Name: "error_message", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
{Name: "last_used_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, {Name: "last_used_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
{Name: "expires_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
{Name: "auto_pause_on_expired", Type: field.TypeBool, Default: true},
{Name: "schedulable", Type: field.TypeBool, Default: true}, {Name: "schedulable", Type: field.TypeBool, Default: true},
{Name: "rate_limited_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, {Name: "rate_limited_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
{Name: "rate_limit_reset_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, {Name: "rate_limit_reset_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
...@@ -97,7 +99,7 @@ var ( ...@@ -97,7 +99,7 @@ var (
ForeignKeys: []*schema.ForeignKey{ ForeignKeys: []*schema.ForeignKey{
{ {
Symbol: "accounts_proxies_proxy", Symbol: "accounts_proxies_proxy",
Columns: []*schema.Column{AccountsColumns[22]}, Columns: []*schema.Column{AccountsColumns[24]},
RefColumns: []*schema.Column{ProxiesColumns[0]}, RefColumns: []*schema.Column{ProxiesColumns[0]},
OnDelete: schema.SetNull, OnDelete: schema.SetNull,
}, },
...@@ -121,7 +123,7 @@ var ( ...@@ -121,7 +123,7 @@ var (
{ {
Name: "account_proxy_id", Name: "account_proxy_id",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[22]}, Columns: []*schema.Column{AccountsColumns[24]},
}, },
{ {
Name: "account_priority", Name: "account_priority",
...@@ -136,22 +138,22 @@ var ( ...@@ -136,22 +138,22 @@ var (
{ {
Name: "account_schedulable", Name: "account_schedulable",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[15]}, Columns: []*schema.Column{AccountsColumns[17]},
}, },
{ {
Name: "account_rate_limited_at", Name: "account_rate_limited_at",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[16]}, Columns: []*schema.Column{AccountsColumns[18]},
}, },
{ {
Name: "account_rate_limit_reset_at", Name: "account_rate_limit_reset_at",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[17]}, Columns: []*schema.Column{AccountsColumns[19]},
}, },
{ {
Name: "account_overload_until", Name: "account_overload_until",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[18]}, Columns: []*schema.Column{AccountsColumns[20]},
}, },
{ {
Name: "account_deleted_at", Name: "account_deleted_at",
...@@ -371,6 +373,7 @@ var ( ...@@ -371,6 +373,7 @@ var (
{Name: "stream", Type: field.TypeBool, Default: false}, {Name: "stream", Type: field.TypeBool, Default: false},
{Name: "duration_ms", Type: field.TypeInt, Nullable: true}, {Name: "duration_ms", Type: field.TypeInt, Nullable: true},
{Name: "first_token_ms", Type: field.TypeInt, Nullable: true}, {Name: "first_token_ms", Type: field.TypeInt, Nullable: true},
{Name: "user_agent", Type: field.TypeString, Nullable: true, Size: 512},
{Name: "image_count", Type: field.TypeInt, Default: 0}, {Name: "image_count", Type: field.TypeInt, Default: 0},
{Name: "image_size", Type: field.TypeString, Nullable: true, Size: 10}, {Name: "image_size", Type: field.TypeString, Nullable: true, Size: 10},
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, {Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
...@@ -388,31 +391,31 @@ var ( ...@@ -388,31 +391,31 @@ var (
ForeignKeys: []*schema.ForeignKey{ ForeignKeys: []*schema.ForeignKey{
{ {
Symbol: "usage_logs_api_keys_usage_logs", Symbol: "usage_logs_api_keys_usage_logs",
Columns: []*schema.Column{UsageLogsColumns[23]}, Columns: []*schema.Column{UsageLogsColumns[24]},
RefColumns: []*schema.Column{APIKeysColumns[0]}, RefColumns: []*schema.Column{APIKeysColumns[0]},
OnDelete: schema.NoAction, OnDelete: schema.NoAction,
}, },
{ {
Symbol: "usage_logs_accounts_usage_logs", Symbol: "usage_logs_accounts_usage_logs",
Columns: []*schema.Column{UsageLogsColumns[24]}, Columns: []*schema.Column{UsageLogsColumns[25]},
RefColumns: []*schema.Column{AccountsColumns[0]}, RefColumns: []*schema.Column{AccountsColumns[0]},
OnDelete: schema.NoAction, OnDelete: schema.NoAction,
}, },
{ {
Symbol: "usage_logs_groups_usage_logs", Symbol: "usage_logs_groups_usage_logs",
Columns: []*schema.Column{UsageLogsColumns[25]}, Columns: []*schema.Column{UsageLogsColumns[26]},
RefColumns: []*schema.Column{GroupsColumns[0]}, RefColumns: []*schema.Column{GroupsColumns[0]},
OnDelete: schema.SetNull, OnDelete: schema.SetNull,
}, },
{ {
Symbol: "usage_logs_users_usage_logs", Symbol: "usage_logs_users_usage_logs",
Columns: []*schema.Column{UsageLogsColumns[26]}, Columns: []*schema.Column{UsageLogsColumns[27]},
RefColumns: []*schema.Column{UsersColumns[0]}, RefColumns: []*schema.Column{UsersColumns[0]},
OnDelete: schema.NoAction, OnDelete: schema.NoAction,
}, },
{ {
Symbol: "usage_logs_user_subscriptions_usage_logs", Symbol: "usage_logs_user_subscriptions_usage_logs",
Columns: []*schema.Column{UsageLogsColumns[27]}, Columns: []*schema.Column{UsageLogsColumns[28]},
RefColumns: []*schema.Column{UserSubscriptionsColumns[0]}, RefColumns: []*schema.Column{UserSubscriptionsColumns[0]},
OnDelete: schema.SetNull, OnDelete: schema.SetNull,
}, },
...@@ -421,32 +424,32 @@ var ( ...@@ -421,32 +424,32 @@ var (
{ {
Name: "usagelog_user_id", Name: "usagelog_user_id",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[26]}, Columns: []*schema.Column{UsageLogsColumns[27]},
}, },
{ {
Name: "usagelog_api_key_id", Name: "usagelog_api_key_id",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[23]}, Columns: []*schema.Column{UsageLogsColumns[24]},
}, },
{ {
Name: "usagelog_account_id", Name: "usagelog_account_id",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[24]}, Columns: []*schema.Column{UsageLogsColumns[25]},
}, },
{ {
Name: "usagelog_group_id", Name: "usagelog_group_id",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[25]}, Columns: []*schema.Column{UsageLogsColumns[26]},
}, },
{ {
Name: "usagelog_subscription_id", Name: "usagelog_subscription_id",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[27]}, Columns: []*schema.Column{UsageLogsColumns[28]},
}, },
{ {
Name: "usagelog_created_at", Name: "usagelog_created_at",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[22]}, Columns: []*schema.Column{UsageLogsColumns[23]},
}, },
{ {
Name: "usagelog_model", Name: "usagelog_model",
...@@ -461,12 +464,12 @@ var ( ...@@ -461,12 +464,12 @@ var (
{ {
Name: "usagelog_user_id_created_at", Name: "usagelog_user_id_created_at",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[26], UsageLogsColumns[22]}, Columns: []*schema.Column{UsageLogsColumns[27], UsageLogsColumns[23]},
}, },
{ {
Name: "usagelog_api_key_id_created_at", Name: "usagelog_api_key_id_created_at",
Unique: false, Unique: false,
Columns: []*schema.Column{UsageLogsColumns[23], UsageLogsColumns[22]}, Columns: []*schema.Column{UsageLogsColumns[24], UsageLogsColumns[23]},
}, },
}, },
} }
......
...@@ -1006,6 +1006,8 @@ type AccountMutation struct { ...@@ -1006,6 +1006,8 @@ type AccountMutation struct {
status *string status *string
error_message *string error_message *string
last_used_at *time.Time last_used_at *time.Time
expires_at *time.Time
auto_pause_on_expired *bool
schedulable *bool schedulable *bool
rate_limited_at *time.Time rate_limited_at *time.Time
rate_limit_reset_at *time.Time rate_limit_reset_at *time.Time
...@@ -1770,6 +1772,91 @@ func (m *AccountMutation) ResetLastUsedAt() { ...@@ -1770,6 +1772,91 @@ func (m *AccountMutation) ResetLastUsedAt() {
delete(m.clearedFields, account.FieldLastUsedAt) delete(m.clearedFields, account.FieldLastUsedAt)
} }
// SetExpiresAt sets the "expires_at" field.
func (m *AccountMutation) SetExpiresAt(t time.Time) {
m.expires_at = &t
}
// ExpiresAt returns the value of the "expires_at" field in the mutation.
func (m *AccountMutation) ExpiresAt() (r time.Time, exists bool) {
v := m.expires_at
if v == nil {
return
}
return *v, true
}
// OldExpiresAt returns the old "expires_at" field's value of the Account entity.
// If the Account object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *AccountMutation) OldExpiresAt(ctx context.Context) (v *time.Time, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldExpiresAt is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldExpiresAt requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldExpiresAt: %w", err)
}
return oldValue.ExpiresAt, nil
}
// ClearExpiresAt clears the value of the "expires_at" field.
func (m *AccountMutation) ClearExpiresAt() {
m.expires_at = nil
m.clearedFields[account.FieldExpiresAt] = struct{}{}
}
// ExpiresAtCleared returns if the "expires_at" field was cleared in this mutation.
func (m *AccountMutation) ExpiresAtCleared() bool {
_, ok := m.clearedFields[account.FieldExpiresAt]
return ok
}
// ResetExpiresAt resets all changes to the "expires_at" field.
func (m *AccountMutation) ResetExpiresAt() {
m.expires_at = nil
delete(m.clearedFields, account.FieldExpiresAt)
}
// SetAutoPauseOnExpired sets the "auto_pause_on_expired" field.
func (m *AccountMutation) SetAutoPauseOnExpired(b bool) {
m.auto_pause_on_expired = &b
}
// AutoPauseOnExpired returns the value of the "auto_pause_on_expired" field in the mutation.
func (m *AccountMutation) AutoPauseOnExpired() (r bool, exists bool) {
v := m.auto_pause_on_expired
if v == nil {
return
}
return *v, true
}
// OldAutoPauseOnExpired returns the old "auto_pause_on_expired" field's value of the Account entity.
// If the Account object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *AccountMutation) OldAutoPauseOnExpired(ctx context.Context) (v bool, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldAutoPauseOnExpired is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldAutoPauseOnExpired requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldAutoPauseOnExpired: %w", err)
}
return oldValue.AutoPauseOnExpired, nil
}
// ResetAutoPauseOnExpired resets all changes to the "auto_pause_on_expired" field.
func (m *AccountMutation) ResetAutoPauseOnExpired() {
m.auto_pause_on_expired = nil
}
// SetSchedulable sets the "schedulable" field. // SetSchedulable sets the "schedulable" field.
func (m *AccountMutation) SetSchedulable(b bool) { func (m *AccountMutation) SetSchedulable(b bool) {
m.schedulable = &b m.schedulable = &b
...@@ -2269,7 +2356,7 @@ func (m *AccountMutation) Type() string { ...@@ -2269,7 +2356,7 @@ func (m *AccountMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call // order to get all numeric fields that were incremented/decremented, call
// AddedFields(). // AddedFields().
func (m *AccountMutation) Fields() []string { func (m *AccountMutation) Fields() []string {
fields := make([]string, 0, 22) fields := make([]string, 0, 24)
if m.created_at != nil { if m.created_at != nil {
fields = append(fields, account.FieldCreatedAt) fields = append(fields, account.FieldCreatedAt)
} }
...@@ -2315,6 +2402,12 @@ func (m *AccountMutation) Fields() []string { ...@@ -2315,6 +2402,12 @@ func (m *AccountMutation) Fields() []string {
if m.last_used_at != nil { if m.last_used_at != nil {
fields = append(fields, account.FieldLastUsedAt) fields = append(fields, account.FieldLastUsedAt)
} }
if m.expires_at != nil {
fields = append(fields, account.FieldExpiresAt)
}
if m.auto_pause_on_expired != nil {
fields = append(fields, account.FieldAutoPauseOnExpired)
}
if m.schedulable != nil { if m.schedulable != nil {
fields = append(fields, account.FieldSchedulable) fields = append(fields, account.FieldSchedulable)
} }
...@@ -2374,6 +2467,10 @@ func (m *AccountMutation) Field(name string) (ent.Value, bool) { ...@@ -2374,6 +2467,10 @@ func (m *AccountMutation) Field(name string) (ent.Value, bool) {
return m.ErrorMessage() return m.ErrorMessage()
case account.FieldLastUsedAt: case account.FieldLastUsedAt:
return m.LastUsedAt() return m.LastUsedAt()
case account.FieldExpiresAt:
return m.ExpiresAt()
case account.FieldAutoPauseOnExpired:
return m.AutoPauseOnExpired()
case account.FieldSchedulable: case account.FieldSchedulable:
return m.Schedulable() return m.Schedulable()
case account.FieldRateLimitedAt: case account.FieldRateLimitedAt:
...@@ -2427,6 +2524,10 @@ func (m *AccountMutation) OldField(ctx context.Context, name string) (ent.Value, ...@@ -2427,6 +2524,10 @@ func (m *AccountMutation) OldField(ctx context.Context, name string) (ent.Value,
return m.OldErrorMessage(ctx) return m.OldErrorMessage(ctx)
case account.FieldLastUsedAt: case account.FieldLastUsedAt:
return m.OldLastUsedAt(ctx) return m.OldLastUsedAt(ctx)
case account.FieldExpiresAt:
return m.OldExpiresAt(ctx)
case account.FieldAutoPauseOnExpired:
return m.OldAutoPauseOnExpired(ctx)
case account.FieldSchedulable: case account.FieldSchedulable:
return m.OldSchedulable(ctx) return m.OldSchedulable(ctx)
case account.FieldRateLimitedAt: case account.FieldRateLimitedAt:
...@@ -2555,6 +2656,20 @@ func (m *AccountMutation) SetField(name string, value ent.Value) error { ...@@ -2555,6 +2656,20 @@ func (m *AccountMutation) SetField(name string, value ent.Value) error {
} }
m.SetLastUsedAt(v) m.SetLastUsedAt(v)
return nil return nil
case account.FieldExpiresAt:
v, ok := value.(time.Time)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetExpiresAt(v)
return nil
case account.FieldAutoPauseOnExpired:
v, ok := value.(bool)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetAutoPauseOnExpired(v)
return nil
case account.FieldSchedulable: case account.FieldSchedulable:
v, ok := value.(bool) v, ok := value.(bool)
if !ok { if !ok {
...@@ -2676,6 +2791,9 @@ func (m *AccountMutation) ClearedFields() []string { ...@@ -2676,6 +2791,9 @@ func (m *AccountMutation) ClearedFields() []string {
if m.FieldCleared(account.FieldLastUsedAt) { if m.FieldCleared(account.FieldLastUsedAt) {
fields = append(fields, account.FieldLastUsedAt) fields = append(fields, account.FieldLastUsedAt)
} }
if m.FieldCleared(account.FieldExpiresAt) {
fields = append(fields, account.FieldExpiresAt)
}
if m.FieldCleared(account.FieldRateLimitedAt) { if m.FieldCleared(account.FieldRateLimitedAt) {
fields = append(fields, account.FieldRateLimitedAt) fields = append(fields, account.FieldRateLimitedAt)
} }
...@@ -2723,6 +2841,9 @@ func (m *AccountMutation) ClearField(name string) error { ...@@ -2723,6 +2841,9 @@ func (m *AccountMutation) ClearField(name string) error {
case account.FieldLastUsedAt: case account.FieldLastUsedAt:
m.ClearLastUsedAt() m.ClearLastUsedAt()
return nil return nil
case account.FieldExpiresAt:
m.ClearExpiresAt()
return nil
case account.FieldRateLimitedAt: case account.FieldRateLimitedAt:
m.ClearRateLimitedAt() m.ClearRateLimitedAt()
return nil return nil
...@@ -2794,6 +2915,12 @@ func (m *AccountMutation) ResetField(name string) error { ...@@ -2794,6 +2915,12 @@ func (m *AccountMutation) ResetField(name string) error {
case account.FieldLastUsedAt: case account.FieldLastUsedAt:
m.ResetLastUsedAt() m.ResetLastUsedAt()
return nil return nil
case account.FieldExpiresAt:
m.ResetExpiresAt()
return nil
case account.FieldAutoPauseOnExpired:
m.ResetAutoPauseOnExpired()
return nil
case account.FieldSchedulable: case account.FieldSchedulable:
m.ResetSchedulable() m.ResetSchedulable()
return nil return nil
...@@ -8107,6 +8234,7 @@ type UsageLogMutation struct { ...@@ -8107,6 +8234,7 @@ type UsageLogMutation struct {
addduration_ms *int addduration_ms *int
first_token_ms *int first_token_ms *int
addfirst_token_ms *int addfirst_token_ms *int
user_agent *string
image_count *int image_count *int
addimage_count *int addimage_count *int
image_size *string image_size *string
...@@ -9463,6 +9591,55 @@ func (m *UsageLogMutation) ResetFirstTokenMs() { ...@@ -9463,6 +9591,55 @@ func (m *UsageLogMutation) ResetFirstTokenMs() {
delete(m.clearedFields, usagelog.FieldFirstTokenMs) delete(m.clearedFields, usagelog.FieldFirstTokenMs)
} }
// SetUserAgent sets the "user_agent" field.
func (m *UsageLogMutation) SetUserAgent(s string) {
m.user_agent = &s
}
// UserAgent returns the value of the "user_agent" field in the mutation.
func (m *UsageLogMutation) UserAgent() (r string, exists bool) {
v := m.user_agent
if v == nil {
return
}
return *v, true
}
// OldUserAgent returns the old "user_agent" field's value of the UsageLog entity.
// If the UsageLog object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *UsageLogMutation) OldUserAgent(ctx context.Context) (v *string, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldUserAgent is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldUserAgent requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldUserAgent: %w", err)
}
return oldValue.UserAgent, nil
}
// ClearUserAgent clears the value of the "user_agent" field.
func (m *UsageLogMutation) ClearUserAgent() {
m.user_agent = nil
m.clearedFields[usagelog.FieldUserAgent] = struct{}{}
}
// UserAgentCleared returns if the "user_agent" field was cleared in this mutation.
func (m *UsageLogMutation) UserAgentCleared() bool {
_, ok := m.clearedFields[usagelog.FieldUserAgent]
return ok
}
// ResetUserAgent resets all changes to the "user_agent" field.
func (m *UsageLogMutation) ResetUserAgent() {
m.user_agent = nil
delete(m.clearedFields, usagelog.FieldUserAgent)
}
// SetImageCount sets the "image_count" field. // SetImageCount sets the "image_count" field.
func (m *UsageLogMutation) SetImageCount(i int) { func (m *UsageLogMutation) SetImageCount(i int) {
m.image_count = &i m.image_count = &i
...@@ -9773,7 +9950,7 @@ func (m *UsageLogMutation) Type() string { ...@@ -9773,7 +9950,7 @@ func (m *UsageLogMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call // order to get all numeric fields that were incremented/decremented, call
// AddedFields(). // AddedFields().
func (m *UsageLogMutation) Fields() []string { func (m *UsageLogMutation) Fields() []string {
fields := make([]string, 0, 27) fields := make([]string, 0, 28)
if m.user != nil { if m.user != nil {
fields = append(fields, usagelog.FieldUserID) fields = append(fields, usagelog.FieldUserID)
} }
...@@ -9846,6 +10023,9 @@ func (m *UsageLogMutation) Fields() []string { ...@@ -9846,6 +10023,9 @@ func (m *UsageLogMutation) Fields() []string {
if m.first_token_ms != nil { if m.first_token_ms != nil {
fields = append(fields, usagelog.FieldFirstTokenMs) fields = append(fields, usagelog.FieldFirstTokenMs)
} }
if m.user_agent != nil {
fields = append(fields, usagelog.FieldUserAgent)
}
if m.image_count != nil { if m.image_count != nil {
fields = append(fields, usagelog.FieldImageCount) fields = append(fields, usagelog.FieldImageCount)
} }
...@@ -9911,6 +10091,8 @@ func (m *UsageLogMutation) Field(name string) (ent.Value, bool) { ...@@ -9911,6 +10091,8 @@ func (m *UsageLogMutation) Field(name string) (ent.Value, bool) {
return m.DurationMs() return m.DurationMs()
case usagelog.FieldFirstTokenMs: case usagelog.FieldFirstTokenMs:
return m.FirstTokenMs() return m.FirstTokenMs()
case usagelog.FieldUserAgent:
return m.UserAgent()
case usagelog.FieldImageCount: case usagelog.FieldImageCount:
return m.ImageCount() return m.ImageCount()
case usagelog.FieldImageSize: case usagelog.FieldImageSize:
...@@ -9974,6 +10156,8 @@ func (m *UsageLogMutation) OldField(ctx context.Context, name string) (ent.Value ...@@ -9974,6 +10156,8 @@ func (m *UsageLogMutation) OldField(ctx context.Context, name string) (ent.Value
return m.OldDurationMs(ctx) return m.OldDurationMs(ctx)
case usagelog.FieldFirstTokenMs: case usagelog.FieldFirstTokenMs:
return m.OldFirstTokenMs(ctx) return m.OldFirstTokenMs(ctx)
case usagelog.FieldUserAgent:
return m.OldUserAgent(ctx)
case usagelog.FieldImageCount: case usagelog.FieldImageCount:
return m.OldImageCount(ctx) return m.OldImageCount(ctx)
case usagelog.FieldImageSize: case usagelog.FieldImageSize:
...@@ -10157,6 +10341,13 @@ func (m *UsageLogMutation) SetField(name string, value ent.Value) error { ...@@ -10157,6 +10341,13 @@ func (m *UsageLogMutation) SetField(name string, value ent.Value) error {
} }
m.SetFirstTokenMs(v) m.SetFirstTokenMs(v)
return nil return nil
case usagelog.FieldUserAgent:
v, ok := value.(string)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetUserAgent(v)
return nil
case usagelog.FieldImageCount: case usagelog.FieldImageCount:
v, ok := value.(int) v, ok := value.(int)
if !ok { if !ok {
...@@ -10427,6 +10618,9 @@ func (m *UsageLogMutation) ClearedFields() []string { ...@@ -10427,6 +10618,9 @@ func (m *UsageLogMutation) ClearedFields() []string {
if m.FieldCleared(usagelog.FieldFirstTokenMs) { if m.FieldCleared(usagelog.FieldFirstTokenMs) {
fields = append(fields, usagelog.FieldFirstTokenMs) fields = append(fields, usagelog.FieldFirstTokenMs)
} }
if m.FieldCleared(usagelog.FieldUserAgent) {
fields = append(fields, usagelog.FieldUserAgent)
}
if m.FieldCleared(usagelog.FieldImageSize) { if m.FieldCleared(usagelog.FieldImageSize) {
fields = append(fields, usagelog.FieldImageSize) fields = append(fields, usagelog.FieldImageSize)
} }
...@@ -10456,6 +10650,9 @@ func (m *UsageLogMutation) ClearField(name string) error { ...@@ -10456,6 +10650,9 @@ func (m *UsageLogMutation) ClearField(name string) error {
case usagelog.FieldFirstTokenMs: case usagelog.FieldFirstTokenMs:
m.ClearFirstTokenMs() m.ClearFirstTokenMs()
return nil return nil
case usagelog.FieldUserAgent:
m.ClearUserAgent()
return nil
case usagelog.FieldImageSize: case usagelog.FieldImageSize:
m.ClearImageSize() m.ClearImageSize()
return nil return nil
...@@ -10539,6 +10736,9 @@ func (m *UsageLogMutation) ResetField(name string) error { ...@@ -10539,6 +10736,9 @@ func (m *UsageLogMutation) ResetField(name string) error {
case usagelog.FieldFirstTokenMs: case usagelog.FieldFirstTokenMs:
m.ResetFirstTokenMs() m.ResetFirstTokenMs()
return nil return nil
case usagelog.FieldUserAgent:
m.ResetUserAgent()
return nil
case usagelog.FieldImageCount: case usagelog.FieldImageCount:
m.ResetImageCount() m.ResetImageCount()
return nil return nil
......
...@@ -181,12 +181,16 @@ func init() { ...@@ -181,12 +181,16 @@ func init() {
account.DefaultStatus = accountDescStatus.Default.(string) account.DefaultStatus = accountDescStatus.Default.(string)
// account.StatusValidator is a validator for the "status" field. It is called by the builders before save. // account.StatusValidator is a validator for the "status" field. It is called by the builders before save.
account.StatusValidator = accountDescStatus.Validators[0].(func(string) error) account.StatusValidator = accountDescStatus.Validators[0].(func(string) error)
// accountDescAutoPauseOnExpired is the schema descriptor for auto_pause_on_expired field.
accountDescAutoPauseOnExpired := accountFields[13].Descriptor()
// account.DefaultAutoPauseOnExpired holds the default value on creation for the auto_pause_on_expired field.
account.DefaultAutoPauseOnExpired = accountDescAutoPauseOnExpired.Default.(bool)
// accountDescSchedulable is the schema descriptor for schedulable field. // accountDescSchedulable is the schema descriptor for schedulable field.
accountDescSchedulable := accountFields[12].Descriptor() accountDescSchedulable := accountFields[14].Descriptor()
// account.DefaultSchedulable holds the default value on creation for the schedulable field. // account.DefaultSchedulable holds the default value on creation for the schedulable field.
account.DefaultSchedulable = accountDescSchedulable.Default.(bool) account.DefaultSchedulable = accountDescSchedulable.Default.(bool)
// accountDescSessionWindowStatus is the schema descriptor for session_window_status field. // accountDescSessionWindowStatus is the schema descriptor for session_window_status field.
accountDescSessionWindowStatus := accountFields[18].Descriptor() accountDescSessionWindowStatus := accountFields[20].Descriptor()
// account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save. // account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
account.SessionWindowStatusValidator = accountDescSessionWindowStatus.Validators[0].(func(string) error) account.SessionWindowStatusValidator = accountDescSessionWindowStatus.Validators[0].(func(string) error)
accountgroupFields := schema.AccountGroup{}.Fields() accountgroupFields := schema.AccountGroup{}.Fields()
...@@ -521,16 +525,20 @@ func init() { ...@@ -521,16 +525,20 @@ func init() {
usagelogDescStream := usagelogFields[21].Descriptor() usagelogDescStream := usagelogFields[21].Descriptor()
// usagelog.DefaultStream holds the default value on creation for the stream field. // usagelog.DefaultStream holds the default value on creation for the stream field.
usagelog.DefaultStream = usagelogDescStream.Default.(bool) usagelog.DefaultStream = usagelogDescStream.Default.(bool)
// usagelogDescUserAgent is the schema descriptor for user_agent field.
usagelogDescUserAgent := usagelogFields[24].Descriptor()
// usagelog.UserAgentValidator is a validator for the "user_agent" field. It is called by the builders before save.
usagelog.UserAgentValidator = usagelogDescUserAgent.Validators[0].(func(string) error)
// usagelogDescImageCount is the schema descriptor for image_count field. // usagelogDescImageCount is the schema descriptor for image_count field.
usagelogDescImageCount := usagelogFields[24].Descriptor() usagelogDescImageCount := usagelogFields[25].Descriptor()
// usagelog.DefaultImageCount holds the default value on creation for the image_count field. // usagelog.DefaultImageCount holds the default value on creation for the image_count field.
usagelog.DefaultImageCount = usagelogDescImageCount.Default.(int) usagelog.DefaultImageCount = usagelogDescImageCount.Default.(int)
// usagelogDescImageSize is the schema descriptor for image_size field. // usagelogDescImageSize is the schema descriptor for image_size field.
usagelogDescImageSize := usagelogFields[25].Descriptor() usagelogDescImageSize := usagelogFields[26].Descriptor()
// usagelog.ImageSizeValidator is a validator for the "image_size" field. It is called by the builders before save. // usagelog.ImageSizeValidator is a validator for the "image_size" field. It is called by the builders before save.
usagelog.ImageSizeValidator = usagelogDescImageSize.Validators[0].(func(string) error) usagelog.ImageSizeValidator = usagelogDescImageSize.Validators[0].(func(string) error)
// usagelogDescCreatedAt is the schema descriptor for created_at field. // usagelogDescCreatedAt is the schema descriptor for created_at field.
usagelogDescCreatedAt := usagelogFields[26].Descriptor() usagelogDescCreatedAt := usagelogFields[27].Descriptor()
// usagelog.DefaultCreatedAt holds the default value on creation for the created_at field. // usagelog.DefaultCreatedAt holds the default value on creation for the created_at field.
usagelog.DefaultCreatedAt = usagelogDescCreatedAt.Default.(func() time.Time) usagelog.DefaultCreatedAt = usagelogDescCreatedAt.Default.(func() time.Time)
userMixin := schema.User{}.Mixin() userMixin := schema.User{}.Mixin()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment