diff --git a/api/api.gen.go b/api/api.gen.go index 1113b2331..9ce5105d4 100644 --- a/api/api.gen.go +++ b/api/api.gen.go @@ -164,8 +164,13 @@ type EntitlementBoolean struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -189,7 +194,12 @@ type EntitlementBooleanType string // EntitlementBooleanCreateInputs defines model for EntitlementBooleanCreateInputs. type EntitlementBooleanCreateInputs struct { // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // Metadata Additional metadata for the feature. Metadata *map[string]string `json:"metadata,omitempty"` @@ -210,7 +220,12 @@ type EntitlementCreateInputs struct { // EntitlementCreateSharedFields defines model for EntitlementCreateSharedFields. type EntitlementCreateSharedFields struct { // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // Metadata Additional metadata for the feature. Metadata *map[string]string `json:"metadata,omitempty"` @@ -323,8 +338,13 @@ type EntitlementMetered struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -369,7 +389,12 @@ type EntitlementMeteredCalculatedFields struct { // EntitlementMeteredCreateInputs defines model for EntitlementMeteredCreateInputs. type EntitlementMeteredCreateInputs struct { // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // IsSoftLimit If softLimit=true the subject can use the feature even if the entitlement is exhausted. IsSoftLimit *bool `json:"isSoftLimit,omitempty"` @@ -403,8 +428,13 @@ type EntitlementSharedFields struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -436,8 +466,13 @@ type EntitlementStatic struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -464,7 +499,12 @@ type EntitlementStaticCreateInputs struct { Config string `json:"config"` // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // Metadata Additional metadata for the feature. Metadata *map[string]string `json:"metadata,omitempty"` @@ -3146,174 +3186,175 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/client/go/client.gen.go b/api/client/go/client.gen.go index 823c587cf..decd5dcb5 100644 --- a/api/client/go/client.gen.go +++ b/api/client/go/client.gen.go @@ -164,8 +164,13 @@ type EntitlementBoolean struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -189,7 +194,12 @@ type EntitlementBooleanType string // EntitlementBooleanCreateInputs defines model for EntitlementBooleanCreateInputs. type EntitlementBooleanCreateInputs struct { // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // Metadata Additional metadata for the feature. Metadata *map[string]string `json:"metadata,omitempty"` @@ -210,7 +220,12 @@ type EntitlementCreateInputs struct { // EntitlementCreateSharedFields defines model for EntitlementCreateSharedFields. type EntitlementCreateSharedFields struct { // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // Metadata Additional metadata for the feature. Metadata *map[string]string `json:"metadata,omitempty"` @@ -323,8 +338,13 @@ type EntitlementMetered struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -369,7 +389,12 @@ type EntitlementMeteredCalculatedFields struct { // EntitlementMeteredCreateInputs defines model for EntitlementMeteredCreateInputs. type EntitlementMeteredCreateInputs struct { // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // IsSoftLimit If softLimit=true the subject can use the feature even if the entitlement is exhausted. IsSoftLimit *bool `json:"isSoftLimit,omitempty"` @@ -403,8 +428,13 @@ type EntitlementSharedFields struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -436,8 +466,13 @@ type EntitlementStatic struct { DeletedAt *time.Time `json:"deletedAt,omitempty"` // FeatureId The feature the subject is entitled to use. + // Either featureKey or featureId is required. FeatureId string `json:"featureId"` + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey string `json:"featureKey"` + // Id Readonly unique ULID identifier. Id *string `json:"id,omitempty"` @@ -464,7 +499,12 @@ type EntitlementStaticCreateInputs struct { Config string `json:"config"` // FeatureId The feature the subject is entitled to use. - FeatureId string `json:"featureId"` + // Either featureKey or featureId is required. + FeatureId *string `json:"featureId,omitempty"` + + // FeatureKey The feature the subject is entitled to use. + // Either featureKey or featureId is required. + FeatureKey *string `json:"featureKey,omitempty"` // Metadata Additional metadata for the feature. Metadata *map[string]string `json:"metadata,omitempty"` @@ -6746,174 +6786,175 @@ func ParseResetEntitlementUsageResponse(rsp *http.Response) (*ResetEntitlementUs // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/client/node/schemas/openapi.ts b/api/client/node/schemas/openapi.ts index 1df0b9ae0..872a200d5 100644 --- a/api/client/node/schemas/openapi.ts +++ b/api/client/node/schemas/openapi.ts @@ -504,10 +504,18 @@ export interface components { EntitlementCreateSharedFields: { /** * @description The feature the subject is entitled to use. + * Either featureKey or featureId is required. + * + * @example example-feature-key + */ + featureKey?: string + /** + * @description The feature the subject is entitled to use. + * Either featureKey or featureId is required. * * @example 01ARZ3NDEKTSV4RRFFQ69G5FAV */ - featureId: string + featureId?: string /** @description Additional metadata for the feature. */ metadata?: { [key: string]: string @@ -777,18 +785,26 @@ export interface components { expiration: components['schemas']['ExpirationPeriod'] /** * Format: double - * @description The maximum amount of the grant that can be rolled over. Defaults to 0. - * - * - maxAmount = {original_amount} -> rollover original amount - * - maxAmount = 0 -> no rollover - * - maxAmount = 90 -> rollover 90 max + * @description Grants are rolled over at reset, after which they can have a different balance compared to what they had before the reset. * - * If it's larger than 0 then the grant's balance will be the MAX(maxRollover, balance) + amount. + * Balance after the reset is calculated as: + * Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, MinRolloverAmount)) * * @default 0 * @example 100 */ maxRolloverAmount?: number + /** + * Format: double + * @description Grants are rolled over at reset, after which they can have a different balance compared to what they had before the reset. + * + * Balance after the reset is calculated as: + * Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, MinRolloverAmount)) + * + * @default 0 + * @example 100 + */ + minRolloverAmount?: number /** * @example { * "stripePaymentId": "pi_4OrAkhLvyihio9p51h9iiFnB" diff --git a/api/client/python/src/openmeter/_operations/_operations.py b/api/client/python/src/openmeter/_operations/_operations.py index 845903412..e1eed665d 100644 --- a/api/client/python/src/openmeter/_operations/_operations.py +++ b/api/client/python/src/openmeter/_operations/_operations.py @@ -3178,14 +3178,19 @@ def list_grants( was last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum - amount of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover - * maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's - balance will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the @@ -3766,14 +3771,19 @@ def list_entitlement_grants( was last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum - amount of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover - * maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's - balance will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the @@ -3885,14 +3895,19 @@ def create_grant( "duration": "str" # The expiration period duration like month. Required. Known values are: "HOUR", "DAY", "WEEK", "MONTH", and "YEAR". }, - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "priority": 1, # Optional. Default value is 1. The priority of the grant. Grants with higher priority are applied first. Priority is a positive decimal numbers. With lower numbers indicating higher importance. For example, a priority @@ -3934,14 +3949,19 @@ def create_grant( last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the grant. @@ -4018,14 +4038,19 @@ def create_grant( last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the grant. @@ -4082,14 +4107,19 @@ def create_grant( "duration": "str" # The expiration period duration like month. Required. Known values are: "HOUR", "DAY", "WEEK", "MONTH", and "YEAR". }, - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "priority": 1, # Optional. Default value is 1. The priority of the grant. Grants with higher priority are applied first. Priority is a positive decimal numbers. With lower numbers indicating higher importance. For example, a priority @@ -4131,14 +4161,19 @@ def create_grant( last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the grant. diff --git a/api/client/python/src/openmeter/aio/_operations/_operations.py b/api/client/python/src/openmeter/aio/_operations/_operations.py index 0a3970635..577f73935 100644 --- a/api/client/python/src/openmeter/aio/_operations/_operations.py +++ b/api/client/python/src/openmeter/aio/_operations/_operations.py @@ -2476,14 +2476,19 @@ async def list_grants( was last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum - amount of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover - * maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's - balance will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the @@ -3064,14 +3069,19 @@ async def list_entitlement_grants( was last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum - amount of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover - * maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's - balance will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are + rolled over at reset, after which they can have a different balance compared + to what they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the @@ -3183,14 +3193,19 @@ async def create_grant( "duration": "str" # The expiration period duration like month. Required. Known values are: "HOUR", "DAY", "WEEK", "MONTH", and "YEAR". }, - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "priority": 1, # Optional. Default value is 1. The priority of the grant. Grants with higher priority are applied first. Priority is a positive decimal numbers. With lower numbers indicating higher importance. For example, a priority @@ -3232,14 +3247,19 @@ async def create_grant( last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the grant. @@ -3316,14 +3336,19 @@ async def create_grant( last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the grant. @@ -3380,14 +3405,19 @@ async def create_grant( "duration": "str" # The expiration period duration like month. Required. Known values are: "HOUR", "DAY", "WEEK", "MONTH", and "YEAR". }, - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "priority": 1, # Optional. Default value is 1. The priority of the grant. Grants with higher priority are applied first. Priority is a positive decimal numbers. With lower numbers indicating higher importance. For example, a priority @@ -3429,14 +3459,19 @@ async def create_grant( last updated. Required. "expiresAt": "2020-02-20 00:00:00", # Optional. The expiration date of the grant. - "maxRolloverAmount": 0, # Optional. Default value is 0. The maximum amount - of the grant that can be rolled over. Defaults to 0. * maxAmount = - {original_amount} -> rollover original amount * maxAmount = 0 -> no rollover * - maxAmount = 90 -> rollover 90 max If it's larger than 0 then the grant's balance - will be the MAX(maxRollover, balance) + amount. + "maxRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "metadata": { "str": "str" # Optional. Dictionary of :code:``. }, + "minRolloverAmount": 0, # Optional. Default value is 0. Grants are rolled + over at reset, after which they can have a different balance compared to what + they had before the reset. Balance after the reset is calculated as: + Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, + MinRolloverAmount)). "nextRecurrence": "2020-02-20 00:00:00", # Optional. The next time the grant will recurr. "priority": 1, # Optional. Default value is 1. The priority of the grant. diff --git a/api/client/web/src/client/openapi.ts b/api/client/web/src/client/openapi.ts index 1df0b9ae0..872a200d5 100644 --- a/api/client/web/src/client/openapi.ts +++ b/api/client/web/src/client/openapi.ts @@ -504,10 +504,18 @@ export interface components { EntitlementCreateSharedFields: { /** * @description The feature the subject is entitled to use. + * Either featureKey or featureId is required. + * + * @example example-feature-key + */ + featureKey?: string + /** + * @description The feature the subject is entitled to use. + * Either featureKey or featureId is required. * * @example 01ARZ3NDEKTSV4RRFFQ69G5FAV */ - featureId: string + featureId?: string /** @description Additional metadata for the feature. */ metadata?: { [key: string]: string @@ -777,18 +785,26 @@ export interface components { expiration: components['schemas']['ExpirationPeriod'] /** * Format: double - * @description The maximum amount of the grant that can be rolled over. Defaults to 0. - * - * - maxAmount = {original_amount} -> rollover original amount - * - maxAmount = 0 -> no rollover - * - maxAmount = 90 -> rollover 90 max + * @description Grants are rolled over at reset, after which they can have a different balance compared to what they had before the reset. * - * If it's larger than 0 then the grant's balance will be the MAX(maxRollover, balance) + amount. + * Balance after the reset is calculated as: + * Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, MinRolloverAmount)) * * @default 0 * @example 100 */ maxRolloverAmount?: number + /** + * Format: double + * @description Grants are rolled over at reset, after which they can have a different balance compared to what they had before the reset. + * + * Balance after the reset is calculated as: + * Balance_After_Reset = MIN(MaxRolloverAmount, MAX(Balance_Before_Reset, MinRolloverAmount)) + * + * @default 0 + * @example 100 + */ + minRolloverAmount?: number /** * @example { * "stripePaymentId": "pi_4OrAkhLvyihio9p51h9iiFnB" diff --git a/api/openapi.yaml b/api/openapi.yaml index c78cb3b0b..4aaea9b8f 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1455,12 +1455,17 @@ components: # Entitlement has 3 subtypes EntitlementCreateSharedFields: type: object - required: - - featureId properties: + featureKey: + description: | + The feature the subject is entitled to use. + Either featureKey or featureId is required. + type: string + example: example-feature-key featureId: description: | The feature the subject is entitled to use. + Either featureKey or featureId is required. type: string example: 01ARZ3NDEKTSV4RRFFQ69G5FAV metadata: @@ -1478,7 +1483,21 @@ components: - type: object required: - subjectKey + - featureKey + - featureId properties: + featureKey: + description: | + The feature the subject is entitled to use. + Either featureKey or featureId is required. + type: string + example: example-feature-key + featureId: + description: | + The feature the subject is entitled to use. + Either featureKey or featureId is required. + type: string + example: 01ARZ3NDEKTSV4RRFFQ69G5FAV subjectKey: description: The identifier key unique to the subject type: string diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index 8bf92fb39..44dc29267 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -512,7 +512,7 @@ func TestCredit(t *testing.T) { t.Run("Create a Entitlement", func(t *testing.T) { meteredEntitlement := api.EntitlementMeteredCreateInputs{ Type: "metered", - FeatureId: *featureId, + FeatureId: featureId, UsagePeriod: api.RecurringPeriodCreateInput{ Anchor: convert.ToPointer(time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC)), Interval: "MONTH", @@ -537,7 +537,7 @@ func TestCredit(t *testing.T) { t.Run("Create for same subject and feature", func(t *testing.T) { meteredEntitlement := api.EntitlementMeteredCreateInputs{ Type: "metered", - FeatureId: *featureId, + FeatureId: featureId, UsagePeriod: api.RecurringPeriodCreateInput{ Anchor: convert.ToPointer(time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC)), Interval: "MONTH", diff --git a/internal/entitlement/connector.go b/internal/entitlement/connector.go index 7af992143..e1dc1991d 100644 --- a/internal/entitlement/connector.go +++ b/internal/entitlement/connector.go @@ -30,7 +30,7 @@ type Connector interface { GetEntitlement(ctx context.Context, namespace string, id string) (*Entitlement, error) DeleteEntitlement(ctx context.Context, namespace string, id string) error - GetEntitlementValue(ctx context.Context, namespace string, subjectKey string, id string, at time.Time) (EntitlementValue, error) + GetEntitlementValue(ctx context.Context, namespace string, subjectKey string, idOrFeatureKey string, at time.Time) (EntitlementValue, error) GetEntitlementsOfSubject(ctx context.Context, namespace string, subjectKey models.SubjectKey) ([]Entitlement, error) ListEntitlements(ctx context.Context, params ListEntitlementsParams) ([]Entitlement, error) @@ -62,19 +62,34 @@ func NewEntitlementConnector( } func (c *entitlementConnector) CreateEntitlement(ctx context.Context, input CreateEntitlementInputs) (*Entitlement, error) { - feature, err := c.featureConnector.GetFeature(ctx, input.Namespace, input.FeatureID) + // ID has priority over key + idOrFeatureKey := input.FeatureID + if idOrFeatureKey == nil { + idOrFeatureKey = input.FeatureKey + } + if idOrFeatureKey == nil { + return nil, &models.GenericUserError{Message: "Feature ID or Key is required"} + } + + feature, err := c.featureConnector.GetFeature(ctx, input.Namespace, *idOrFeatureKey) if err != nil || feature == nil { - return nil, &productcatalog.FeatureNotFoundError{ID: input.FeatureID} + return nil, &productcatalog.FeatureNotFoundError{ID: *idOrFeatureKey} } if feature.ArchivedAt != nil && feature.ArchivedAt.Before(time.Now()) { return nil, &models.GenericUserError{Message: "Feature is archived"} } + + // fill featureId and featureKey + input.FeatureID = &feature.ID + input.FeatureKey = &feature.Key + currentEntitlements, err := c.entitlementRepo.GetEntitlementsOfSubject(ctx, input.Namespace, models.SubjectKey(input.SubjectKey)) if err != nil { return nil, err } for _, ent := range currentEntitlements { - if ent.FeatureID == feature.ID { + // you can only have a single entitlemnet per feature key + if ent.FeatureKey == feature.Key || ent.FeatureID == feature.ID { return nil, &AlreadyExistsError{EntitlementID: ent.ID, FeatureID: feature.ID, SubjectKey: input.SubjectKey} } } @@ -104,7 +119,8 @@ func (c *entitlementConnector) CreateEntitlement(ctx context.Context, input Crea ent, err := c.entitlementRepo.CreateEntitlement(ctx, CreateEntitlementRepoInputs{ Namespace: input.Namespace, - FeatureID: input.FeatureID, + FeatureID: feature.ID, + FeatureKey: feature.Key, SubjectKey: input.SubjectKey, EntitlementType: input.EntitlementType, Metadata: input.Metadata, @@ -138,8 +154,8 @@ func (c *entitlementConnector) GetEntitlementsOfSubject(ctx context.Context, nam return c.entitlementRepo.GetEntitlementsOfSubject(ctx, namespace, subjectKey) } -func (c *entitlementConnector) GetEntitlementValue(ctx context.Context, namespace string, subjectKey string, id string, at time.Time) (EntitlementValue, error) { - ent, err := c.entitlementRepo.GetEntitlementOfSubject(ctx, namespace, subjectKey, id) +func (c *entitlementConnector) GetEntitlementValue(ctx context.Context, namespace string, subjectKey string, idOrFeatureKey string, at time.Time) (EntitlementValue, error) { + ent, err := c.entitlementRepo.GetEntitlementOfSubject(ctx, namespace, subjectKey, idOrFeatureKey) if err != nil { return nil, err } diff --git a/internal/entitlement/entitlement.go b/internal/entitlement/entitlement.go index 2ec99dc0e..4a0afbb5b 100644 --- a/internal/entitlement/entitlement.go +++ b/internal/entitlement/entitlement.go @@ -14,7 +14,8 @@ type TypedEntitlement interface { type CreateEntitlementInputs struct { Namespace string `json:"namespace"` - FeatureID string `json:"featureId"` + FeatureID *string `json:"featureId"` + FeatureKey *string `json:"featureKey"` SubjectKey string `json:"subjectKey"` EntitlementType EntitlementType `json:"type"` Metadata map[string]string `json:"metadata,omitempty"` @@ -83,6 +84,7 @@ type GenericProperties struct { ID string `json:"id,omitempty"` FeatureID string `json:"featureId,omitempty"` + FeatureKey string `json:"featureKey,omitempty"` SubjectKey string `json:"subjectKey,omitempty"` EntitlementType EntitlementType `json:"type,omitempty"` diff --git a/internal/entitlement/httpdriver/entitlement.go b/internal/entitlement/httpdriver/entitlement.go index e909c3541..e63be7cc5 100644 --- a/internal/entitlement/httpdriver/entitlement.go +++ b/internal/entitlement/httpdriver/entitlement.go @@ -77,6 +77,7 @@ func (h *entitlementHandler) CreateEntitlement() CreateEntitlementHandler { request = entitlement.CreateEntitlementInputs{ Namespace: ns, FeatureID: v.FeatureId, + FeatureKey: v.FeatureKey, SubjectKey: subjectIdOrKey, EntitlementType: entitlement.EntitlementTypeMetered, IsSoftLimit: v.IsSoftLimit, @@ -93,6 +94,7 @@ func (h *entitlementHandler) CreateEntitlement() CreateEntitlementHandler { request = entitlement.CreateEntitlementInputs{ Namespace: ns, FeatureID: v.FeatureId, + FeatureKey: v.FeatureKey, SubjectKey: subjectIdOrKey, EntitlementType: entitlement.EntitlementTypeStatic, Config: &v.Config, @@ -110,6 +112,7 @@ func (h *entitlementHandler) CreateEntitlement() CreateEntitlementHandler { request = entitlement.CreateEntitlementInputs{ Namespace: ns, FeatureID: v.FeatureId, + FeatureKey: v.FeatureKey, SubjectKey: subjectIdOrKey, EntitlementType: entitlement.EntitlementTypeBoolean, } diff --git a/internal/entitlement/httpdriver/parser.go b/internal/entitlement/httpdriver/parser.go index e81005a26..3d9a77d55 100644 --- a/internal/entitlement/httpdriver/parser.go +++ b/internal/entitlement/httpdriver/parser.go @@ -26,6 +26,7 @@ func (parser) ToMetered(e *entitlement.Entitlement) (*api.EntitlementMetered, er CreatedAt: &metered.CreatedAt, DeletedAt: metered.DeletedAt, FeatureId: metered.FeatureID, + FeatureKey: metered.FeatureKey, Id: &metered.ID, IsUnlimited: convert.ToPointer(false), // implement IssueAfterReset: metered.IssuesAfterReset, @@ -49,6 +50,7 @@ func (parser) ToStatic(e *entitlement.Entitlement) (*api.EntitlementStatic, erro CreatedAt: &static.CreatedAt, DeletedAt: static.DeletedAt, FeatureId: static.FeatureID, + FeatureKey: static.FeatureKey, Id: &static.ID, Metadata: convert.MapToPointer(static.Metadata), SubjectKey: static.SubjectKey, @@ -72,6 +74,7 @@ func (parser) ToBoolean(e *entitlement.Entitlement) (*api.EntitlementBoolean, er CreatedAt: &boolean.CreatedAt, DeletedAt: boolean.DeletedAt, FeatureId: boolean.FeatureID, + FeatureKey: boolean.FeatureKey, Id: &boolean.ID, Metadata: convert.MapToPointer(boolean.Metadata), SubjectKey: boolean.SubjectKey, diff --git a/internal/entitlement/metered/balance_test.go b/internal/entitlement/metered/balance_test.go index 2bf50837a..487fc2978 100644 --- a/internal/entitlement/metered/balance_test.go +++ b/internal/entitlement/metered/balance_test.go @@ -43,6 +43,8 @@ func TestGetEntitlementBalance(t *testing.T) { input := entitlement.CreateEntitlementRepoInputs{ Namespace: namespace, FeatureID: feature.ID, + FeatureKey: feature.Key, + SubjectKey: "subject1", MeasureUsageFrom: convert.ToPointer(testutils.GetRFC3339Time(t, "1024-03-01T00:00:00Z")), // old, override in tests EntitlementType: entitlement.EntitlementTypeMetered, IssueAfterReset: convert.ToPointer(0.0), @@ -428,6 +430,8 @@ func TestGetEntitlementHistory(t *testing.T) { input := entitlement.CreateEntitlementRepoInputs{ Namespace: namespace, FeatureID: feature.ID, + FeatureKey: feature.Key, + SubjectKey: "subject1", MeasureUsageFrom: convert.ToPointer(testutils.GetRFC3339Time(t, "1024-03-01T00:00:00Z")), // old, override in tests EntitlementType: entitlement.EntitlementTypeMetered, IssueAfterReset: convert.ToPointer(0.0), @@ -672,6 +676,8 @@ func TestResetEntitlementUsage(t *testing.T) { input := entitlement.CreateEntitlementRepoInputs{ Namespace: namespace, FeatureID: feature.ID, + FeatureKey: feature.Key, + SubjectKey: "subject1", MeasureUsageFrom: convert.ToPointer(testutils.GetRFC3339Time(t, "1024-03-01T00:00:00Z")), // old, override in tests EntitlementType: entitlement.EntitlementTypeMetered, IssueAfterReset: convert.ToPointer(0.0), diff --git a/internal/entitlement/postgresadapter/ent/db/entitlement.go b/internal/entitlement/postgresadapter/ent/db/entitlement.go index 76176155d..734b73bda 100644 --- a/internal/entitlement/postgresadapter/ent/db/entitlement.go +++ b/internal/entitlement/postgresadapter/ent/db/entitlement.go @@ -32,6 +32,8 @@ type Entitlement struct { EntitlementType entitlement.EntitlementType `json:"entitlement_type,omitempty"` // FeatureID holds the value of the "feature_id" field. FeatureID string `json:"feature_id,omitempty"` + // FeatureKey holds the value of the "feature_key" field. + FeatureKey string `json:"feature_key,omitempty"` // SubjectKey holds the value of the "subject_key" field. SubjectKey string `json:"subject_key,omitempty"` // MeasureUsageFrom holds the value of the "measure_usage_from" field. @@ -85,7 +87,7 @@ func (*Entitlement) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullBool) case entitlement.FieldIssueAfterReset: values[i] = new(sql.NullFloat64) - case entitlement.FieldID, entitlement.FieldNamespace, entitlement.FieldEntitlementType, entitlement.FieldFeatureID, entitlement.FieldSubjectKey, entitlement.FieldUsagePeriodInterval: + case entitlement.FieldID, entitlement.FieldNamespace, entitlement.FieldEntitlementType, entitlement.FieldFeatureID, entitlement.FieldFeatureKey, entitlement.FieldSubjectKey, entitlement.FieldUsagePeriodInterval: values[i] = new(sql.NullString) case entitlement.FieldCreatedAt, entitlement.FieldUpdatedAt, entitlement.FieldDeletedAt, entitlement.FieldMeasureUsageFrom, entitlement.FieldUsagePeriodAnchor, entitlement.FieldCurrentUsagePeriodStart, entitlement.FieldCurrentUsagePeriodEnd: values[i] = new(sql.NullTime) @@ -155,6 +157,12 @@ func (e *Entitlement) assignValues(columns []string, values []any) error { } else if value.Valid { e.FeatureID = value.String } + case entitlement.FieldFeatureKey: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field feature_key", values[i]) + } else if value.Valid { + e.FeatureKey = value.String + } case entitlement.FieldSubjectKey: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field subject_key", values[i]) @@ -282,6 +290,9 @@ func (e *Entitlement) String() string { builder.WriteString("feature_id=") builder.WriteString(e.FeatureID) builder.WriteString(", ") + builder.WriteString("feature_key=") + builder.WriteString(e.FeatureKey) + builder.WriteString(", ") builder.WriteString("subject_key=") builder.WriteString(e.SubjectKey) builder.WriteString(", ") diff --git a/internal/entitlement/postgresadapter/ent/db/entitlement/entitlement.go b/internal/entitlement/postgresadapter/ent/db/entitlement/entitlement.go index 2fca7dc9d..0267412ad 100644 --- a/internal/entitlement/postgresadapter/ent/db/entitlement/entitlement.go +++ b/internal/entitlement/postgresadapter/ent/db/entitlement/entitlement.go @@ -29,6 +29,8 @@ const ( FieldEntitlementType = "entitlement_type" // FieldFeatureID holds the string denoting the feature_id field in the database. FieldFeatureID = "feature_id" + // FieldFeatureKey holds the string denoting the feature_key field in the database. + FieldFeatureKey = "feature_key" // FieldSubjectKey holds the string denoting the subject_key field in the database. FieldSubjectKey = "subject_key" // FieldMeasureUsageFrom holds the string denoting the measure_usage_from field in the database. @@ -70,6 +72,7 @@ var Columns = []string{ FieldDeletedAt, FieldEntitlementType, FieldFeatureID, + FieldFeatureKey, FieldSubjectKey, FieldMeasureUsageFrom, FieldIssueAfterReset, @@ -100,6 +103,10 @@ var ( DefaultUpdatedAt func() time.Time // UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field. UpdateDefaultUpdatedAt func() time.Time + // FeatureKeyValidator is a validator for the "feature_key" field. It is called by the builders before save. + FeatureKeyValidator func(string) error + // SubjectKeyValidator is a validator for the "subject_key" field. It is called by the builders before save. + SubjectKeyValidator func(string) error // DefaultID holds the default value on creation for the "id" field. DefaultID func() string ) @@ -191,6 +198,11 @@ func ByFeatureID(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldFeatureID, opts...).ToFunc() } +// ByFeatureKey orders the results by the feature_key field. +func ByFeatureKey(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFeatureKey, opts...).ToFunc() +} + // BySubjectKey orders the results by the subject_key field. func BySubjectKey(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldSubjectKey, opts...).ToFunc() diff --git a/internal/entitlement/postgresadapter/ent/db/entitlement/where.go b/internal/entitlement/postgresadapter/ent/db/entitlement/where.go index 747c1c27e..fec305bd3 100644 --- a/internal/entitlement/postgresadapter/ent/db/entitlement/where.go +++ b/internal/entitlement/postgresadapter/ent/db/entitlement/where.go @@ -90,6 +90,11 @@ func FeatureID(v string) predicate.Entitlement { return predicate.Entitlement(sql.FieldEQ(FieldFeatureID, v)) } +// FeatureKey applies equality check predicate on the "feature_key" field. It's identical to FeatureKeyEQ. +func FeatureKey(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldEQ(FieldFeatureKey, v)) +} + // SubjectKey applies equality check predicate on the "subject_key" field. It's identical to SubjectKeyEQ. func SubjectKey(v string) predicate.Entitlement { return predicate.Entitlement(sql.FieldEQ(FieldSubjectKey, v)) @@ -415,6 +420,71 @@ func FeatureIDContainsFold(v string) predicate.Entitlement { return predicate.Entitlement(sql.FieldContainsFold(FieldFeatureID, v)) } +// FeatureKeyEQ applies the EQ predicate on the "feature_key" field. +func FeatureKeyEQ(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldEQ(FieldFeatureKey, v)) +} + +// FeatureKeyNEQ applies the NEQ predicate on the "feature_key" field. +func FeatureKeyNEQ(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldNEQ(FieldFeatureKey, v)) +} + +// FeatureKeyIn applies the In predicate on the "feature_key" field. +func FeatureKeyIn(vs ...string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldIn(FieldFeatureKey, vs...)) +} + +// FeatureKeyNotIn applies the NotIn predicate on the "feature_key" field. +func FeatureKeyNotIn(vs ...string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldNotIn(FieldFeatureKey, vs...)) +} + +// FeatureKeyGT applies the GT predicate on the "feature_key" field. +func FeatureKeyGT(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldGT(FieldFeatureKey, v)) +} + +// FeatureKeyGTE applies the GTE predicate on the "feature_key" field. +func FeatureKeyGTE(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldGTE(FieldFeatureKey, v)) +} + +// FeatureKeyLT applies the LT predicate on the "feature_key" field. +func FeatureKeyLT(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldLT(FieldFeatureKey, v)) +} + +// FeatureKeyLTE applies the LTE predicate on the "feature_key" field. +func FeatureKeyLTE(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldLTE(FieldFeatureKey, v)) +} + +// FeatureKeyContains applies the Contains predicate on the "feature_key" field. +func FeatureKeyContains(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldContains(FieldFeatureKey, v)) +} + +// FeatureKeyHasPrefix applies the HasPrefix predicate on the "feature_key" field. +func FeatureKeyHasPrefix(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldHasPrefix(FieldFeatureKey, v)) +} + +// FeatureKeyHasSuffix applies the HasSuffix predicate on the "feature_key" field. +func FeatureKeyHasSuffix(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldHasSuffix(FieldFeatureKey, v)) +} + +// FeatureKeyEqualFold applies the EqualFold predicate on the "feature_key" field. +func FeatureKeyEqualFold(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldEqualFold(FieldFeatureKey, v)) +} + +// FeatureKeyContainsFold applies the ContainsFold predicate on the "feature_key" field. +func FeatureKeyContainsFold(v string) predicate.Entitlement { + return predicate.Entitlement(sql.FieldContainsFold(FieldFeatureKey, v)) +} + // SubjectKeyEQ applies the EQ predicate on the "subject_key" field. func SubjectKeyEQ(v string) predicate.Entitlement { return predicate.Entitlement(sql.FieldEQ(FieldSubjectKey, v)) diff --git a/internal/entitlement/postgresadapter/ent/db/entitlement_create.go b/internal/entitlement/postgresadapter/ent/db/entitlement_create.go index 4d632cba8..60625d48a 100644 --- a/internal/entitlement/postgresadapter/ent/db/entitlement_create.go +++ b/internal/entitlement/postgresadapter/ent/db/entitlement_create.go @@ -90,6 +90,12 @@ func (ec *EntitlementCreate) SetFeatureID(s string) *EntitlementCreate { return ec } +// SetFeatureKey sets the "feature_key" field. +func (ec *EntitlementCreate) SetFeatureKey(s string) *EntitlementCreate { + ec.mutation.SetFeatureKey(s) + return ec +} + // SetSubjectKey sets the "subject_key" field. func (ec *EntitlementCreate) SetSubjectKey(s string) *EntitlementCreate { ec.mutation.SetSubjectKey(s) @@ -305,9 +311,22 @@ func (ec *EntitlementCreate) check() error { if _, ok := ec.mutation.FeatureID(); !ok { return &ValidationError{Name: "feature_id", err: errors.New(`db: missing required field "Entitlement.feature_id"`)} } + if _, ok := ec.mutation.FeatureKey(); !ok { + return &ValidationError{Name: "feature_key", err: errors.New(`db: missing required field "Entitlement.feature_key"`)} + } + if v, ok := ec.mutation.FeatureKey(); ok { + if err := entitlement.FeatureKeyValidator(v); err != nil { + return &ValidationError{Name: "feature_key", err: fmt.Errorf(`db: validator failed for field "Entitlement.feature_key": %w`, err)} + } + } if _, ok := ec.mutation.SubjectKey(); !ok { return &ValidationError{Name: "subject_key", err: errors.New(`db: missing required field "Entitlement.subject_key"`)} } + if v, ok := ec.mutation.SubjectKey(); ok { + if err := entitlement.SubjectKeyValidator(v); err != nil { + return &ValidationError{Name: "subject_key", err: fmt.Errorf(`db: validator failed for field "Entitlement.subject_key": %w`, err)} + } + } if v, ok := ec.mutation.UsagePeriodInterval(); ok { if err := entitlement.UsagePeriodIntervalValidator(v); err != nil { return &ValidationError{Name: "usage_period_interval", err: fmt.Errorf(`db: validator failed for field "Entitlement.usage_period_interval": %w`, err)} @@ -377,6 +396,10 @@ func (ec *EntitlementCreate) createSpec() (*Entitlement, *sqlgraph.CreateSpec) { _spec.SetField(entitlement.FieldFeatureID, field.TypeString, value) _node.FeatureID = value } + if value, ok := ec.mutation.FeatureKey(); ok { + _spec.SetField(entitlement.FieldFeatureKey, field.TypeString, value) + _node.FeatureKey = value + } if value, ok := ec.mutation.SubjectKey(); ok { _spec.SetField(entitlement.FieldSubjectKey, field.TypeString, value) _node.SubjectKey = value @@ -630,6 +653,9 @@ func (u *EntitlementUpsertOne) UpdateNewValues() *EntitlementUpsertOne { if _, exists := u.create.mutation.FeatureID(); exists { s.SetIgnore(entitlement.FieldFeatureID) } + if _, exists := u.create.mutation.FeatureKey(); exists { + s.SetIgnore(entitlement.FieldFeatureKey) + } if _, exists := u.create.mutation.SubjectKey(); exists { s.SetIgnore(entitlement.FieldSubjectKey) } @@ -1011,6 +1037,9 @@ func (u *EntitlementUpsertBulk) UpdateNewValues() *EntitlementUpsertBulk { if _, exists := b.mutation.FeatureID(); exists { s.SetIgnore(entitlement.FieldFeatureID) } + if _, exists := b.mutation.FeatureKey(); exists { + s.SetIgnore(entitlement.FieldFeatureKey) + } if _, exists := b.mutation.SubjectKey(); exists { s.SetIgnore(entitlement.FieldSubjectKey) } diff --git a/internal/entitlement/postgresadapter/ent/db/migrate/schema.go b/internal/entitlement/postgresadapter/ent/db/migrate/schema.go index 8638fcf96..56d29ac1c 100644 --- a/internal/entitlement/postgresadapter/ent/db/migrate/schema.go +++ b/internal/entitlement/postgresadapter/ent/db/migrate/schema.go @@ -18,6 +18,7 @@ var ( {Name: "deleted_at", Type: field.TypeTime, Nullable: true}, {Name: "entitlement_type", Type: field.TypeEnum, Enums: []string{"metered", "static", "boolean"}}, {Name: "feature_id", Type: field.TypeString, SchemaType: map[string]string{"postgres": "char(26)"}}, + {Name: "feature_key", Type: field.TypeString}, {Name: "subject_key", Type: field.TypeString}, {Name: "measure_usage_from", Type: field.TypeTime, Nullable: true}, {Name: "issue_after_reset", Type: field.TypeFloat64, Nullable: true}, @@ -47,12 +48,12 @@ var ( { Name: "entitlement_namespace_subject_key", Unique: false, - Columns: []*schema.Column{EntitlementsColumns[1], EntitlementsColumns[8]}, + Columns: []*schema.Column{EntitlementsColumns[1], EntitlementsColumns[9]}, }, { Name: "entitlement_namespace_id_subject_key", Unique: false, - Columns: []*schema.Column{EntitlementsColumns[1], EntitlementsColumns[0], EntitlementsColumns[8]}, + Columns: []*schema.Column{EntitlementsColumns[1], EntitlementsColumns[0], EntitlementsColumns[9]}, }, { Name: "entitlement_namespace_feature_id_id", @@ -62,7 +63,7 @@ var ( { Name: "entitlement_namespace_current_usage_period_end", Unique: false, - Columns: []*schema.Column{EntitlementsColumns[1], EntitlementsColumns[16]}, + Columns: []*schema.Column{EntitlementsColumns[1], EntitlementsColumns[17]}, }, }, } diff --git a/internal/entitlement/postgresadapter/ent/db/mutation.go b/internal/entitlement/postgresadapter/ent/db/mutation.go index ff206b98f..ac59c6536 100644 --- a/internal/entitlement/postgresadapter/ent/db/mutation.go +++ b/internal/entitlement/postgresadapter/ent/db/mutation.go @@ -42,6 +42,7 @@ type EntitlementMutation struct { deleted_at *time.Time entitlement_type *entitlement.EntitlementType feature_id *string + feature_key *string subject_key *string measure_usage_from *time.Time issue_after_reset *float64 @@ -443,6 +444,42 @@ func (m *EntitlementMutation) ResetFeatureID() { m.feature_id = nil } +// SetFeatureKey sets the "feature_key" field. +func (m *EntitlementMutation) SetFeatureKey(s string) { + m.feature_key = &s +} + +// FeatureKey returns the value of the "feature_key" field in the mutation. +func (m *EntitlementMutation) FeatureKey() (r string, exists bool) { + v := m.feature_key + if v == nil { + return + } + return *v, true +} + +// OldFeatureKey returns the old "feature_key" field's value of the Entitlement entity. +// If the Entitlement 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 *EntitlementMutation) OldFeatureKey(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFeatureKey is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFeatureKey requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFeatureKey: %w", err) + } + return oldValue.FeatureKey, nil +} + +// ResetFeatureKey resets all changes to the "feature_key" field. +func (m *EntitlementMutation) ResetFeatureKey() { + m.feature_key = nil +} + // SetSubjectKey sets the "subject_key" field. func (m *EntitlementMutation) SetSubjectKey(s string) { m.subject_key = &s @@ -980,7 +1017,7 @@ func (m *EntitlementMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *EntitlementMutation) Fields() []string { - fields := make([]string, 0, 16) + fields := make([]string, 0, 17) if m.namespace != nil { fields = append(fields, entitlement.FieldNamespace) } @@ -1002,6 +1039,9 @@ func (m *EntitlementMutation) Fields() []string { if m.feature_id != nil { fields = append(fields, entitlement.FieldFeatureID) } + if m.feature_key != nil { + fields = append(fields, entitlement.FieldFeatureKey) + } if m.subject_key != nil { fields = append(fields, entitlement.FieldSubjectKey) } @@ -1051,6 +1091,8 @@ func (m *EntitlementMutation) Field(name string) (ent.Value, bool) { return m.EntitlementType() case entitlement.FieldFeatureID: return m.FeatureID() + case entitlement.FieldFeatureKey: + return m.FeatureKey() case entitlement.FieldSubjectKey: return m.SubjectKey() case entitlement.FieldMeasureUsageFrom: @@ -1092,6 +1134,8 @@ func (m *EntitlementMutation) OldField(ctx context.Context, name string) (ent.Va return m.OldEntitlementType(ctx) case entitlement.FieldFeatureID: return m.OldFeatureID(ctx) + case entitlement.FieldFeatureKey: + return m.OldFeatureKey(ctx) case entitlement.FieldSubjectKey: return m.OldSubjectKey(ctx) case entitlement.FieldMeasureUsageFrom: @@ -1168,6 +1212,13 @@ func (m *EntitlementMutation) SetField(name string, value ent.Value) error { } m.SetFeatureID(v) return nil + case entitlement.FieldFeatureKey: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFeatureKey(v) + return nil case entitlement.FieldSubjectKey: v, ok := value.(string) if !ok { @@ -1379,6 +1430,9 @@ func (m *EntitlementMutation) ResetField(name string) error { case entitlement.FieldFeatureID: m.ResetFeatureID() return nil + case entitlement.FieldFeatureKey: + m.ResetFeatureKey() + return nil case entitlement.FieldSubjectKey: m.ResetSubjectKey() return nil diff --git a/internal/entitlement/postgresadapter/ent/db/runtime.go b/internal/entitlement/postgresadapter/ent/db/runtime.go index c129bd025..4b0b46e93 100644 --- a/internal/entitlement/postgresadapter/ent/db/runtime.go +++ b/internal/entitlement/postgresadapter/ent/db/runtime.go @@ -37,6 +37,14 @@ func init() { entitlement.DefaultUpdatedAt = entitlementDescUpdatedAt.Default.(func() time.Time) // entitlement.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field. entitlement.UpdateDefaultUpdatedAt = entitlementDescUpdatedAt.UpdateDefault.(func() time.Time) + // entitlementDescFeatureKey is the schema descriptor for feature_key field. + entitlementDescFeatureKey := entitlementFields[2].Descriptor() + // entitlement.FeatureKeyValidator is a validator for the "feature_key" field. It is called by the builders before save. + entitlement.FeatureKeyValidator = entitlementDescFeatureKey.Validators[0].(func(string) error) + // entitlementDescSubjectKey is the schema descriptor for subject_key field. + entitlementDescSubjectKey := entitlementFields[3].Descriptor() + // entitlement.SubjectKeyValidator is a validator for the "subject_key" field. It is called by the builders before save. + entitlement.SubjectKeyValidator = entitlementDescSubjectKey.Validators[0].(func(string) error) // entitlementDescID is the schema descriptor for id field. entitlementDescID := entitlementMixinFields0[0].Descriptor() // entitlement.DefaultID holds the default value on creation for the id field. diff --git a/internal/entitlement/postgresadapter/ent/schema/entitlement.go b/internal/entitlement/postgresadapter/ent/schema/entitlement.go index d16fba3f1..449364565 100644 --- a/internal/entitlement/postgresadapter/ent/schema/entitlement.go +++ b/internal/entitlement/postgresadapter/ent/schema/entitlement.go @@ -31,7 +31,8 @@ func (Entitlement) Fields() []ent.Field { field.String("feature_id").Immutable().SchemaType(map[string]string{ dialect.Postgres: "char(26)", }), - field.String("subject_key").Immutable(), + field.String("feature_key").NotEmpty().Immutable(), + field.String("subject_key").NotEmpty().Immutable(), field.Time("measure_usage_from").Optional().Nillable().Immutable(), field.Float("issue_after_reset").Optional().Nillable().Immutable(), field.Bool("is_soft_limit").Optional().Nillable().Immutable(), diff --git a/internal/entitlement/postgresadapter/entitlement.go b/internal/entitlement/postgresadapter/entitlement.go index c3b6c84da..dbbddc509 100644 --- a/internal/entitlement/postgresadapter/entitlement.go +++ b/internal/entitlement/postgresadapter/entitlement.go @@ -46,13 +46,13 @@ func (a *entitlementDBAdapter) GetEntitlement(ctx context.Context, entitlementID return mapEntitlementEntity(res), nil } -func (a *entitlementDBAdapter) GetEntitlementOfSubject(ctx context.Context, namespace string, subjectKey string, id string) (*entitlement.Entitlement, error) { +func (a *entitlementDBAdapter) GetEntitlementOfSubject(ctx context.Context, namespace string, subjectKey string, idOrFeatureKey string) (*entitlement.Entitlement, error) { res, err := withLatestUsageReset(a.db.Entitlement.Query()). Where( db_entitlement.Or(db_entitlement.DeletedAtGT(time.Now()), db_entitlement.DeletedAtIsNil()), db_entitlement.SubjectKey(string(subjectKey)), db_entitlement.Namespace(namespace), - db_entitlement.ID(id), + db_entitlement.Or(db_entitlement.ID(idOrFeatureKey), db_entitlement.FeatureKey(idOrFeatureKey)), ). First(ctx) @@ -61,7 +61,7 @@ func (a *entitlementDBAdapter) GetEntitlementOfSubject(ctx context.Context, name return nil, &entitlement.NotFoundError{ EntitlementID: models.NamespacedID{ Namespace: namespace, - ID: id, + ID: idOrFeatureKey, }, } } @@ -78,6 +78,7 @@ func (a *entitlementDBAdapter) CreateEntitlement(ctx context.Context, entitlemen SetFeatureID(entitlement.FeatureID). SetMetadata(entitlement.Metadata). SetSubjectKey(entitlement.SubjectKey). + SetFeatureKey(entitlement.FeatureKey). SetNillableMeasureUsageFrom(entitlement.MeasureUsageFrom). SetNillableIssueAfterReset(entitlement.IssueAfterReset). SetNillableIsSoftLimit(entitlement.IsSoftLimit) @@ -191,6 +192,7 @@ func mapEntitlementEntity(e *db.Entitlement) *entitlement.Entitlement { ID: e.ID, SubjectKey: e.SubjectKey, FeatureID: e.FeatureID, + FeatureKey: e.FeatureKey, EntitlementType: entitlement.EntitlementType(e.EntitlementType), Metadata: e.Metadata, }, diff --git a/internal/entitlement/repository.go b/internal/entitlement/repository.go index 16162b590..2fe1c1b31 100644 --- a/internal/entitlement/repository.go +++ b/internal/entitlement/repository.go @@ -19,7 +19,7 @@ type EntitlementRepo interface { GetEntitlementsOfSubject(ctx context.Context, namespace string, subjectKey models.SubjectKey) ([]Entitlement, error) CreateEntitlement(ctx context.Context, entitlement CreateEntitlementRepoInputs) (*Entitlement, error) GetEntitlement(ctx context.Context, entitlementID models.NamespacedID) (*Entitlement, error) - GetEntitlementOfSubject(ctx context.Context, namespace string, subjectKey string, id string) (*Entitlement, error) + GetEntitlementOfSubject(ctx context.Context, namespace string, subjectKey string, idOrFeatureKey string) (*Entitlement, error) DeleteEntitlement(ctx context.Context, entitlementID models.NamespacedID) error ListEntitlements(ctx context.Context, params ListEntitlementsParams) ([]Entitlement, error) @@ -37,6 +37,7 @@ type EntitlementRepo interface { type CreateEntitlementRepoInputs struct { Namespace string `json:"namespace"` FeatureID string `json:"featureId"` + FeatureKey string `json:"featureKey"` SubjectKey string `json:"subjectKey"` EntitlementType EntitlementType `json:"type"` Metadata map[string]string `json:"metadata,omitempty"`