Files
plane/apps/monitor/cli/pkg/db/models.go
T
e939dc3ef7 [PRIME-21]: Enterprise Plan for self hosted and airgapped (#4141)
* feat: add enterprise license activation and deactivation endpoints

- Implemented `EnterpriseLicenseActivateEndpoint` and `EnterpriseLicenseDeactivateEndpoint` for managing enterprise licenses.
- Updated URL routing to include new endpoints for activating and deactivating enterprise licenses.
- Added necessary request handling and response structures for enterprise license operations.
- Enhanced existing license management logic to accommodate enterprise-specific requirements.

* feat: add enterprise plan invite and update handling

- Implemented `handle_enterprise_plan_invite_case` to manage invites under the enterprise plan.
- Added `handle_enterprise_plan_update_case` for role updates within the enterprise plan.
- Updated `handle_cloud_payments` to incorporate new enterprise plan handling logic for invites and role updates.

* feat: add enterprise license management endpoints

- Introduced new endpoints for managing enterprise licenses, including `InstanceLicenseSyncEndpoint`, `EnterpriseModifySeatsEndpoint`, `EnterpriseSubscriptionPortalEndpoint`, and `EnterpriseSubscriptionProrationPreviewEndpoint`.
- Updated URL routing to accommodate the new endpoints for enterprise license operations.
- Enhanced the views and API interactions to support enterprise license modifications and subscription management.

* feat: enhance enterprise license activation and management

- Updated `EnterpriseLicenseActivateEndpoint` to allow any user to access the activation endpoint.
- Introduced new airgapped activation handler for enterprise licenses, enabling file uploads and processing of activation files.
- Added routes for enterprise license activation in airgapped mode, including file handling and database population.
- Enhanced error handling and response structures for better user feedback during activation processes.

* feat: implement instance license management features

- Added new components and hooks for managing instance licenses, including activation via license key and file uploads.
- Introduced `InstanceManagementStore` to handle license operations and state management.
- Created UI components for license management, including forms for entering license keys and uploading license files.
- Enhanced API interactions for license activation and deactivation, with improved error handling and user feedback.
- Updated routing and layout for the instance management page to accommodate new features.

* refactor: replace regular imports with type imports for improved clarity across multiple components

* fix: admin build

* refactor: update enterprise license API paths and enhance error handling

- Changed API paths for enterprise license endpoints to include "instances" in the URL structure.
- Improved error handling in the EnterpriseLicenseActivateEndpoint and EnterpriseLicenseDeactivateEndpoint to return more specific error messages based on response status codes.
- Added logging configuration for "plane.payments" in both local and production settings.

* feat: add InstanceLicenseEndpoint for retrieving current enterprise license plan

- Introduced InstanceLicenseEndpoint to fetch the current enterprise license plan from the payment server.
- Updated URL routing to include the new endpoint for instance licenses.
- Enhanced error handling for the new endpoint to manage various response scenarios.

* feat: add billing and user management pages, update sidebar menu

- Introduced new routes for billing and user management in the admin dashboard.
- Updated the sidebar menu to include links for the new billing and user management pages.
- Refactored existing components to utilize a new PageWrapper for consistent layout across pages.
- Enhanced the AI, authentication, and image pages with the new PageWrapper for improved UI consistency.

* fix: adjust icon sizes

* feat: enterprise license activation UI

* fix: remove unnecessary shrink-0 class from header actions div in PageWrapper

* fix: update error handling in enterprise license endpoints

- Removed unnecessary newline in the Python API view for instance licenses.
- Changed the response in the Go handler to return a success status with a message when no enterprise license exists, instead of an internal server error.

* feat: enhance enterprise license management and update dependencies

* refactor: simplify EnterprisePlanCard and enhance button handling

- Removed unnecessary props and state management from EnterprisePlanCard.
- Updated PlanCard to conditionally render the button.
- Enhanced BillingActionsButton to provide tooltips for Enterprise plan users.
- Adjusted limit-reached-info to reflect Enterprise plan status in seat management.

* style: update modal styling for enterprise license success component

* refactor: streamline enterprise license deactivation process

- Removed the requirement for a license key in the Python API view.
- Simplified the Go handler by eliminating unnecessary payload parsing and improved the response structure for cases with no existing enterprise license.

* refactor: remove InstanceLicenseActions component and clean up related code

- Deleted the InstanceLicenseActions component to streamline the enterprise license management.
- Updated EnterprisePlanCard to conditionally render components based on the subscription status.
- Removed unused props and functions related to trial period checks from the instance management store and types.

* refactor: simplify GetEnterpriseLicenseCurrentPlan response structure

- Removed unnecessary fields from the response for both existing and new enterprise licenses.
- Streamlined the JSON output to focus on essential information, enhancing clarity and reducing payload size.

* feat: implement seat management functionality for enterprise licenses

- Added InstanceLicenseActions component to handle license synchronization and deactivation.
- Introduced SeatsManagementButton for managing seat additions and removals.
- Created modals and forms for adding and removing seats, including proration previews.
- Updated EnterprisePlanCard to integrate new seat management features.
- Enhanced instance management store with methods for updating subscription details and managing seats.

* feat: enhance enterprise plan user guidance and UI updates

* refactor: update instance management service usage and rename seat form components

* fix: closure issues in enterprise plan card and instance management store

* feat: add endpoint to remove unused seats from enterprise licenses

- Introduced EnterpriseLicenseRemoveUnusedSeatsEndpoint to handle the removal of unused seats.
- Updated URL routing to include the new endpoint.
- Refactored user count retrieval logic to streamline seat management processes.

* fix: remove duplicate workspaceSlug prop from RemoveUnusedSeatsModal in GlobalModals component

* chore: change the enterprise member count

* feat: enhance seat management UI and logic for subscription levels

- Updated the SelectSeatsStep component to display different messages based on subscription level (workspace vs instance).
- Modified the ConfirmPriceStep to reflect the subscription level in the confirmation message.
- Added subscription level handling in the AddSeatsForm component.
- Improved the invitation description to differentiate between Enterprise and non-Enterprise plans.
- Introduced a new field for allowed total users in the TMemberInviteCheck type for Enterprise plans.
- Refactored styles for better UI consistency in the NumberInputWithControls component.

* feat: implement enterprise plan invite check for workspace

- Added a method to check the allowed total users for inviting new members based on the enterprise plan.
- Integrated the invite check into the existing endpoint response, providing clarity on user limits for enterprise workspaces.
- Enhanced the logic to count current active and invited users, ensuring accurate seat management for enterprise licenses.

* refactor: remove unused import in workspace invite check endpoint

- Eliminated the unused import of handle_enterprise_plan_invite_case from the invite.py file, streamlining the code and improving maintainability.

* fix: update enterprise plan user limit check in invitation description

* fix: format

---------

Co-authored-by: Prateek Shourya <[email protected]>
Co-authored-by: b-saikrishnakanth <[email protected]>
2025-12-24 13:19:03 +05:30

87 lines
3.8 KiB
Go

package db
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
type License struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
LicenseKey string `json:"license_key" gorm:"not null;uniqueIndex:idx_workspace_license"`
InstanceID uuid.UUID `json:"instance_id" gorm:"type:uuid"`
WorkspaceID uuid.UUID `json:"workspace_id" gorm:"type:uuid;unique;uniqueIndex:idx_workspace_license"`
WorkspaceSlug string `json:"workspace_slug" gorm:"unique"`
Product string `json:"product" gorm:"not null"`
ProductType string `json:"product_type" gorm:"not null"`
Seats int `json:"seats" gorm:"not null;default:0"`
FreeSeats int `json:"free_seats" gorm:"not null;default:12"`
CurrentPeriodEndDate *time.Time `json:"current_period_end_date"`
IsCancelled bool `json:"is_cancelled" gorm:"not null;default:false"`
Interval string `json:"interval"`
IsOfflinePayment bool `json:"is_offline_payment" gorm:"not null;default:false"`
TrialEndDate *time.Time `json:"trial_end_date"`
HasAddedPaymentMethod bool `json:"has_added_payment_method" gorm:"not null;default:false"`
HasActivatedFreeTrial bool `json:"has_activated_free_trial" gorm:"not null;default:false"`
Subscription string `json:"subscription" gorm:"not null"`
IsAirgapped bool `json:"is_airgapped" gorm:"not null;default:false"`
LastVerifiedAt *time.Time `json:"last_verified_at"`
LastPaymentFailedDate *time.Time `json:"last_payment_failed_date"`
LastPaymentFailedCount int `json:"last_payment_failed_count" gorm:"not null;default:0"`
// time stamps
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
}
func (license *License) BeforeCreate(scope *gorm.DB) error {
// If the license id is not set, generate a new uuid
if license.ID == uuid.Nil {
license.ID = uuid.New()
}
return nil
}
type UserLicense struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
LicenseID uuid.UUID `json:"license_id" gorm:"type:uuid;not null"`
License License `json:"license" gorm:"foreignKey:LicenseID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
UserID uuid.UUID `json:"user_id" gorm:"type:uuid;not null"`
Role int `json:"role" gorm:"not null"`
Synced bool `json:"synced" gorm:"not null;default:false"`
IsActive bool `json:"is_active" gorm:"not null;default:false"`
// time stamps
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
}
func (userLicense *UserLicense) BeforeCreate(scope *gorm.DB) error {
// If the user license id is not set, generate a new uuid
if userLicense.ID == uuid.Nil {
userLicense.ID = uuid.New()
}
return nil
}
type Flags struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
LicenseID uuid.UUID `json:"license_id" gorm:"type:uuid;not null"`
License License `json:"license" gorm:"foreignKey:LicenseID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Version string `json:"version" gorm:"not null"`
AesKey string `json:"aes_key" gorm:"not null"`
Nonce string `json:"nonce" gorm:"not null"`
CipherText string `json:"cipher_text" gorm:"not null"`
Tag string `json:"tag" gorm:"not null"`
// time stamps
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
}
func (flags *Flags) BeforeCreate(scope *gorm.DB) error {
// If the flags id is not set, generate a new uuid
if flags.ID == uuid.Nil {
flags.ID = uuid.New()
}
return nil
}