* fix(costcenter): embed Alipay cashier page via iframe
The Alipay payment URL from TradePagePay is a signed gateway URL over
900 characters long, which cannot be scanned as a QR code. Switch to
qr_pay_mode=4 (order code mode) so Alipay renders the official cashier
page, return its auto-submitting form HTML as the payment code, and
embed it in the frontend via an iframe. QR code rendering remains for
legacy data.
* refactor(pay): restore original alipay comments
* refactor(costcenter): load Alipay cashier page via iframe src
* feat(billing): route Stripe returns to declared app
Signed-off-by: aimeritething <aimeritething@gmail.com>
* fix(billing): persist Stripe callback app
Signed-off-by: aimeritething <aimeritething@gmail.com>
* fix(billing): address review feedback for Stripe payApp routing
- Fix golangci-lint issues: use NewRequestWithContext and
http.MethodPost in tests, drop a trailing blank line
- Normalize array-valued app query params in the desktop
Stripe callback resolver and cover it with a test
- Simplify pendingTransactionPromotionCode with strings.SplitN
- Rename the parser test to reflect it only verifies JSON binding
- Refresh the stale callback URL example comment in buildURLs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: aimeritething <aimeritething@gmail.com>
* docs(pay): use placeholder values in callback URL example
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: aimeritething <aimeritething@gmail.com>
---------
Signed-off-by: aimeritething <aimeritething@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix(account): make hourly billing reconciliation resumable and idempotent
- schedule every ready billing hour from a persisted Mongo checkpoint
- retry failed owner reconciliation and preserve checkpoint progress
- use stable billing IDs with Mongo upsert semantics
- recover stable unsettled billings independently from monitor data
- make Cockroach balance and credits deductions idempotent
- reconstruct historical debt and subscription state using transaction UpdatedAt
- scope subscription history queries to active workspaces in the target hour
- add focused unit and Testcontainers runtime coverage
* perf
* fix(account): restore hourly billing deduction semantics
* feat(account): bound billing checkpoint catch-up window
- add BILLING_MAX_CATCHUP_DURATION with a default of 24h
- limit historical billing replay to the configured duration
- preserve first-start behavior to process only the latest ready hour
- log skipped hours when the persisted checkpoint exceeds the replay window
- expose durable checkpoint lag and windowed pending checkpoint metrics
- wire the setting into the account controller Helm chart
- add bounded catch-up, first-start, validation, and metric tests
* fix: ci
* perf(account): optimize indexed historical billing queries
- replace full DebtStatusRecord loading with per-user LATERAL lookup
- use half-open billing time boundaries for historical debt state
- add composite indexes for debt, subscription, and credits queries
- add Testcontainers runtime and execution-plan coverage for billing paths
- verify Mongo billing indexes and repeated initialization behavior
* Add a prompt for detecting the number of users exceeding the active license
Multiple Active licenses only use the latest License for restriction detection
init
# Conflicts:
# controllers/user/api/v1/user_webhook.go
# controllers/user/controllers/user_controller.go
* fix rebase conflict
* fix ci lint
* feat: add workspace subscription card management APIs
- Add CreateWorkspaceSubscriptionCardManagePortal for creating Stripe portal sessions
- Add GetWorkspaceSubscriptionCardInfo for retrieving payment method details
- Add new request structs and route definitions
- Update constants for new API endpoints
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: implement subscription-specific card management portal
- Add CreateSubscriptionPortalSession method in Stripe service
- Modify CreateWorkspaceSubscriptionCardManagePortal to use workspace-specific subscription
- Use flow_data to restrict portal to payment method updates only
- This ensures users only see the current workspace's subscription in the portal
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: implement subscription upgrade billing cycle reset and discount code support
## Key Changes
### 1. New Billing Logic for Upgrades
- Changed from prorated remaining value to current plan remaining value calculation
- Formula: Upgrade Fee = New Plan Full Price - Current Plan Remaining Value
- Ensures fair pricing based on unused portion of current plan
### 2. Billing Cycle Reset for Upgrades
- Upgrade payments now start a new billing cycle from the upgrade date
- Next payment date resets to the same day next month
- Modified finalizeWorkspaceSubscriptionSuccess to handle upgrade cycle reset
### 3. Discount Code Integration
- Added DiscountCode field to WorkspaceSubscriptionOperatorReq
- Created CreateWorkspaceSubscriptionSessionWithDiscount method for payment sessions
- Enhanced UpdatePlanPricePreviewWithDiscount for accurate discount preview
- Discount information stored in transaction.StatusDesc
### 4. API Response Enhancement
- Upgrade amount API returns detailed discount information
- Supports amount preview with and without discount codes
- Frontend can display discount comparison and validation
### 5. Stripe SDK Integration
- Used InvoiceCreatePreviewParams.Discounts for discount preview
- Used CheckoutSessionParams.Discounts for payment discount
- Proper BillingCycleAnchor configuration for upgrade cycles
## Technical Implementation
- Maintains backward compatibility for existing operations
- Discount codes only apply to upgrade operations
- Consistent billing cycle logic across preview and payment
- No database schema changes required
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: enhance subscription upgrade package management with proper expiration
- Add upgrade-aware traffic and AI quota package management
- Implement proper expiration of old packages during upgrades
- Add AddTrafficPackageWithUpgrade and AddWorkspaceSubscriptionAIQuotaPackageWithUpgrade functions
- Fix stripe subscription cancellation and upgrade logic
- Maintain backward compatibility with existing package functions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* add redirect url & create subscription setup intent
* support get create subscription amount with discount code.
* convert the discount code to the promotion code
* support cancel workspace subscription invoice
* support deleteImmediately
---------
Co-authored-by: Claude <noreply@anthropic.com>
* add user alert notification account
* debt supports multiple notification account
* feat: add UserAlertNotificationAccount CRUD interfaces with unified POST endpoints
- Implement user-level alert notification account management
- Add CREATE, LIST, DELETE operations using POST requests
- Remove GET and UPDATE operations as per requirements
- All endpoints use POST method with different route paths
- Delete operation is idempotent (succeeds even if record doesn't exist)
- Include proper authentication, validation, and error handling
- Add comprehensive API documentation with Swagger annotations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: return 409 status for duplicate user alert notification accounts
- Add duplicate key error detection in CreateUserAlertNotificationAccount
- Return HTTP 409 Conflict instead of 500 for duplicate entries
- Add isDuplicatedKeyError helper function to handle various DB error messages
- Import necessary packages (errors, strings, gorm)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(controller): simplify OperationRequestMonitor namespace status sync
- Remove debt status checking logic and Database dependencies
- Focus on synchronizing target namespace based on owner's namespace status only
- Simplify logic: only sync OperationRequest.spec.namespace instead of all owner namespaces
- Resume target namespace when owner is eligible (empty/normal/resume states) and target is suspended
- Remove network status handling, focus only on debt status
- Add proper helper functions for status checking and validation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix ci lint
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat: migrate PaymentRefund table to support multiple refunds per order
- Add OrderID field to PaymentRefund struct for business logic
- Add RowID UUID primary key for CockroachDB compatibility
- Migrate ID primary key to RowID using atomic transaction
- Copy existing ID values to OrderID field
- Remove primary key constraint from ID field
- Convert trade_no from UUID to TEXT type if needed
- Enable multiple partial refunds per payment order
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* ci fix
---------
Co-authored-by: Claude <noreply@anthropic.com>
Add two optional metav1.Time fields to mark notification active period:
- StartTime: marks when notification becomes active
- EndTime: marks when notification expires
This enables time-based notification control and filtering.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
* feat(license): implement license controller with Helm chart and RBAC configuration
* fix(license): correct logic for extending default license for devbox users
* fix(license): update license validation to use context for improved handling
* fix(license): change EncryptionKey to encryptionKey and add getter function
* fix(license): extend default license expiration for devbox users to 50 years
* fix empty old plan status
* add AdminSubscriptionPlanManage api
* fix(account): implement idempotency for AdminSubscriptionPlanManage API
This commit fixes critical issues with the AdminSubscriptionPlanManage API
that caused "duplicated key not allowed" and "violates foreign key constraint"
errors.
Key improvements:
- Enhanced plan lookup logic to support both ID and name-based searches
- Implemented comprehensive change detection for plans and prices
- Added intelligent price update/creation/deletion logic
- Ensured proper transaction handling and data consistency
- Added detailed logging for debugging and monitoring
The API now properly handles:
- Finding existing plans by name when ID is empty
- Skipping updates when no changes are detected (idempotency)
- Updating prices without violating unique constraints
- Preserving data integrity in concurrent scenarios
Fixes #ISSUE-ID
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(account): fix golangci-lint issues and improve code structure
This commit addresses all golangci-lint issues while preserving functionality:
Key improvements:
- Reduced cyclomatic complexity from 66 to <20 by extracting functions
- Replaced if-else chains with switch statements where appropriate
- Eliminated elseif patterns in favor of proper switch statements
- Extracted helper functions for better code organization
- Improved readability and maintainability
Breaking down the large AdminManageSubscriptionPlan function:
- logPlanDetails: handles debug logging
- processPlanUpdate: orchestrates the update process
- findExistingPlan: searches for plans by ID/name
- createNewPlan: creates new subscription plans
- validatePlanNameUpdate: validates name changes
- hasPlanChanged: detects plan modifications
- havePricesChanged: detects price modifications
- updatePlanIfNeeded: updates plans when needed
- updatePricesIfNeeded: updates prices when needed
- deleteObsoletePrices: removes unused prices
- createOrUpdatePrices: handles price creation/updates
- findExistingPrice: searches for existing prices
- updateExistingPriceIfNeeded: updates prices when values change
- hasPriceChanged: detects individual price changes
The refactored code maintains all original functionality while being
more testable, maintainable, and compliant with linting standards.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(account): resolve remaining golangci-lint formatting issues
This commit fixes the remaining formatting issues identified by golangci-lint:
- Fixed golines issue by breaking long function signature into multiple lines
- Fixed gofmt issue by inlining the map declaration
- Fixed gofumpt issue by ensuring proper line spacing
All code quality issues are now resolved while maintaining full functionality.
The code successfully compiles and all original features are preserved.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(account): improve code formatting and resolve cross-file reference issues
- Fix code formatting issues in admin.go with proper line breaks and indentation
- Improve code readability with consistent formatting across functions
- Fix MongoDB pipeline copy issue in dao/interface.go
- Update router logging condition formatting
- Add comments for cross-file function references to help with static analysis
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(account): comprehensive admin subscription API improvements
Fixes multiple critical issues in admin workspace subscription management:
**Key Fixes:**
1. **Price check bypass**: Remove strict price validation for admin operations, allowing arbitrary periods (e.g., 3m) without predefined pricing
2. **Payment method correction**: Change from PaymentMethodErrAndUseBalance to PaymentMethodBalance for admin operations
3. **Period parsing enhancement**: Use ParsePeriod() to correctly handle custom periods (3m = 90 days, not 1 month)
4. **Smart operator detection**: Intelligently detect operation type based on plan comparison:
- Same plan → renewed (renewal)
- Different plan → upgraded (upgrade)
- No existing plan → created (new subscription)
5. **Traffic package optimization**: Skip traffic/AI package addition for renewals when current period hasn't expired
6. **Upgraded operation period support**: Extend proper period calculation to upgraded operations
Resolves issues where 3m period additions failed with "no price found" errors and ensures proper transaction classification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix ci lint
* fix json return
* add edit user role
* fix init balance
* delete useless account field
---------
Co-authored-by: Claude <noreply@anthropic.com>
* initialize the data structure
* Initialize the lifecycle management of workspace subscriptions
* fix index
* add workspace subscription debt
* optimize parse period & init workspace subscription & fix subscription create bug
* remove quota controller
* add user notify framework:
content_generator:content generation
service:event notification service
providers:vms/sms/email ... provider implementation
types: core structure type definition
* optimize struct & adjust the database to obtain data
* Implement the initialization of subscriptions and the implementation of subscription traffic packages
* service implement the database layer
* auto add column payment.stripe
* add stripe pay interface
* add workspace subscription service
* add the usercr tag for subscription based spaces, Add delete workspace subscription operator & Add api interfaces related to obtaining workspace costs
* optimize interface
* overall adjustment and repair
* optimize traffic early warning notifications
* optimize traffic early warning notifications
* optimize
* optimize & add deletion account api
* optimize log
* add get payment status api && support workspace subscription AI quota package
* optimize
* Fixed the issue where traffic was not distributed after renewing the subscription package
* fix
* fix workspace subscription transaction process add ai quota package
* fix ci lint
* fix controller/account ci lint
* fix controller/pkg ci lint
* fix controller/account ci lint
* fix controller/pkg ci lint
* add admin add workspace subscription
* fix upgrade workspace subscription
* add get workspace subscription plans api
* add get workspace subscription plans api
* fix ci lint
* fix ci lint
* fix ci lint
* support the suspension and resumption of export network services
* support recording user traffic to the database: `UserTimeRangeTraffic` Table.
* network suspend/resume annotation value to upper
* add suspend/resume user traffic api
* optimize monitor user traffic process
* realize the automatic refresh of traffic usage
* add test
* optimize sendFlushQuotaRequest log & fix create or update quota
* optimize: user remove the watching AnnotationChangedPredicate
* optimize initialize the account data
* fix debt time range process: if error occurs, the start time of the next execution is the start time of the last one
* optimize
* suspend create transaction
* add github detection initialization account
* fix ci
* upgrade: controller runtime version
* Upgrade k8s.io/client-go version v0.28.3 => v0.32.1; Upgrade golang version v1.22 => 1.24 to be compatible with client-go v0.32.1
* fix ci
* fix ci
* skip md5 semgrep check
---------
Co-authored-by: jiahui <bxy4543@gmail.com>
* billing reconciler changed from controller trigger to scheduled task execution.
* with manager runner
* with manager runner
* change cmv billing with manager runner
* optimize log
* fix reconcile
* add billing with wait group goroutine
* add logger
* get the user cr using the cacheless client
* optimize
* Removes mongo Aggregate processing data that is too slow and uses in-memory batch user metering data.
* fix
* remove the owner that does not need to be updated
* optimize log && fix the genGroupKey GenerateBillingDataFromRecords rules
* make format