Refactor the `Whoami` handler to validate token metadata (status, expiration,
revocation) against Redis before database lookup, ensuring consistency with
balancer logic. Add `allow_ips`, `deny_ips`, and `expires_at` fields to
authentication responses.
Update internal middleware to support explicit anonymous access configuration
and harden security for unconfigured tokens.
Remove legacy fallback logic for master keys without digests.
BREAKING CHANGE: Internal endpoints now reject requests by default if no stats token is configured. To allow unauthenticated access, set `internal.allow_anonymous` to true.
BREAKING CHANGE: Support for legacy master keys without stored digests has been removed.
Replace internal goroutine-based timing loops with scheduler integration
for SyncOutboxService and ModelRegistryService. Both services now expose
RunOnce() methods called by the central scheduler instead of managing
their own background loops.
- Add Interval() and RunOnce() methods to SyncOutboxService
- Add RefreshEvery() and RunOnce() methods to ModelRegistryService
- Remove started flag from SyncOutboxService struct
- Move scheduler.Start() after all services are initialized
- Ensure initial model registry refresh before scheduler starts
Add new admin API endpoints for dashboard metrics and system-wide
realtime statistics:
- Add /admin/dashboard/summary endpoint with aggregated metrics
including requests, tokens, latency, masters, keys, and provider
keys statistics with time period filtering
- Add /admin/realtime endpoint for system-level realtime stats
aggregated across all masters
- Add status filter parameter to ListAPIKeys endpoint
- Add hour grouping option to log stats aggregation
- Update OpenAPI documentation with new endpoints and schemas
Add support for OAuth-based authentication with access/refresh tokens
and expiration tracking for API keys. Extend provider groups with
static headers configuration and headers profile options.
Changes include:
- Add AccessToken, RefreshToken, ExpiresAt, AccountID, ProjectID to APIKey model
- Add StaticHeaders and HeadersProfile to ProviderGroup model
- Add TokenRefresh configuration for background token management
- Support new provider types: ClaudeCode, Codex, GeminiCLI, Antigravity
- Update sync service to include new fields in provider snapshots
Use UnixNano for version field while keeping Unix seconds for updated_at
timestamp. This ensures version changes are detected even when multiple
syncs occur within the same second.
- Introduce `SyncOutboxService` and model to retry failed CP-to-Redis sync operations
- Update `SyncService` to handle sync failures by enqueuing tasks to the outbox
- Centralize provider group and API key validation logic into `ProviderGroupManager`
- Refactor API handlers to utilize the new manager and robust sync methods
- Add configuration options for sync outbox (interval, batch size, retries)
- Update TestBatchBindings_Status to use newTestHandlerWithRedis helper
- Remove unused jsonID helper function from sync_bindings_spec_test.go
- Add time import to models.go
Restructure the provider management system by separating the monolithic
Provider model into two distinct entities:
- ProviderGroup: defines shared upstream configuration (type, base_url,
google settings, models, status)
- APIKey: represents individual credentials within a group (api_key,
weight, status, auto_ban, ban settings)
This change also updates:
- Binding model to reference GroupID instead of RouteGroup string
- All CRUD handlers for the new provider-group and api-key endpoints
- Sync service to rebuild provider snapshots from joined tables
- Model registry to aggregate capabilities across group/key pairs
- Access handler to validate namespace existence and subset constraints
- Migration importer to handle the new schema structure
- All related tests to use the new model relationships
BREAKING CHANGE: Provider API endpoints replaced with /provider-groups
and /api-keys endpoints; Binding.RouteGroup replaced with Binding.GroupID
Introduce StatsService integration to admin and master handlers,
exposing realtime metrics (requests, tokens, QPS, rate limit status)
via new endpoints:
- GET /admin/masters/:id/realtime
- GET /v1/realtime
Also embed realtime stats in the existing GET /admin/masters/:id
response and change GlobalQPS default to 0 with validation to
reject negative values.
Implement webhook notifications for log error threshold alerts with
configurable thresholds, time windows, and cooldown periods.
- Add LogWebhookService with Redis-backed configuration storage
- Add admin endpoints for webhook config management (GET/PUT)
- Trigger webhook notifications when error count exceeds threshold
- Support status code threshold and error message detection
- Include sample log record data in webhook payload
- Add `POST /admin/providers/preset` for streamlined creation of official providers (OpenAI, Anthropic, Gemini)
- Add `POST /admin/providers/custom` for generic OpenAI-compatible providers
- Add `weight` field to provider model and DTOs to enable weighted routing
- Update sync service to propagate provider weights
- Add unit tests for new creation handlers
Add unit tests for the SyncBindings service covering exact matching,
regex selectors, and normalized matching logic using in-memory
dependencies (SQLite and MiniRedis) to ensure correct upstream
resolution.
Add endpoints for master and key access management to configure default
and allowed namespaces, including propagation options.
Implement GET and DELETE operations for individual bindings.
Update sync service to persist bindings snapshots even when no upstreams
are available.
Standardize alignment of struct tags in models and field assignments in
services for better readability. Additionally, include the Binding model
in the test database auto-migration.
Implement handlers for creating, listing, and updating model bindings.
Register new routes in the admin server group and add DTO definitions.
Update provider handlers to trigger binding synchronization on changes
to ensure upstream mappings remain current.
Introduce namespace-aware routing capabilities through a new Binding
model and updates to Master/Key entities.
- Add Binding model for configuring model routes per namespace
- Add DefaultNamespace and Namespaces fields to Master and Key models
- Update auto-migration to include Binding table
- Implement Redis synchronization for binding configurations
- Propagate namespace settings during master creation and key issuance
Add `POST /admin/masters/{id}/keys` allowing admins to issue child keys
on behalf of a master. Introduce an `issued_by` field in the Key model
to audit whether a key was issued by the master or an admin.
Refactor master service to use typed errors for consistent HTTP status
mapping and ensure validation logic (active status, group check) is
shared.
- Update TESTING.md to reflect current testing status and future plans
- Add golden file comparison for provider snapshot validation in sync_test.go
- Introduce master_test.go for testing Master/Key functionality
- Add testdata directory for contract testing snapshots
Introduce a middleware layer to attach a unique identifier to each HTTP request for observability purposes. The identifier is propagated via the X-Request-ID header, allowing for correlation of logs and events across distributed system components.
Add support for Google Cloud-specific configuration in provider models.
New fields `GoogleProject` and `GoogleLocation` are now included in the
Provider DTO, database model, API handlers, and sync service snapshots.
- Extend Provider struct in model with gorm/json tags
- Update ProviderDTO with omitempty JSON tags
- Include fields in handler create/update logic with trim
- Add fields to providerSnapshot for sync operations
- Replace direct zerolog usage with standard library `log/slog` in business code
- Add `internal/logging` package with zerolog bridge handler for structured output
- Create `internal/jsoncodec` package to centralize JSON encoding/decoding using Sonic
- Update all services and main entry point to use new logging interface
- Maintain backward compatibility with existing zerolog console output
- Remove custom logger setup in favor of structured logging bridge
Add `PUT /admin/providers/{id}` endpoint to allow updating provider
configurations, including status and ban details. Update synchronization
logic to exclude inactive or banned providers from routing tables to
ensure traffic is not routed to them.
Introduce fields for managing provider status (active, auto_disabled,
manual_disabled) and banning logic.
- Add Status, AutoBan, BanReason, and BanUntil to Provider model and DTO
- Update CreateProvider handler to process new fields with defaults
- Extend sync service to propagate status and ban information in snapshots
- Serialize BanUntil as Unix timestamp for sync compatibility
- Integrate `rs/zerolog` for structured and leveled logging
- Add `EZ_LOG_LEVEL` environment variable support (default: info)
- Configure console output with timestamps and service fields
- Migrate `main.go` and `LogWriter` to use the new logger instance
- Update README with logging configuration and design details
Migrate all JSON marshaling and unmarshaling operations to use
github.com/bytedance/sonic for improved performance. This affects
adapters, middleware, proxy handlers, and the sync store.
- Add token hash fields to Master and Key models for indexed lookups
- Implement SyncService integration in admin and master handlers
- Update master key validation with backward-compatible digest lookup
- Hash child keys in database and store token digests for Redis sync
- Add master metadata sync to Redis for balancer validation
- Ensure backward compatibility with legacy rows during migration
Add admin and master authentication layers with JWT support. Replace direct
key creation with hierarchical master/child key system. Update database
schema to support master accounts with configurable limits and epoch-based
key revocation. Add health check endpoint with system status monitoring.
BREAKING CHANGE: Removed direct POST /keys endpoint in favor of master-based
key issuance through /v1/tokens. Database migration requires dropping old User
table and creating Master table with new relationships.
Replace direct provider linkage with group-based routing for Keys and
Providers. This allows for more flexible load balancing and tiering
strategies.
Changes include:
- Remove `ProviderID` from Key model and DTO
- Add `Group` field to Key and Provider models
- Refactor Redis sync to use Hashes for O(1) partial updates
- Update API handlers to perform incremental syncs
BREAKING CHANGE: Key API payload no longer accepts `provider_id`. Redis
configuration storage format has changed from JSON strings to Hashes.
Enable full resource management via API and support data plane
synchronization.
- Add CRUD handlers for Providers, Models, and Keys using DTOs
- Implement LogWriter service for asynchronous, batched audit logging
- Update SyncService to snapshot full configuration state to Redis
- Register new API routes and initialize background services
- Add configuration options for logging performance tuning
Establish the foundational structure for the ez-api server.
Key changes include:
- Set up main entry point with graceful shutdown and Gin router
- Configure database connections for PostgreSQL (GORM) and Redis
- Define core data models (User, Provider, Key, Model)
- Implement configuration loading and basic key creation handler
- Add Dockerfile for multi-stage builds and .gitignore