From 8155544904aca5423213c08e2d8d501acc257688 Mon Sep 17 00:00:00 2001 From: Nick Zelei <2420177+nickzelei@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:50:39 -0700 Subject: [PATCH] NEOS-1562: convert record limit to time based in account status (#2842) --- backend/gen/go/db/mock_Querier.go | 32 +- backend/gen/go/db/querier.go | 2 +- backend/gen/go/db/users.sql.go | 14 +- .../protos/mgmt/v1alpha1/user_account.pb.go | 439 ++++++++++-------- .../mgmt/v1alpha1/user_account.openapi.yaml | 9 +- .../internal/cmds/mgmt/serve/connect/cmd.go | 2 +- .../protos/mgmt/v1alpha1/user_account.proto | 14 +- .../integration_tests/integration_test.go | 3 - .../integration_util_test.go | 11 +- .../user-account-service_integration_test.go | 198 +++----- .../v1alpha1/user-account-service/billing.go | 248 ++++------ .../user-account-service/billing_test.go | 35 -- .../v1alpha1/user-account-service/service.go | 4 - backend/sql/postgresql/queries/users.sql | 4 +- docs/protos/proto_docs.json | 28 +- .../site-header/AccountStatusHandler.tsx | 18 +- .../site-header/RecordsProgressBar.tsx | 87 ---- .../web/components/site-header/Upgrade.tsx | 97 +--- frontend/apps/web/components/ui/progress.tsx | 28 -- frontend/apps/web/package.json | 1 - frontend/package-lock.json | 24 - .../client/mgmt/v1alpha1/user_account_pb.ts | 38 +- .../neosync/mgmt/v1alpha1/user_account_pb2.py | 14 +- .../mgmt/v1alpha1/user_account_pb2.pyi | 8 + 24 files changed, 540 insertions(+), 818 deletions(-) delete mode 100644 backend/services/mgmt/v1alpha1/user-account-service/billing_test.go delete mode 100644 frontend/apps/web/components/site-header/RecordsProgressBar.tsx delete mode 100644 frontend/apps/web/components/ui/progress.tsx diff --git a/backend/gen/go/db/mock_Querier.go b/backend/gen/go/db/mock_Querier.go index f55dae8390..a7b734aff5 100644 --- a/backend/gen/go/db/mock_Querier.go +++ b/backend/gen/go/db/mock_Querier.go @@ -3771,26 +3771,26 @@ func (_c *MockQuerier_RemoveJobConnectionDestinations_Call) RunAndReturn(run fun return _c } -// SetAccountMaxAllowedRecords provides a mock function with given fields: ctx, db, arg -func (_m *MockQuerier) SetAccountMaxAllowedRecords(ctx context.Context, db DBTX, arg SetAccountMaxAllowedRecordsParams) (NeosyncApiAccount, error) { +// SetAccountCreatedAt provides a mock function with given fields: ctx, db, arg +func (_m *MockQuerier) SetAccountCreatedAt(ctx context.Context, db DBTX, arg SetAccountCreatedAtParams) (NeosyncApiAccount, error) { ret := _m.Called(ctx, db, arg) if len(ret) == 0 { - panic("no return value specified for SetAccountMaxAllowedRecords") + panic("no return value specified for SetAccountCreatedAt") } var r0 NeosyncApiAccount var r1 error - if rf, ok := ret.Get(0).(func(context.Context, DBTX, SetAccountMaxAllowedRecordsParams) (NeosyncApiAccount, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, DBTX, SetAccountCreatedAtParams) (NeosyncApiAccount, error)); ok { return rf(ctx, db, arg) } - if rf, ok := ret.Get(0).(func(context.Context, DBTX, SetAccountMaxAllowedRecordsParams) NeosyncApiAccount); ok { + if rf, ok := ret.Get(0).(func(context.Context, DBTX, SetAccountCreatedAtParams) NeosyncApiAccount); ok { r0 = rf(ctx, db, arg) } else { r0 = ret.Get(0).(NeosyncApiAccount) } - if rf, ok := ret.Get(1).(func(context.Context, DBTX, SetAccountMaxAllowedRecordsParams) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, DBTX, SetAccountCreatedAtParams) error); ok { r1 = rf(ctx, db, arg) } else { r1 = ret.Error(1) @@ -3799,32 +3799,32 @@ func (_m *MockQuerier) SetAccountMaxAllowedRecords(ctx context.Context, db DBTX, return r0, r1 } -// MockQuerier_SetAccountMaxAllowedRecords_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAccountMaxAllowedRecords' -type MockQuerier_SetAccountMaxAllowedRecords_Call struct { +// MockQuerier_SetAccountCreatedAt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAccountCreatedAt' +type MockQuerier_SetAccountCreatedAt_Call struct { *mock.Call } -// SetAccountMaxAllowedRecords is a helper method to define mock.On call +// SetAccountCreatedAt is a helper method to define mock.On call // - ctx context.Context // - db DBTX -// - arg SetAccountMaxAllowedRecordsParams -func (_e *MockQuerier_Expecter) SetAccountMaxAllowedRecords(ctx interface{}, db interface{}, arg interface{}) *MockQuerier_SetAccountMaxAllowedRecords_Call { - return &MockQuerier_SetAccountMaxAllowedRecords_Call{Call: _e.mock.On("SetAccountMaxAllowedRecords", ctx, db, arg)} +// - arg SetAccountCreatedAtParams +func (_e *MockQuerier_Expecter) SetAccountCreatedAt(ctx interface{}, db interface{}, arg interface{}) *MockQuerier_SetAccountCreatedAt_Call { + return &MockQuerier_SetAccountCreatedAt_Call{Call: _e.mock.On("SetAccountCreatedAt", ctx, db, arg)} } -func (_c *MockQuerier_SetAccountMaxAllowedRecords_Call) Run(run func(ctx context.Context, db DBTX, arg SetAccountMaxAllowedRecordsParams)) *MockQuerier_SetAccountMaxAllowedRecords_Call { +func (_c *MockQuerier_SetAccountCreatedAt_Call) Run(run func(ctx context.Context, db DBTX, arg SetAccountCreatedAtParams)) *MockQuerier_SetAccountCreatedAt_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(DBTX), args[2].(SetAccountMaxAllowedRecordsParams)) + run(args[0].(context.Context), args[1].(DBTX), args[2].(SetAccountCreatedAtParams)) }) return _c } -func (_c *MockQuerier_SetAccountMaxAllowedRecords_Call) Return(_a0 NeosyncApiAccount, _a1 error) *MockQuerier_SetAccountMaxAllowedRecords_Call { +func (_c *MockQuerier_SetAccountCreatedAt_Call) Return(_a0 NeosyncApiAccount, _a1 error) *MockQuerier_SetAccountCreatedAt_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockQuerier_SetAccountMaxAllowedRecords_Call) RunAndReturn(run func(context.Context, DBTX, SetAccountMaxAllowedRecordsParams) (NeosyncApiAccount, error)) *MockQuerier_SetAccountMaxAllowedRecords_Call { +func (_c *MockQuerier_SetAccountCreatedAt_Call) RunAndReturn(run func(context.Context, DBTX, SetAccountCreatedAtParams) (NeosyncApiAccount, error)) *MockQuerier_SetAccountCreatedAt_Call { _c.Call.Return(run) return _c } diff --git a/backend/gen/go/db/querier.go b/backend/gen/go/db/querier.go index 10e97220e1..3b3e87f08a 100644 --- a/backend/gen/go/db/querier.go +++ b/backend/gen/go/db/querier.go @@ -78,7 +78,7 @@ type Querier interface { RemoveJobById(ctx context.Context, db DBTX, id pgtype.UUID) error RemoveJobConnectionDestination(ctx context.Context, db DBTX, id pgtype.UUID) error RemoveJobConnectionDestinations(ctx context.Context, db DBTX, jobids []pgtype.UUID) error - SetAccountMaxAllowedRecords(ctx context.Context, db DBTX, arg SetAccountMaxAllowedRecordsParams) (NeosyncApiAccount, error) + SetAccountCreatedAt(ctx context.Context, db DBTX, arg SetAccountCreatedAtParams) (NeosyncApiAccount, error) SetAnonymousUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) SetJobSyncOptions(ctx context.Context, db DBTX, arg SetJobSyncOptionsParams) (NeosyncApiJob, error) SetJobWorkflowOptions(ctx context.Context, db DBTX, arg SetJobWorkflowOptionsParams) (NeosyncApiJob, error) diff --git a/backend/gen/go/db/users.sql.go b/backend/gen/go/db/users.sql.go index 744ac9ec21..9e2ec0f783 100644 --- a/backend/gen/go/db/users.sql.go +++ b/backend/gen/go/db/users.sql.go @@ -737,20 +737,20 @@ func (q *Queries) RemoveAccountUser(ctx context.Context, db DBTX, arg RemoveAcco return err } -const setAccountMaxAllowedRecords = `-- name: SetAccountMaxAllowedRecords :one +const setAccountCreatedAt = `-- name: SetAccountCreatedAt :one UPDATE neosync_api.accounts -SET max_allowed_records = $1 +SET created_at = $1 WHERE id = $2 RETURNING id, created_at, updated_at, account_type, account_slug, temporal_config, onboarding_config, max_allowed_records, stripe_customer_id ` -type SetAccountMaxAllowedRecordsParams struct { - MaxAllowedRecords pgtype.Int8 - AccountId pgtype.UUID +type SetAccountCreatedAtParams struct { + CreatedAt pgtype.Timestamp + AccountId pgtype.UUID } -func (q *Queries) SetAccountMaxAllowedRecords(ctx context.Context, db DBTX, arg SetAccountMaxAllowedRecordsParams) (NeosyncApiAccount, error) { - row := db.QueryRow(ctx, setAccountMaxAllowedRecords, arg.MaxAllowedRecords, arg.AccountId) +func (q *Queries) SetAccountCreatedAt(ctx context.Context, db DBTX, arg SetAccountCreatedAtParams) (NeosyncApiAccount, error) { + row := db.QueryRow(ctx, setAccountCreatedAt, arg.CreatedAt, arg.AccountId) var i NeosyncApiAccount err := row.Scan( &i.ID, diff --git a/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go b/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go index d9332c3840..9e57d6f8b9 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/user_account.pb.go @@ -83,6 +83,10 @@ const ( BillingStatus_BILLING_STATUS_ACTIVE BillingStatus = 1 // If the system could not find any active subscriptions BillingStatus_BILLING_STATUS_EXPIRED BillingStatus = 2 + // The account does not have an active subscription and is in a valid trial period + BillingStatus_BILLING_STATUS_TRIAL_ACTIVE BillingStatus = 3 + // The account does not have an active subscription and the trial period has ended + BillingStatus_BILLING_STATUS_TRIAL_EXPIRED BillingStatus = 4 ) // Enum value maps for BillingStatus. @@ -91,11 +95,15 @@ var ( 0: "BILLING_STATUS_UNSPECIFIED", 1: "BILLING_STATUS_ACTIVE", 2: "BILLING_STATUS_EXPIRED", + 3: "BILLING_STATUS_TRIAL_ACTIVE", + 4: "BILLING_STATUS_TRIAL_EXPIRED", } BillingStatus_value = map[string]int32{ - "BILLING_STATUS_UNSPECIFIED": 0, - "BILLING_STATUS_ACTIVE": 1, - "BILLING_STATUS_EXPIRED": 2, + "BILLING_STATUS_UNSPECIFIED": 0, + "BILLING_STATUS_ACTIVE": 1, + "BILLING_STATUS_EXPIRED": 2, + "BILLING_STATUS_TRIAL_ACTIVE": 3, + "BILLING_STATUS_TRIAL_EXPIRED": 4, } ) @@ -131,12 +139,16 @@ type AccountStatus int32 const ( // Default value, should be used when no reason is specified AccountStatus_ACCOUNT_STATUS_REASON_UNSPECIFIED AccountStatus = 0 - // Current usage exceeds allowed limit + // @deprecated - Current usage exceeds allowed limit AccountStatus_ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT AccountStatus = 1 - // Adding requested records exceeds the allowed limit + // @deprecated - Adding requested records exceeds the allowed limit AccountStatus_ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT AccountStatus = 2 // Account is currently in an expired state AccountStatus_ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE AccountStatus = 3 + // The account is currently in an active trial period + AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE AccountStatus = 4 + // The account is past the active trial period + AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED AccountStatus = 5 ) // Enum value maps for AccountStatus. @@ -146,12 +158,16 @@ var ( 1: "ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT", 2: "ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT", 3: "ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE", + 4: "ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE", + 5: "ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED", } AccountStatus_value = map[string]int32{ "ACCOUNT_STATUS_REASON_UNSPECIFIED": 0, "ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT": 1, "ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT": 2, "ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE": 3, + "ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE": 4, + "ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED": 5, } ) @@ -2416,8 +2432,10 @@ type IsAccountStatusValidResponse struct { ShouldPoll bool `protobuf:"varint,3,opt,name=should_poll,json=shouldPoll,proto3" json:"should_poll,omitempty"` // A count of the currently used records for the current billing period. // This may go over the allowed record count depending on when the record count is polled by the metric system. + // @deprecated UsedRecordCount uint64 `protobuf:"varint,4,opt,name=used_record_count,json=usedRecordCount,proto3" json:"used_record_count,omitempty"` // The allowed record count. It will be null if there is no limit. + // @deprecated AllowedRecordCount *uint64 `protobuf:"varint,5,opt,name=allowed_record_count,json=allowedRecordCount,proto3,oneof" json:"allowed_record_count,omitempty"` // The current status of the account. Default is valid. AccountStatus AccountStatus `protobuf:"varint,6,opt,name=account_status,json=accountStatus,proto3,enum=mgmt.v1alpha1.AccountStatus" json:"account_status,omitempty"` @@ -3254,217 +3272,226 @@ var file_mgmt_v1alpha1_user_account_proto_rawDesc = []byte{ 0x45, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x54, 0x45, - 0x52, 0x50, 0x52, 0x49, 0x53, 0x45, 0x10, 0x03, 0x2a, 0x66, 0x0a, 0x0d, 0x42, 0x69, 0x6c, 0x6c, - 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x49, 0x4c, - 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x49, 0x4c, - 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x54, 0x49, - 0x56, 0x45, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, - 0x2a, 0xb9, 0x01, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x25, 0x0a, 0x21, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x43, 0x43, - 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x43, 0x45, - 0x45, 0x44, 0x53, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x4d, 0x49, - 0x54, 0x10, 0x01, 0x12, 0x2a, 0x0a, 0x26, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x45, 0x44, 0x5f, - 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x02, 0x12, - 0x2b, 0x0a, 0x27, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x45, 0x58, 0x50, - 0x49, 0x52, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x03, 0x32, 0xa0, 0x16, 0x0a, - 0x12, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, - 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x4a, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x6d, 0x67, 0x6d, - 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x25, - 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, + 0x52, 0x50, 0x52, 0x49, 0x53, 0x45, 0x10, 0x03, 0x2a, 0xa9, 0x01, 0x0a, 0x0d, 0x42, 0x69, 0x6c, + 0x6c, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x49, + 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x49, + 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x56, 0x45, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, 0x47, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, + 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x54, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, + 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x42, 0x49, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, + 0x45, 0x44, 0x10, 0x04, 0x2a, 0x8c, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x21, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, + 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x28, 0x0a, + 0x24, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x53, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x45, 0x44, 0x5f, + 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x01, 0x12, 0x2a, 0x0a, 0x26, 0x41, 0x43, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, + 0x54, 0x45, 0x44, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, + 0x54, 0x10, 0x02, 0x12, 0x2b, 0x0a, 0x27, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49, 0x4e, + 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x03, + 0x12, 0x27, 0x0a, 0x23, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x49, 0x41, 0x4c, + 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x04, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x43, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x4f, + 0x55, 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, + 0x44, 0x10, 0x05, 0x32, 0xa0, 0x16, 0x0a, 0x12, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x12, 0x1d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x6b, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, - 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x29, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x89, 0x01, 0x0a, - 0x1c, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, - 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x32, 0x2e, - 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, - 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x33, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, - 0x6c, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x2e, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, + 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, + 0x61, 0x6c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x89, 0x01, 0x0a, 0x1c, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, + 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x32, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x50, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x68, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x61, - 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x49, 0x73, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62, 0x0a, 0x0f, 0x49, 0x73, 0x55, + 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x25, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x55, - 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, + 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, + 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, - 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, - 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, + 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x67, 0x6d, 0x74, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7d, 0x0a, 0x18, + 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, + 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, - 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, - 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x2b, 0x2e, - 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x67, 0x6d, - 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, - 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x17, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x17, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x55, 0x73, 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, - 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, - 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x74, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x6d, 0x67, - 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, - 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x17, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x65, - 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x12, - 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, - 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x15, 0x47, + 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x12, 0x2b, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x7a, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x67, + 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, + 0x17, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, + 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x54, 0x6f, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x15, 0x47, 0x65, 0x74, + 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, + 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, + 0x76, 0x69, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x7a, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x6d, 0x67, 0x6d, + 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x17, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x74, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x83, 0x01, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x65, 0x61, + 0x6d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x54, 0x65, 0x61, 0x6d, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x2a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x67, + 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x83, 0x01, + 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, + 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x83, 0x01, 0x0a, 0x1a, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x83, 0x01, 0x0a, - 0x1a, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x2e, 0x6d, 0x67, - 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, - 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, - 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x68, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x69, 0x67, 0x12, 0x30, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x6e, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, + 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x10, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, + 0x90, 0x02, 0x01, 0x12, 0x74, 0x0a, 0x14, 0x49, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x2a, 0x2e, 0x6d, 0x67, + 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x20, 0x47, 0x65, + 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x74, 0x0a, 0x14, - 0x49, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x12, 0x2a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2b, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x49, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, - 0x02, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, - 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x37, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, - 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x8f, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, - 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, - 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, - 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x69, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x12, - 0x47, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x73, 0x12, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, - 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x71, 0x0a, 0x14, - 0x53, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x4d, - 0x65, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2b, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x53, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x65, 0x72, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0xcc, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x75, 0x63, 0x6c, 0x65, 0x75, 0x73, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x2f, 0x6e, 0x65, 0x6f, 0x73, 0x79, 0x6e, 0x63, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6d, - 0x67, 0x6d, 0x74, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x58, - 0x58, 0xaa, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0xca, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0xe2, 0x02, 0x19, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, - 0x4d, 0x67, 0x6d, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x8f, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, + 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x6d, 0x67, 0x6d, + 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x72, 0x74, + 0x61, 0x6c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x69, 0x6c, + 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, + 0x90, 0x02, 0x01, 0x12, 0x71, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x2e, 0x6d, 0x67, + 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, + 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x42, 0x69, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcc, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, + 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x55, 0x73, + 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x75, 0x63, + 0x6c, 0x65, 0x75, 0x73, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6e, 0x65, 0x6f, 0x73, 0x79, 0x6e, + 0x63, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x67, 0x6d, 0x74, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x58, 0x58, 0xaa, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x2e, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x5c, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x19, 0x4d, 0x67, 0x6d, 0x74, 0x5c, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x67, 0x6d, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/backend/gen/openapi/mgmt/v1alpha1/user_account.openapi.yaml b/backend/gen/openapi/mgmt/v1alpha1/user_account.openapi.yaml index e3f0abaa0d..a7617eca94 100644 --- a/backend/gen/openapi/mgmt/v1alpha1/user_account.openapi.yaml +++ b/backend/gen/openapi/mgmt/v1alpha1/user_account.openapi.yaml @@ -860,6 +860,8 @@ components: - ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT - ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT - ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE + - ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE + - ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED mgmt.v1alpha1.BillingStatus: type: string title: BillingStatus @@ -867,6 +869,8 @@ components: - BILLING_STATUS_UNSPECIFIED - BILLING_STATUS_ACTIVE - BILLING_STATUS_EXPIRED + - BILLING_STATUS_TRIAL_ACTIVE + - BILLING_STATUS_TRIAL_EXPIRED mgmt.v1alpha1.UserAccountType: type: string title: UserAccountType @@ -1503,12 +1507,15 @@ components: description: |- A count of the currently used records for the current billing period. This may go over the allowed record count depending on when the record count is polled by the metric system. + @deprecated allowedRecordCount: oneOf: - type: string - type: number title: allowed_record_count - description: The allowed record count. It will be null if there is no limit. + description: |- + The allowed record count. It will be null if there is no limit. + @deprecated accountStatus: allOf: - title: account_status diff --git a/backend/internal/cmds/mgmt/serve/connect/cmd.go b/backend/internal/cmds/mgmt/serve/connect/cmd.go index 98a9dd38ea..d740d01da4 100644 --- a/backend/internal/cmds/mgmt/serve/connect/cmd.go +++ b/backend/internal/cmds/mgmt/serve/connect/cmd.go @@ -411,7 +411,7 @@ func serve(ctx context.Context) error { IsAuthEnabled: isAuthEnabled, IsNeosyncCloud: getIsNeosyncCloud(), DefaultMaxAllowedRecords: getDefaultMaxAllowedRecords(), - }, db, tfwfmgr, authclient, authadminclient, promv1.NewAPI(promclient), billingClient) + }, db, tfwfmgr, authclient, authadminclient, billingClient) api.Handle( mgmtv1alpha1connect.NewUserAccountServiceHandler( useraccountService, diff --git a/backend/protos/mgmt/v1alpha1/user_account.proto b/backend/protos/mgmt/v1alpha1/user_account.proto index 6ace3b34e5..20dd0529ff 100644 --- a/backend/protos/mgmt/v1alpha1/user_account.proto +++ b/backend/protos/mgmt/v1alpha1/user_account.proto @@ -208,6 +208,10 @@ enum BillingStatus { BILLING_STATUS_ACTIVE = 1; // If the system could not find any active subscriptions BILLING_STATUS_EXPIRED = 2; + // The account does not have an active subscription and is in a valid trial period + BILLING_STATUS_TRIAL_ACTIVE = 3; + // The account does not have an active subscription and the trial period has ended + BILLING_STATUS_TRIAL_EXPIRED = 4; } message GetAccountStatusResponse { @@ -235,8 +239,10 @@ message IsAccountStatusValidResponse { bool should_poll = 3; // A count of the currently used records for the current billing period. // This may go over the allowed record count depending on when the record count is polled by the metric system. + // @deprecated uint64 used_record_count = 4; // The allowed record count. It will be null if there is no limit. + // @deprecated optional uint64 allowed_record_count = 5; // The current status of the account. Default is valid. AccountStatus account_status = 6; @@ -245,12 +251,16 @@ message IsAccountStatusValidResponse { enum AccountStatus { // Default value, should be used when no reason is specified ACCOUNT_STATUS_REASON_UNSPECIFIED = 0; - // Current usage exceeds allowed limit + // @deprecated - Current usage exceeds allowed limit ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT = 1; - // Adding requested records exceeds the allowed limit + // @deprecated - Adding requested records exceeds the allowed limit ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT = 2; // Account is currently in an expired state ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE = 3; + // The account is currently in an active trial period + ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE = 4; + // The account is past the active trial period + ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED = 5; } message GetAccountBillingCheckoutSessionRequest { diff --git a/backend/services/mgmt/v1alpha1/integration_tests/integration_test.go b/backend/services/mgmt/v1alpha1/integration_tests/integration_test.go index 7ec794df50..3b40117809 100644 --- a/backend/services/mgmt/v1alpha1/integration_tests/integration_test.go +++ b/backend/services/mgmt/v1alpha1/integration_tests/integration_test.go @@ -163,7 +163,6 @@ func (s *IntegrationTestSuite) SetupSuite() { s.mocks.temporalClientManager, s.mocks.authclient, s.mocks.authmanagerclient, - s.mocks.prometheusclient, nil, ) @@ -173,7 +172,6 @@ func (s *IntegrationTestSuite) SetupSuite() { s.mocks.temporalClientManager, s.mocks.authclient, s.mocks.authmanagerclient, - s.mocks.prometheusclient, nil, ) @@ -183,7 +181,6 @@ func (s *IntegrationTestSuite) SetupSuite() { s.mocks.temporalClientManager, s.mocks.authclient, s.mocks.authmanagerclient, - s.mocks.prometheusclient, s.mocks.billingclient, ) neoCloudAuthdAnonymizeService := v1alpha_anonymizationservice.New( diff --git a/backend/services/mgmt/v1alpha1/integration_tests/integration_util_test.go b/backend/services/mgmt/v1alpha1/integration_tests/integration_util_test.go index b5bf0d092d..7fd0720b36 100644 --- a/backend/services/mgmt/v1alpha1/integration_tests/integration_util_test.go +++ b/backend/services/mgmt/v1alpha1/integration_tests/integration_util_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "testing" + "time" "connectrpc.com/connect" "github.com/jackc/pgx/v5/pgtype" @@ -43,18 +44,18 @@ func requireConnectError(t testing.TB, err error, expectedCode connect.Code) { require.Equal(t, expectedCode, connectErr.Code(), fmt.Sprintf("%d: %s", connectErr.Code(), connectErr.Message())) } -func (s *IntegrationTestSuite) setMaxAllowedRecords( +func (s *IntegrationTestSuite) setAccountCreatedAt( ctx context.Context, accountId string, - maxAllowed uint64, //nolint:unparam // want to leave it here to allow other options in the future + createdAt time.Time, ) error { accountUuid, err := neosyncdb.ToUuid(accountId) if err != nil { return err } - _, err = s.neosyncQuerier.SetAccountMaxAllowedRecords(ctx, s.pgpool, db_queries.SetAccountMaxAllowedRecordsParams{ - MaxAllowedRecords: pgtype.Int8{Int64: int64(maxAllowed), Valid: true}, - AccountId: accountUuid, + _, err = s.neosyncQuerier.SetAccountCreatedAt(ctx, s.pgpool, db_queries.SetAccountCreatedAtParams{ + CreatedAt: pgtype.Timestamp{Time: createdAt, Valid: true}, + AccountId: accountUuid, }) return err } diff --git a/backend/services/mgmt/v1alpha1/integration_tests/user-account-service_integration_test.go b/backend/services/mgmt/v1alpha1/integration_tests/user-account-service_integration_test.go index 532b373471..bfc52a801e 100644 --- a/backend/services/mgmt/v1alpha1/integration_tests/user-account-service_integration_test.go +++ b/backend/services/mgmt/v1alpha1/integration_tests/user-account-service_integration_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "testing" + "time" "connectrpc.com/connect" "github.com/google/uuid" @@ -13,9 +14,6 @@ import ( "github.com/nucleuscloud/neosync/backend/internal/authmgmt" nucleuserrors "github.com/nucleuscloud/neosync/backend/internal/errors" pg_models "github.com/nucleuscloud/neosync/backend/sql/postgresql/models" - "github.com/nucleuscloud/neosync/worker/pkg/workflows/datasync/activities/shared" - promv1 "github.com/prometheus/client_golang/api/prometheus/v1" - "github.com/prometheus/common/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -377,38 +375,12 @@ func (s *IntegrationTestSuite) Test_UserAccountService_GetAccountStatus_NeosyncC s.setUser(s.ctx, userclient) accountId := s.createPersonalAccount(s.ctx, userclient) - err := s.setMaxAllowedRecords(s.ctx, accountId, 100) - require.NoError(s.T(), err) - - s.mocks.prometheusclient.On("Query", mock.Anything, mock.AnythingOfType("string"), mock.AnythingOfType("time.Time")). - Once(). - Return(model.Vector{{ - Value: 2, - Timestamp: 0, - }}, promv1.Warnings{}, nil) - resp, err := userclient.GetAccountStatus(s.ctx, connect.NewRequest(&mgmtv1alpha1.GetAccountStatusRequest{ AccountId: accountId, })) requireNoErrResp(s.T(), resp, err) - require.Equal(s.T(), resp.Msg.GetUsedRecordCount(), uint64(2)) - require.NotNil(s.T(), resp.Msg.AllowedRecordCount) - require.Equal(s.T(), uint64(100), resp.Msg.GetAllowedRecordCount()) -} - -func (s *IntegrationTestSuite) Test_UserAccountService_GetAccountStatus_NeosyncCloud_Personal_Unlimited() { - userclient := s.neosyncCloudClients.getUserClient(testAuthUserId) - s.setUser(s.ctx, userclient) - accountId := s.createPersonalAccount(s.ctx, userclient) - - resp, err := userclient.GetAccountStatus(s.ctx, connect.NewRequest(&mgmtv1alpha1.GetAccountStatusRequest{ - AccountId: accountId, - })) - requireNoErrResp(s.T(), resp, err) - - require.Equal(s.T(), resp.Msg.GetUsedRecordCount(), uint64(0)) - require.Nil(s.T(), resp.Msg.AllowedRecordCount) + require.Equal(s.T(), mgmtv1alpha1.BillingStatus_BILLING_STATUS_TRIAL_ACTIVE, resp.Msg.GetSubscriptionStatus()) } type testSubscriptionIter struct { @@ -434,7 +406,7 @@ func (s *IntegrationTestSuite) Test_UserAccountService_GetAccountStatus_NeosyncC t := s.T() - t.Run("active sub", func(t *testing.T) { + t.Run("active_sub", func(t *testing.T) { custId := "cust_id1" accountId := s.createBilledTeamAccount(s.ctx, userclient, "test-team", custId) s.mocks.billingclient.On("GetSubscriptions", custId).Once().Return(&testSubscriptionIter{subscriptions: []*stripe.Subscription{ @@ -450,9 +422,12 @@ func (s *IntegrationTestSuite) Test_UserAccountService_GetAccountStatus_NeosyncC require.Equal(s.T(), mgmtv1alpha1.BillingStatus_BILLING_STATUS_ACTIVE, resp.Msg.GetSubscriptionStatus()) }) - t.Run("no active subscriptions", func(t *testing.T) { + t.Run("no_active_subscriptions", func(t *testing.T) { custId := "cust_id2" accountId := s.createBilledTeamAccount(s.ctx, userclient, "test-team1", custId) + err := s.setAccountCreatedAt(s.ctx, accountId, time.Now().UTC().Add(-30*24*time.Hour)) + assert.NoError(s.T(), err) + s.mocks.billingclient.On("GetSubscriptions", custId).Once().Return(&testSubscriptionIter{subscriptions: []*stripe.Subscription{ {Status: stripe.SubscriptionStatusIncompleteExpired}, {Status: stripe.SubscriptionStatusIncompleteExpired}, @@ -475,8 +450,7 @@ func (s *IntegrationTestSuite) Test_UserAccountService_GetAccountStatus_OSS_Pers })) requireNoErrResp(s.T(), resp, err) - require.Equal(s.T(), resp.Msg.GetUsedRecordCount(), uint64(0)) - require.Nil(s.T(), resp.Msg.AllowedRecordCount) + require.Equal(s.T(), mgmtv1alpha1.BillingStatus_BILLING_STATUS_UNSPECIFIED, resp.Msg.GetSubscriptionStatus()) } func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_NeosyncCloud_Personal() { @@ -484,16 +458,6 @@ func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_Neos s.setUser(s.ctx, userclient) accountId := s.createPersonalAccount(s.ctx, userclient) - err := s.setMaxAllowedRecords(s.ctx, accountId, 100) - require.NoError(s.T(), err) - - s.mocks.prometheusclient.On("Query", mock.Anything, mock.AnythingOfType("string"), mock.AnythingOfType("time.Time")). - Once(). - Return(model.Vector{{ - Value: 2, - Timestamp: 0, - }}, promv1.Warnings{}, nil) - resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ AccountId: accountId, })) @@ -501,80 +465,7 @@ func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_Neos require.True(s.T(), resp.Msg.GetIsValid()) require.Empty(s.T(), resp.Msg.GetReason()) - require.Equal(s.T(), mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REASON_UNSPECIFIED, resp.Msg.GetAccountStatus()) - require.True(s.T(), resp.Msg.GetShouldPoll()) -} - -func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_NeosyncCloud_Personal_Overprovisioned() { - userclient := s.neosyncCloudClients.getUserClient(testAuthUserId) - s.setUser(s.ctx, userclient) - accountId := s.createPersonalAccount(s.ctx, userclient) - - err := s.setMaxAllowedRecords(s.ctx, accountId, 100) - require.NoError(s.T(), err) - - s.mocks.prometheusclient.On("Query", mock.Anything, mock.AnythingOfType("string"), mock.AnythingOfType("time.Time")). - Once(). - Return(model.Vector{{ - Value: 100, - Timestamp: 0, - }}, promv1.Warnings{}, nil) - - resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ - AccountId: accountId, - })) - requireNoErrResp(s.T(), resp, err) - - require.False(s.T(), resp.Msg.GetIsValid()) - require.NotEmpty(s.T(), resp.Msg.GetReason()) - require.Equal(s.T(), mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT, resp.Msg.GetAccountStatus()) - require.Equal(s.T(), uint64(100), resp.Msg.GetUsedRecordCount()) - require.Equal(s.T(), uint64(100), resp.Msg.GetAllowedRecordCount()) - require.False(s.T(), resp.Msg.GetShouldPoll()) -} - -func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_NeosyncCloud_Personal_RequestedRecords() { - userclient := s.neosyncCloudClients.getUserClient(testAuthUserId) - s.setUser(s.ctx, userclient) - accountId := s.createPersonalAccount(s.ctx, userclient) - - err := s.setMaxAllowedRecords(s.ctx, accountId, 100) - require.NoError(s.T(), err) - - s.mocks.prometheusclient.On("Query", mock.Anything, mock.AnythingOfType("string"), mock.AnythingOfType("time.Time")). - Twice(). - Return(model.Vector{{ - Value: 50, - Timestamp: 0, - }}, promv1.Warnings{}, nil) - - t := s.T() - t.Run("over the limit", func(t *testing.T) { - resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ - AccountId: accountId, - RequestedRecordCount: shared.Ptr(uint64(51)), // puts the user one over the limit - })) - requireNoErrResp(s.T(), resp, err) - - require.False(s.T(), resp.Msg.GetIsValid()) - require.NotEmpty(s.T(), resp.Msg.GetReason()) - require.Equal(s.T(), mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT, resp.Msg.GetAccountStatus()) - require.Equal(s.T(), uint64(50), resp.Msg.GetUsedRecordCount()) - require.Equal(s.T(), uint64(100), resp.Msg.GetAllowedRecordCount()) - require.False(s.T(), resp.Msg.GetShouldPoll()) - }) - t.Run("under the limit", func(t *testing.T) { - resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ - AccountId: accountId, - RequestedRecordCount: shared.Ptr(uint64(50)), - })) - requireNoErrResp(s.T(), resp, err) - - require.True(s.T(), resp.Msg.GetIsValid()) - require.Empty(s.T(), resp.Msg.GetReason()) - require.Equal(s.T(), mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REASON_UNSPECIFIED, resp.Msg.GetAccountStatus()) - require.True(s.T(), resp.Msg.GetShouldPoll()) - }) + require.Equal(s.T(), mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE, resp.Msg.GetAccountStatus()) } func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_NeosyncCloud_Billed() { @@ -591,16 +482,18 @@ func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_Neos resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ AccountId: accountId, })) - requireNoErrResp(s.T(), resp, err) + requireNoErrResp(t, resp, err) - assert.True(s.T(), resp.Msg.GetIsValid()) - assert.Empty(s.T(), resp.Msg.GetReason()) - require.Equal(s.T(), mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REASON_UNSPECIFIED, resp.Msg.GetAccountStatus()) - require.False(s.T(), resp.Msg.GetShouldPoll()) + assert.True(t, resp.Msg.GetIsValid()) + assert.Empty(t, resp.Msg.GetReason()) + require.Equal(t, mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REASON_UNSPECIFIED, resp.Msg.GetAccountStatus()) + require.False(t, resp.Msg.GetShouldPoll()) }) - t.Run("inactive", func(t *testing.T) { + t.Run("no_active_subs", func(t *testing.T) { custId := "cust_id2" accountId := s.createBilledTeamAccount(s.ctx, userclient, "test2", custId) + err := s.setAccountCreatedAt(s.ctx, accountId, time.Now().UTC().Add(-30*24*time.Hour)) + assert.NoError(t, err) s.mocks.billingclient.On("GetSubscriptions", custId).Once().Return(&testSubscriptionIter{subscriptions: []*stripe.Subscription{ {Status: stripe.SubscriptionStatusIncompleteExpired}, }}, nil) @@ -608,12 +501,59 @@ func (s *IntegrationTestSuite) Test_UserAccountService_IsAccountStatusValid_Neos resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ AccountId: accountId, })) - requireNoErrResp(s.T(), resp, err) + requireNoErrResp(t, resp, err) - assert.False(s.T(), resp.Msg.GetIsValid()) - assert.NotEmpty(s.T(), resp.Msg.GetReason()) - require.Equal(s.T(), mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE, resp.Msg.GetAccountStatus()) - require.False(s.T(), resp.Msg.GetShouldPoll()) + assert.False(t, resp.Msg.GetIsValid()) + assert.NotEmpty(t, resp.Msg.GetReason()) + assert.Equal(t, mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE, resp.Msg.GetAccountStatus()) + assert.False(t, resp.Msg.GetShouldPoll()) + }) + t.Run("no_subs_active_trial", func(t *testing.T) { + custId := "cust_id3" + accountId := s.createBilledTeamAccount(s.ctx, userclient, "test3", custId) + s.mocks.billingclient.On("GetSubscriptions", custId).Once().Return(&testSubscriptionIter{subscriptions: []*stripe.Subscription{}}, nil) + + resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ + AccountId: accountId, + })) + requireNoErrResp(t, resp, err) + assert.True(t, resp.Msg.GetIsValid()) + assert.Empty(t, resp.Msg.GetReason()) + assert.Equal(t, mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE, resp.Msg.GetAccountStatus()) + assert.False(t, resp.Msg.GetShouldPoll()) + }) + t.Run("no_subs_expired_trial", func(t *testing.T) { + custId := "cust_id4" + accountId := s.createBilledTeamAccount(s.ctx, userclient, "test4", custId) + err := s.setAccountCreatedAt(s.ctx, accountId, time.Now().UTC().Add(-30*24*time.Hour)) + assert.NoError(t, err) + s.mocks.billingclient.On("GetSubscriptions", custId).Once().Return(&testSubscriptionIter{subscriptions: []*stripe.Subscription{}}, nil) + + resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ + AccountId: accountId, + })) + requireNoErrResp(t, resp, err) + + assert.False(t, resp.Msg.GetIsValid()) + assert.NotEmpty(t, resp.Msg.GetReason()) + assert.Equal(t, mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED, resp.Msg.GetAccountStatus()) + assert.False(t, resp.Msg.GetShouldPoll()) + }) + t.Run("no_active_subs_active_trial", func(t *testing.T) { + custId := "cust_id5" + accountId := s.createBilledTeamAccount(s.ctx, userclient, "test5", custId) + s.mocks.billingclient.On("GetSubscriptions", custId).Once().Return(&testSubscriptionIter{subscriptions: []*stripe.Subscription{ + {Status: stripe.SubscriptionStatusIncompleteExpired}, + }}, nil) + + resp, err := userclient.IsAccountStatusValid(s.ctx, connect.NewRequest(&mgmtv1alpha1.IsAccountStatusValidRequest{ + AccountId: accountId, + })) + requireNoErrResp(t, resp, err) + assert.True(t, resp.Msg.GetIsValid()) + assert.Empty(t, resp.Msg.GetReason()) + assert.Equal(t, mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE, resp.Msg.GetAccountStatus()) + assert.False(t, resp.Msg.GetShouldPoll()) }) } diff --git a/backend/services/mgmt/v1alpha1/user-account-service/billing.go b/backend/services/mgmt/v1alpha1/user-account-service/billing.go index 34d9214481..0d7fcc4bbb 100644 --- a/backend/services/mgmt/v1alpha1/user-account-service/billing.go +++ b/backend/services/mgmt/v1alpha1/user-account-service/billing.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "log/slog" "math" "strings" "time" @@ -17,11 +16,15 @@ import ( "github.com/nucleuscloud/neosync/backend/internal/dtomaps" nucleuserrors "github.com/nucleuscloud/neosync/backend/internal/errors" "github.com/nucleuscloud/neosync/backend/internal/neosyncdb" - "github.com/nucleuscloud/neosync/backend/pkg/metrics" "github.com/nucleuscloud/neosync/internal/billing" "github.com/stripe/stripe-go/v79" ) +var ( + // 14 days duration + trialDuration = 14 * 24 * time.Hour +) + func (s *Service) GetAccountStatus( ctx context.Context, req *connect.Request[mgmtv1alpha1.GetAccountStatusRequest], @@ -33,70 +36,93 @@ func (s *Service) GetAccountStatus( return nil, err } logger = logger.With("accountId", accountId) + if !s.cfg.IsNeosyncCloud || s.billingclient == nil { + return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{}), nil + } account, err := s.db.Q.GetAccount(ctx, s.db.Db, *accountId) if err != nil { return nil, fmt.Errorf("unable to retrieve account: %w", err) } - if s.cfg.IsNeosyncCloud { - if account.AccountType == int16(neosyncdb.AccountType_Personal) { - allowedRecordCount := getAllowedRecordCount(account.MaxAllowedRecords) - var usedRecordCount uint64 - if allowedRecordCount != nil && *allowedRecordCount > 0 { - count, err := s.getUsedRecordCountForMonth(ctx, req.Msg.GetAccountId(), logger) - if err != nil { - return nil, fmt.Errorf("unable to retrieve used record count for month: %w", err) - } - usedRecordCount = count - } - return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ - UsedRecordCount: usedRecordCount, - AllowedRecordCount: allowedRecordCount, - SubscriptionStatus: mgmtv1alpha1.BillingStatus_BILLING_STATUS_UNSPECIFIED, - }), nil - } else if s.billingclient != nil { - if !account.StripeCustomerID.Valid { - logger.Warn("stripe is enabled but team account does not have stripe customer id") - return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ - SubscriptionStatus: mgmtv1alpha1.BillingStatus_BILLING_STATUS_UNSPECIFIED, - }), nil - } - logger.Debug("attempting to find active stripe subscription") - subscription, err := s.findActiveStripeSubscription(account.StripeCustomerID.String) - if err != nil { - return nil, err - } - if subscription == nil { - return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ - SubscriptionStatus: mgmtv1alpha1.BillingStatus_BILLING_STATUS_EXPIRED, - }), nil - } - return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ - SubscriptionStatus: mgmtv1alpha1.BillingStatus_BILLING_STATUS_ACTIVE, - }), nil - } - return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{}), nil + trialStatus := getTrialStatus(account.CreatedAt) + + if account.AccountType == int16(neosyncdb.AccountType_Personal) { + return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ + SubscriptionStatus: trialStatus, + }), nil + } + if !account.StripeCustomerID.Valid { + logger.Warn("stripe is enabled but team account does not have stripe customer id") + return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ + SubscriptionStatus: trialStatus, + }), nil + } + + logger.Debug("attempting to find active stripe subscription") + subscriptions, err := s.getStripeSubscriptions(account.StripeCustomerID.String) + if err != nil { + return nil, err + } + logger.Debug(fmt.Sprintf("found %d stripe subscriptions for account", len(subscriptions))) + _, hasActiveSub := findActiveStripeSubscription(subscriptions) + if hasActiveSub { + logger.Debug("account has active billing subscription") + return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ + SubscriptionStatus: mgmtv1alpha1.BillingStatus_BILLING_STATUS_ACTIVE, + }), nil + } + if len(subscriptions) == 0 { + logger.Debug("account has no subscriptions, returning trial status") + return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ + SubscriptionStatus: trialStatus, + }), nil } - return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{}), nil + if trialStatus == mgmtv1alpha1.BillingStatus_BILLING_STATUS_TRIAL_ACTIVE { + logger.Debug("account has no active subscriptions but trial is still active") + return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ + SubscriptionStatus: trialStatus, + }), nil + } + logger.Debug("account has no active subscriptions and trial is expired") + return connect.NewResponse(&mgmtv1alpha1.GetAccountStatusResponse{ + SubscriptionStatus: mgmtv1alpha1.BillingStatus_BILLING_STATUS_EXPIRED, + }), nil } -func (s *Service) findActiveStripeSubscription(customerId string) (*stripe.Subscription, error) { - subIter := s.billingclient.GetSubscriptions(customerId) - var validSubscription *stripe.Subscription +func getTrialStatus(ts pgtype.Timestamp) mgmtv1alpha1.BillingStatus { + if !ts.Valid || ts.Time.IsZero() { + return mgmtv1alpha1.BillingStatus_BILLING_STATUS_TRIAL_EXPIRED + } + trialEndTime := ts.Time.Add(trialDuration) + trialActive := time.Now().UTC().Before(trialEndTime) + + if trialActive { + return mgmtv1alpha1.BillingStatus_BILLING_STATUS_TRIAL_ACTIVE + } + return mgmtv1alpha1.BillingStatus_BILLING_STATUS_TRIAL_EXPIRED +} + +func (s *Service) getStripeSubscriptions(customerId string) ([]*stripe.Subscription, error) { + subIter := s.billingclient.GetSubscriptions(customerId) + output := []*stripe.Subscription{} for subIter.Next() { - subscription := subIter.Subscription() - if isSubscriptionActive(subscription.Status) { - validSubscription = subscription - break - } + output = append(output, subIter.Subscription()) } - // this could be bad, we may want to cache the stripe subscriptions to prevent any issues with stripe outages if subIter.Err() != nil { return nil, fmt.Errorf("encountered error when retrieving stripe subscriptions: %w", subIter.Err()) } - return validSubscription, nil + return output, nil +} + +func findActiveStripeSubscription(subs []*stripe.Subscription) (*stripe.Subscription, bool) { + for _, sub := range subs { + if isSubscriptionActive(sub.Status) { + return sub, true + } + } + return nil, false } func isSubscriptionActive(status stripe.SubscriptionStatus) bool { @@ -120,22 +146,6 @@ func isSubscriptionActive(status stripe.SubscriptionStatus) bool { } } -func getAllowedRecordCount(maxAllowed pgtype.Int8) *uint64 { - if maxAllowed.Valid { - val := toUint64(maxAllowed.Int64) - return &val - } - return nil -} - -// Returns the int64 as a uint64, or if int64 is negative, returns 0 -func toUint64(val int64) uint64 { - if val >= 0 { - return uint64(val) - } - return 0 -} - func (s *Service) IsAccountStatusValid( ctx context.Context, req *connect.Request[mgmtv1alpha1.IsAccountStatusValidRequest], @@ -147,102 +157,36 @@ func (s *Service) IsAccountStatusValid( return nil, err } - if !s.cfg.IsNeosyncCloud { + if !s.cfg.IsNeosyncCloud || s.billingclient == nil { return connect.NewResponse(&mgmtv1alpha1.IsAccountStatusValidResponse{IsValid: true}), nil } - accountUuid, err := neosyncdb.ToUuid(req.Msg.GetAccountId()) - if err != nil { - return nil, err - } - - account, err := s.db.Q.GetAccount(ctx, s.db.Db, accountUuid) - if err != nil { - return nil, fmt.Errorf("unable to retrieve account: %w", err) - } - - if account.AccountType == int16(neosyncdb.AccountType_Personal) { - if accountStatusResp.Msg.AllowedRecordCount == nil { - return connect.NewResponse(&mgmtv1alpha1.IsAccountStatusValidResponse{IsValid: true}), nil - } - - currentUsed := accountStatusResp.Msg.GetUsedRecordCount() - allowed := accountStatusResp.Msg.GetAllowedRecordCount() - - if currentUsed >= allowed { - description := fmt.Sprintf("Current used record count (%d) exceeds the allowed limit (%d).", currentUsed, allowed) - return connect.NewResponse(&mgmtv1alpha1.IsAccountStatusValidResponse{ - IsValid: false, - Reason: &description, - AccountStatus: mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT, - UsedRecordCount: currentUsed, - AllowedRecordCount: &allowed, - }), nil - } - - if req.Msg.GetRequestedRecordCount() > 0 { - requested := req.Msg.GetRequestedRecordCount() - totalUsed := currentUsed + requested - if totalUsed > allowed { - description := fmt.Sprintf("Adding requested record count (%d) would exceed the allowed limit (%d). Current used: %d.", requested, allowed, currentUsed) - return connect.NewResponse(&mgmtv1alpha1.IsAccountStatusValidResponse{ - IsValid: false, - AccountStatus: mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT, - Reason: &description, - UsedRecordCount: currentUsed, - AllowedRecordCount: &allowed, - }), nil - } - } - - return connect.NewResponse(&mgmtv1alpha1.IsAccountStatusValidResponse{ - IsValid: true, - ShouldPoll: true, // Is active free account that is currently under their usage limit - }), nil - } - - billingStatus := accountStatusResp.Msg.GetSubscriptionStatus() + accountStatus := mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REASON_UNSPECIFIED + var description string + isValid := false - if s.billingclient == nil || billingStatus == mgmtv1alpha1.BillingStatus_BILLING_STATUS_ACTIVE { - return connect.NewResponse(&mgmtv1alpha1.IsAccountStatusValidResponse{IsValid: true}), nil + switch accountStatusResp.Msg.GetSubscriptionStatus() { + case mgmtv1alpha1.BillingStatus_BILLING_STATUS_EXPIRED: + accountStatus = mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE + description = "Account is currently in expired state, visit the billing page to activate your subscription." + case mgmtv1alpha1.BillingStatus_BILLING_STATUS_TRIAL_EXPIRED: + accountStatus = mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED + description = "The trial period has ended, visit the billing page to activate your subscription." + case mgmtv1alpha1.BillingStatus_BILLING_STATUS_TRIAL_ACTIVE: + accountStatus = mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE + isValid = true + case mgmtv1alpha1.BillingStatus_BILLING_STATUS_ACTIVE: + accountStatus = mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_REASON_UNSPECIFIED + isValid = true } - description := "Account is currently in expired state, visit the billing page to activate your subscription." return connect.NewResponse(&mgmtv1alpha1.IsAccountStatusValidResponse{ - IsValid: false, - AccountStatus: mgmtv1alpha1.AccountStatus_ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE, + IsValid: isValid, + AccountStatus: accountStatus, Reason: &description, }), nil } -func (s *Service) getUsedRecordCountForMonth( - ctx context.Context, - accountId string, - logger *slog.Logger, -) (uint64, error) { - today := time.Now().UTC() - promWindow := fmt.Sprintf("%dd", today.Day()) - - queryLabels := metrics.MetricLabels{ - metrics.NewNotEqLabel(metrics.IsUpdateConfigLabel, "true"), // we want to always exclude update configs - metrics.NewEqLabel(metrics.AccountIdLabel, accountId), - } - - query, err := metrics.GetPromQueryFromMetric(mgmtv1alpha1.RangedMetricName_RANGED_METRIC_NAME_INPUT_RECEIVED, queryLabels, promWindow) - if err != nil { - return 0, err - } - totalCount, err := metrics.GetTotalUsageFromProm(ctx, s.prometheusclient, query, today, logger) - if err != nil { - return 0, err - } - if totalCount < 0 { - logger.Warn("the response from prometheus returned a negative count when computing used records") - totalCount = 0 - } - return uint64(totalCount), nil -} - func (s *Service) GetAccountBillingCheckoutSession( ctx context.Context, req *connect.Request[mgmtv1alpha1.GetAccountBillingCheckoutSessionRequest], diff --git a/backend/services/mgmt/v1alpha1/user-account-service/billing_test.go b/backend/services/mgmt/v1alpha1/user-account-service/billing_test.go deleted file mode 100644 index aac8541647..0000000000 --- a/backend/services/mgmt/v1alpha1/user-account-service/billing_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package v1alpha1_useraccountservice - -import ( - "testing" - - "github.com/jackc/pgx/v5/pgtype" - "github.com/stretchr/testify/require" -) - -func Test_getAllowedRecordCount(t *testing.T) { - t.Run("valid", func(t *testing.T) { - actual := getAllowedRecordCount(pgtype.Int8{Int64: 1, Valid: true}) - require.NotNil(t, actual) - require.Equal(t, uint64(1), *actual) - }) - t.Run("invalid", func(t *testing.T) { - actual := getAllowedRecordCount(pgtype.Int8{}) - require.Nil(t, actual) - }) -} - -func Test_toUint64(t *testing.T) { - t.Run("positive", func(t *testing.T) { - actual := toUint64(1) - require.Equal(t, uint64(1), actual) - }) - t.Run("zero", func(t *testing.T) { - actual := toUint64(0) - require.Equal(t, uint64(0), actual) - }) - t.Run("negative", func(t *testing.T) { - actual := toUint64(-1) - require.Equal(t, uint64(0), actual) - }) -} diff --git a/backend/services/mgmt/v1alpha1/user-account-service/service.go b/backend/services/mgmt/v1alpha1/user-account-service/service.go index a696176f1e..e817440159 100644 --- a/backend/services/mgmt/v1alpha1/user-account-service/service.go +++ b/backend/services/mgmt/v1alpha1/user-account-service/service.go @@ -6,7 +6,6 @@ import ( "github.com/nucleuscloud/neosync/backend/internal/neosyncdb" clientmanager "github.com/nucleuscloud/neosync/backend/internal/temporal/client-manager" "github.com/nucleuscloud/neosync/internal/billing" - promv1 "github.com/prometheus/client_golang/api/prometheus/v1" ) type Service struct { @@ -15,7 +14,6 @@ type Service struct { temporalClientManager clientmanager.TemporalClientManagerClient authclient auth_client.Interface authadminclient authmgmt.Interface - prometheusclient promv1.API billingclient billing.Interface } @@ -31,7 +29,6 @@ func New( temporalClientManager clientmanager.TemporalClientManagerClient, authclient auth_client.Interface, authadminclient authmgmt.Interface, - prometheusclient promv1.API, billingclient billing.Interface, ) *Service { return &Service{ @@ -40,7 +37,6 @@ func New( temporalClientManager: temporalClientManager, authclient: authclient, authadminclient: authadminclient, - prometheusclient: prometheusclient, billingclient: billingclient, } } diff --git a/backend/sql/postgresql/queries/users.sql b/backend/sql/postgresql/queries/users.sql index 3aacd0e78c..5ac3c03265 100644 --- a/backend/sql/postgresql/queries/users.sql +++ b/backend/sql/postgresql/queries/users.sql @@ -202,9 +202,9 @@ SET onboarding_config = $1 WHERE id = sqlc.arg('accountId') RETURNING *; --- name: SetAccountMaxAllowedRecords :one +-- name: SetAccountCreatedAt :one UPDATE neosync_api.accounts -SET max_allowed_records = $1 +SET created_at = $1 WHERE id = sqlc.arg('accountId') RETURNING *; diff --git a/docs/protos/proto_docs.json b/docs/protos/proto_docs.json index 0daf348082..c669493069 100644 --- a/docs/protos/proto_docs.json +++ b/docs/protos/proto_docs.json @@ -14412,17 +14412,27 @@ { "name": "ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT", "number": "1", - "description": "Current usage exceeds allowed limit" + "description": "@deprecated - Current usage exceeds allowed limit" }, { "name": "ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT", "number": "2", - "description": "Adding requested records exceeds the allowed limit" + "description": "@deprecated - Adding requested records exceeds the allowed limit" }, { "name": "ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE", "number": "3", "description": "Account is currently in an expired state" + }, + { + "name": "ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE", + "number": "4", + "description": "The account is currently in an active trial period" + }, + { + "name": "ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED", + "number": "5", + "description": "The account is past the active trial period" } ] }, @@ -14446,6 +14456,16 @@ "name": "BILLING_STATUS_EXPIRED", "number": "2", "description": "If the system could not find any active subscriptions" + }, + { + "name": "BILLING_STATUS_TRIAL_ACTIVE", + "number": "3", + "description": "The account does not have an active subscription and is in a valid trial period" + }, + { + "name": "BILLING_STATUS_TRIAL_EXPIRED", + "number": "4", + "description": "The account does not have an active subscription and the trial period has ended" } ] }, @@ -15677,7 +15697,7 @@ }, { "name": "used_record_count", - "description": "A count of the currently used records for the current billing period.\nThis may go over the allowed record count depending on when the record count is polled by the metric system.", + "description": "A count of the currently used records for the current billing period.\nThis may go over the allowed record count depending on when the record count is polled by the metric system.\n@deprecated", "label": "", "type": "uint64", "longType": "uint64", @@ -15689,7 +15709,7 @@ }, { "name": "allowed_record_count", - "description": "The allowed record count. It will be null if there is no limit.", + "description": "The allowed record count. It will be null if there is no limit.\n@deprecated", "label": "optional", "type": "uint64", "longType": "uint64", diff --git a/frontend/apps/web/components/site-header/AccountStatusHandler.tsx b/frontend/apps/web/components/site-header/AccountStatusHandler.tsx index 69dde0101e..60447881f3 100644 --- a/frontend/apps/web/components/site-header/AccountStatusHandler.tsx +++ b/frontend/apps/web/components/site-header/AccountStatusHandler.tsx @@ -1,11 +1,9 @@ 'use client'; import { SystemAppConfig } from '@/app/config/app-config'; import { useQuery } from '@connectrpc/connect-query'; -import { UserAccountType } from '@neosync/sdk'; import { isAccountStatusValid } from '@neosync/sdk/connectquery'; import { useAccount } from '../providers/account-provider'; import { Skeleton } from '../ui/skeleton'; -import RecordsProgressBar from './RecordsProgressBar'; import Upgrade from './Upgrade'; interface Props { @@ -15,15 +13,11 @@ interface Props { export function AccountStatusHandler(props: Props) { const { systemAppConfig } = props; const { account } = useAccount(); - const showRecordsUsage = - systemAppConfig.isNeosyncCloud && - systemAppConfig.isStripeEnabled && - account?.type === UserAccountType.PERSONAL; const { data: data, isLoading } = useQuery( isAccountStatusValid, { accountId: account?.id }, - { enabled: !!account?.id && showRecordsUsage } + { enabled: !!account?.id } ); if (isLoading) { @@ -32,19 +26,9 @@ export function AccountStatusHandler(props: Props) { return (
- {showRecordsUsage && ( - - )} diff --git a/frontend/apps/web/components/site-header/RecordsProgressBar.tsx b/frontend/apps/web/components/site-header/RecordsProgressBar.tsx deleted file mode 100644 index 4b3a468be5..0000000000 --- a/frontend/apps/web/components/site-header/RecordsProgressBar.tsx +++ /dev/null @@ -1,87 +0,0 @@ -'use client'; -import { cn } from '@/libs/utils'; -import { GetMetricCountRequest } from '@neosync/sdk'; -import { useRouter } from 'next/navigation'; -import { ReactElement } from 'react'; -import { useAccount } from '../providers/account-provider'; -import { Button } from '../ui/button'; -import { Progress } from '../ui/progress'; - -interface Props { - count: number; - allowedRecords: number; - identifier: string; - idType: MetricsIdentifierCase; -} - -export default function RecordsProgressBar(props: Props): ReactElement { - const { count, allowedRecords, identifier, idType } = props; - const { account } = useAccount(); - - const router = useRouter(); - - const percentageUsed = (count / allowedRecords) * 100; - - return ( - - ); -} - -function getUsageLink( - basePath: string, - idtype: MetricsIdentifierCase, - identifier: string -): string | null { - if (idtype === 'accountId') { - return `${basePath}/settings/usage`; - } - if (idtype === 'jobId') { - return `${basePath}/jobs/${identifier}/usage`; - } - if (idtype === 'runId') { - return `${basePath}/runs/${identifier}/usage`; - } - return null; -} - -// helper fund to extract case types for metric identifiers -type ExtractCase = T extends { case: infer U } ? U : never; - -type MetricsIdentifierCase = NonNullable< - ExtractCase ->; - -export function formatNumber(num: number): string { - const browserLanguages = navigator.languages; - const formatter = new Intl.NumberFormat(browserLanguages, { - notation: 'compact', - compactDisplay: 'short', - maximumFractionDigits: 1, - }); - return formatter.format(num); -} diff --git a/frontend/apps/web/components/site-header/Upgrade.tsx b/frontend/apps/web/components/site-header/Upgrade.tsx index 720dcf0408..5d3780da07 100644 --- a/frontend/apps/web/components/site-header/Upgrade.tsx +++ b/frontend/apps/web/components/site-header/Upgrade.tsx @@ -1,13 +1,5 @@ 'use client'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; -import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from '@/components/ui/card'; import { AccountStatus, IsAccountStatusValidResponse } from '@neosync/sdk'; import { ArrowUpIcon, ExclamationTriangleIcon } from '@radix-ui/react-icons'; import { ReactElement, useState } from 'react'; @@ -24,28 +16,18 @@ import { DialogTitle, DialogTrigger, } from '../ui/dialog'; -import { Progress } from '../ui/progress'; -import { formatNumber } from './RecordsProgressBar'; import UpgradeButton from './UpgradeButton'; interface UpgradeProps { calendlyLink: string; isNeosyncCloud: boolean; - count: number; - allowedRecords: number; isAccountStatusValidResp: IsAccountStatusValidResponse | undefined; isLoading: boolean; } export default function Upgrade(props: UpgradeProps): ReactElement | null { - const { - calendlyLink, - isNeosyncCloud, - count, - allowedRecords, - isAccountStatusValidResp, - isLoading, - } = props; + const { calendlyLink, isNeosyncCloud, isAccountStatusValidResp, isLoading } = + props; const { account } = useAccount(); // always surface the upgrade button for non-neosynccloud users if (!isNeosyncCloud) { @@ -65,8 +47,6 @@ export default function Upgrade(props: UpgradeProps): ReactElement | null { upgradeHref={billingHref} accountStatus={isAccountStatusValidResp?.accountStatus} reason={isAccountStatusValidResp?.reason} - count={count} - allowedRecords={allowedRecords} /> ) : ( @@ -77,14 +57,12 @@ export default function Upgrade(props: UpgradeProps): ReactElement | null { interface UpgradeInfoDialogProps { upgradeHref: string; - count: number; - allowedRecords: number; accountStatus?: AccountStatus; reason?: string; } function UpgradeInfoDialog(props: UpgradeInfoDialogProps): ReactElement { - const { upgradeHref, count, allowedRecords, accountStatus, reason } = props; + const { upgradeHref, accountStatus, reason } = props; const [open, onOpenChange] = useState(false); return ( @@ -106,12 +84,7 @@ function UpgradeInfoDialog(props: UpgradeInfoDialogProps): ReactElement { {!!accountStatus && !!reason && (
- +
)} @@ -133,32 +106,12 @@ function UpgradeInfoDialog(props: UpgradeInfoDialogProps): ReactElement { interface IncludedReasonProps { accountStatus: AccountStatus; reason: string; - count: number; - allowedRecords: number; } function IncludedReason(props: IncludedReasonProps): ReactElement { - const { accountStatus, reason, count, allowedRecords } = props; + const { accountStatus, reason } = props; switch (accountStatus) { - case AccountStatus.EXCEEDS_ALLOWED_LIMIT: - return ( - - ); - case AccountStatus.REQUESTED_EXCEEDS_LIMIT: - return ( - - ); case AccountStatus.ACCOUNT_IN_EXPIRED_STATE: return ( @@ -167,6 +120,14 @@ function IncludedReason(props: IncludedReasonProps): ReactElement { {reason} ); + case AccountStatus.ACCOUNT_TRIAL_EXPIRED: + return ( + + + Account Trial is Expired + {reason} + + ); default: return ( @@ -180,35 +141,3 @@ function IncludedReason(props: IncludedReasonProps): ReactElement { ); } } - -interface UsageLimitExceededProps { - current: number; - allowed: number; - title: string; - reason: string; -} - -function UsageLimitExceeded(props: UsageLimitExceededProps) { - const { current, allowed, title, reason } = props; - return ( -
- - - {title} - - -
-
Current Usage
-
- {formatNumber(current)}/{formatNumber(allowed)} -
-
- -
- - {reason} - -
-
- ); -} diff --git a/frontend/apps/web/components/ui/progress.tsx b/frontend/apps/web/components/ui/progress.tsx deleted file mode 100644 index 3756981788..0000000000 --- a/frontend/apps/web/components/ui/progress.tsx +++ /dev/null @@ -1,28 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as ProgressPrimitive from '@radix-ui/react-progress'; - -import { cn } from '@/libs/utils'; - -const Progress = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, value, ...props }, ref) => ( - - - -)); -Progress.displayName = ProgressPrimitive.Root.displayName; - -export { Progress }; diff --git a/frontend/apps/web/package.json b/frontend/apps/web/package.json index 9517ae883d..8b57d10900 100644 --- a/frontend/apps/web/package.json +++ b/frontend/apps/web/package.json @@ -30,7 +30,6 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-popover": "^1.1.1", - "@radix-ui/react-progress": "^1.1.0", "@radix-ui/react-radio-group": "^1.2.0", "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-select": "^2.1.1", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 17b4ed2017..7302834589 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -36,7 +36,6 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-popover": "^1.1.1", - "@radix-ui/react-progress": "^1.1.0", "@radix-ui/react-radio-group": "^1.2.0", "@radix-ui/react-scroll-area": "^1.1.0", "@radix-ui/react-select": "^2.1.1", @@ -2711,29 +2710,6 @@ } } }, - "node_modules/@radix-ui/react-progress": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.0.tgz", - "integrity": "sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==", - "dependencies": { - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-radio-group": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.0.tgz", diff --git a/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts b/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts index 665d12aaa5..8eaf8ec110 100644 --- a/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts +++ b/frontend/packages/sdk/src/client/mgmt/v1alpha1/user_account_pb.ts @@ -61,12 +61,28 @@ export enum BillingStatus { * @generated from enum value: BILLING_STATUS_EXPIRED = 2; */ EXPIRED = 2, + + /** + * The account does not have an active subscription and is in a valid trial period + * + * @generated from enum value: BILLING_STATUS_TRIAL_ACTIVE = 3; + */ + TRIAL_ACTIVE = 3, + + /** + * The account does not have an active subscription and the trial period has ended + * + * @generated from enum value: BILLING_STATUS_TRIAL_EXPIRED = 4; + */ + TRIAL_EXPIRED = 4, } // Retrieve enum metadata with: proto3.getEnumType(BillingStatus) proto3.util.setEnumType(BillingStatus, "mgmt.v1alpha1.BillingStatus", [ { no: 0, name: "BILLING_STATUS_UNSPECIFIED" }, { no: 1, name: "BILLING_STATUS_ACTIVE" }, { no: 2, name: "BILLING_STATUS_EXPIRED" }, + { no: 3, name: "BILLING_STATUS_TRIAL_ACTIVE" }, + { no: 4, name: "BILLING_STATUS_TRIAL_EXPIRED" }, ]); /** @@ -81,14 +97,14 @@ export enum AccountStatus { REASON_UNSPECIFIED = 0, /** - * Current usage exceeds allowed limit + * @deprecated - Current usage exceeds allowed limit * * @generated from enum value: ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT = 1; */ EXCEEDS_ALLOWED_LIMIT = 1, /** - * Adding requested records exceeds the allowed limit + * @deprecated - Adding requested records exceeds the allowed limit * * @generated from enum value: ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT = 2; */ @@ -100,6 +116,20 @@ export enum AccountStatus { * @generated from enum value: ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE = 3; */ ACCOUNT_IN_EXPIRED_STATE = 3, + + /** + * The account is currently in an active trial period + * + * @generated from enum value: ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE = 4; + */ + ACCOUNT_TRIAL_ACTIVE = 4, + + /** + * The account is past the active trial period + * + * @generated from enum value: ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED = 5; + */ + ACCOUNT_TRIAL_EXPIRED = 5, } // Retrieve enum metadata with: proto3.getEnumType(AccountStatus) proto3.util.setEnumType(AccountStatus, "mgmt.v1alpha1.AccountStatus", [ @@ -107,6 +137,8 @@ proto3.util.setEnumType(AccountStatus, "mgmt.v1alpha1.AccountStatus", [ { no: 1, name: "ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT" }, { no: 2, name: "ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT" }, { no: 3, name: "ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE" }, + { no: 4, name: "ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE" }, + { no: 5, name: "ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED" }, ]); /** @@ -1979,6 +2011,7 @@ export class IsAccountStatusValidResponse extends Message\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\x8c\x01\n!SetAccountOnboardingConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12>\n\x06\x63onfig\x18\x02 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"d\n\"SetAccountOnboardingConfigResponse\x12>\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\xbb\x02\n\x17\x41\x63\x63ountOnboardingConfig\x12\x41\n\x1dhas_created_source_connection\x18\x01 \x01(\x08R\x1ahasCreatedSourceConnection\x12K\n\"has_created_destination_connection\x18\x02 \x01(\x08R\x1fhasCreatedDestinationConnection\x12&\n\x0fhas_created_job\x18\x03 \x01(\x08R\rhasCreatedJob\x12.\n\x13has_invited_members\x18\x04 \x01(\x08R\x11hasInvitedMembers\x12\x38\n\x18has_completed_onboarding\x18\x05 \x01(\x08R\x16hasCompletedOnboarding\"B\n\x17GetAccountStatusRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\xe5\x01\n\x18GetAccountStatusResponse\x12*\n\x11used_record_count\x18\x01 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x02 \x01(\x04H\x00R\x12\x61llowedRecordCount\x88\x01\x01\x12M\n\x13subscription_status\x18\x03 \x01(\x0e\x32\x1c.mgmt.v1alpha1.BillingStatusR\x12subscriptionStatusB\x17\n\x15_allowed_record_count\"\x9c\x01\n\x1bIsAccountStatusValidRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12\x39\n\x16requested_record_count\x18\x02 \x01(\x04H\x00R\x14requestedRecordCount\x88\x01\x01\x42\x19\n\x17_requested_record_count\"\xc3\x02\n\x1cIsAccountStatusValidResponse\x12\x19\n\x08is_valid\x18\x01 \x01(\x08R\x07isValid\x12\x1b\n\x06reason\x18\x02 \x01(\tH\x00R\x06reason\x88\x01\x01\x12\x1f\n\x0bshould_poll\x18\x03 \x01(\x08R\nshouldPoll\x12*\n\x11used_record_count\x18\x04 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x05 \x01(\x04H\x01R\x12\x61llowedRecordCount\x88\x01\x01\x12\x43\n\x0e\x61\x63\x63ount_status\x18\x06 \x01(\x0e\x32\x1c.mgmt.v1alpha1.AccountStatusR\raccountStatusB\t\n\x07_reasonB\x17\n\x15_allowed_record_count\"R\n\'GetAccountBillingCheckoutSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\\\n(GetAccountBillingCheckoutSessionResponse\x12\x30\n\x14\x63heckout_session_url\x18\x01 \x01(\tR\x12\x63heckoutSessionUrl\"P\n%GetAccountBillingPortalSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"V\n&GetAccountBillingPortalSessionResponse\x12,\n\x12portal_session_url\x18\x01 \x01(\tR\x10portalSessionUrl\"<\n\x19GetBillingAccountsRequest\x12\x1f\n\x0b\x61\x63\x63ount_ids\x18\x01 \x03(\tR\naccountIds\"T\n\x1aGetBillingAccountsResponse\x12\x36\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x08\x61\x63\x63ounts\"\xe2\x01\n\x1bSetBillingMeterEventRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12&\n\nevent_name\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\teventName\x12\x1d\n\x05value\x18\x03 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05value\x12\"\n\x08\x65vent_id\x18\x04 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x07\x65ventId\x12!\n\ttimestamp\x18\x05 \x01(\x04H\x00R\ttimestamp\x88\x01\x01\x42\x0c\n\n_timestamp\"\x1e\n\x1cSetBillingMeterEventResponse*\x92\x01\n\x0fUserAccountType\x12!\n\x1dUSER_ACCOUNT_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aUSER_ACCOUNT_TYPE_PERSONAL\x10\x01\x12\x1a\n\x16USER_ACCOUNT_TYPE_TEAM\x10\x02\x12 \n\x1cUSER_ACCOUNT_TYPE_ENTERPRISE\x10\x03*f\n\rBillingStatus\x12\x1e\n\x1a\x42ILLING_STATUS_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42ILLING_STATUS_ACTIVE\x10\x01\x12\x1a\n\x16\x42ILLING_STATUS_EXPIRED\x10\x02*\xb9\x01\n\rAccountStatus\x12%\n!ACCOUNT_STATUS_REASON_UNSPECIFIED\x10\x00\x12(\n$ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT\x10\x01\x12*\n&ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT\x10\x02\x12+\n\'ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE\x10\x03\x32\xa0\x16\n\x12UserAccountService\x12J\n\x07GetUser\x12\x1d.mgmt.v1alpha1.GetUserRequest\x1a\x1e.mgmt.v1alpha1.GetUserResponse\"\x00\x12J\n\x07SetUser\x12\x1d.mgmt.v1alpha1.SetUserRequest\x1a\x1e.mgmt.v1alpha1.SetUserResponse\"\x00\x12\x62\n\x0fGetUserAccounts\x12%.mgmt.v1alpha1.GetUserAccountsRequest\x1a&.mgmt.v1alpha1.GetUserAccountsResponse\"\x00\x12k\n\x12SetPersonalAccount\x12(.mgmt.v1alpha1.SetPersonalAccountRequest\x1a).mgmt.v1alpha1.SetPersonalAccountResponse\"\x00\x12\x89\x01\n\x1c\x43onvertPersonalToTeamAccount\x12\x32.mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest\x1a\x33.mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse\"\x00\x12h\n\x11\x43reateTeamAccount\x12\'.mgmt.v1alpha1.CreateTeamAccountRequest\x1a(.mgmt.v1alpha1.CreateTeamAccountResponse\"\x00\x12\x62\n\x0fIsUserInAccount\x12%.mgmt.v1alpha1.IsUserInAccountRequest\x1a&.mgmt.v1alpha1.IsUserInAccountResponse\"\x00\x12}\n\x18GetAccountTemporalConfig\x12..mgmt.v1alpha1.GetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.GetAccountTemporalConfigResponse\"\x00\x12}\n\x18SetAccountTemporalConfig\x12..mgmt.v1alpha1.SetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.SetAccountTemporalConfigResponse\"\x00\x12t\n\x15GetTeamAccountMembers\x12+.mgmt.v1alpha1.GetTeamAccountMembersRequest\x1a,.mgmt.v1alpha1.GetTeamAccountMembersResponse\"\x00\x12z\n\x17RemoveTeamAccountMember\x12-.mgmt.v1alpha1.RemoveTeamAccountMemberRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountMemberResponse\"\x00\x12z\n\x17InviteUserToTeamAccount\x12-.mgmt.v1alpha1.InviteUserToTeamAccountRequest\x1a..mgmt.v1alpha1.InviteUserToTeamAccountResponse\"\x00\x12t\n\x15GetTeamAccountInvites\x12+.mgmt.v1alpha1.GetTeamAccountInvitesRequest\x1a,.mgmt.v1alpha1.GetTeamAccountInvitesResponse\"\x00\x12z\n\x17RemoveTeamAccountInvite\x12-.mgmt.v1alpha1.RemoveTeamAccountInviteRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountInviteResponse\"\x00\x12z\n\x17\x41\x63\x63\x65ptTeamAccountInvite\x12-.mgmt.v1alpha1.AcceptTeamAccountInviteRequest\x1a..mgmt.v1alpha1.AcceptTeamAccountInviteResponse\"\x00\x12t\n\x14GetSystemInformation\x12*.mgmt.v1alpha1.GetSystemInformationRequest\x1a+.mgmt.v1alpha1.GetSystemInformationResponse\"\x03\x90\x02\x01\x12\x83\x01\n\x1aGetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.GetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.GetAccountOnboardingConfigResponse\"\x00\x12\x83\x01\n\x1aSetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.SetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.SetAccountOnboardingConfigResponse\"\x00\x12h\n\x10GetAccountStatus\x12&.mgmt.v1alpha1.GetAccountStatusRequest\x1a\'.mgmt.v1alpha1.GetAccountStatusResponse\"\x03\x90\x02\x01\x12t\n\x14IsAccountStatusValid\x12*.mgmt.v1alpha1.IsAccountStatusValidRequest\x1a+.mgmt.v1alpha1.IsAccountStatusValidResponse\"\x03\x90\x02\x01\x12\x95\x01\n GetAccountBillingCheckoutSession\x12\x36.mgmt.v1alpha1.GetAccountBillingCheckoutSessionRequest\x1a\x37.mgmt.v1alpha1.GetAccountBillingCheckoutSessionResponse\"\x00\x12\x8f\x01\n\x1eGetAccountBillingPortalSession\x12\x34.mgmt.v1alpha1.GetAccountBillingPortalSessionRequest\x1a\x35.mgmt.v1alpha1.GetAccountBillingPortalSessionResponse\"\x00\x12n\n\x12GetBillingAccounts\x12(.mgmt.v1alpha1.GetBillingAccountsRequest\x1a).mgmt.v1alpha1.GetBillingAccountsResponse\"\x03\x90\x02\x01\x12q\n\x14SetBillingMeterEvent\x12*.mgmt.v1alpha1.SetBillingMeterEventRequest\x1a+.mgmt.v1alpha1.SetBillingMeterEventResponse\"\x00\x42\xcc\x01\n\x11\x63om.mgmt.v1alpha1B\x10UserAccountProtoP\x01ZPgithub.com/nucleuscloud/neosync/backend/gen/go/protos/mgmt/v1alpha1;mgmtv1alpha1\xa2\x02\x03MXX\xaa\x02\rMgmt.V1alpha1\xca\x02\rMgmt\\V1alpha1\xe2\x02\x19Mgmt\\V1alpha1\\GPBMetadata\xea\x02\x0eMgmt::V1alpha1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n mgmt/v1alpha1/user_account.proto\x12\rmgmt.v1alpha1\x1a\x1b\x62uf/validate/validate.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x10\n\x0eGetUserRequest\"*\n\x0fGetUserResponse\x12\x17\n\x07user_id\x18\x01 \x01(\tR\x06userId\"\x10\n\x0eSetUserRequest\"*\n\x0fSetUserResponse\x12\x17\n\x07user_id\x18\x01 \x01(\tR\x06userId\"\x18\n\x16GetUserAccountsRequest\"Q\n\x17GetUserAccountsResponse\x12\x36\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x08\x61\x63\x63ounts\"\x9a\x01\n\x0bUserAccount\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x32\n\x04type\x18\x03 \x01(\x0e\x32\x1e.mgmt.v1alpha1.UserAccountTypeR\x04type\x12\x33\n\x16has_stripe_customer_id\x18\x04 \x01(\x08R\x13hasStripeCustomerId\"\x91\x01\n#ConvertPersonalToTeamAccountRequest\x12-\n\x04name\x18\x01 \x01(\tB\x19\xbaH\x16r\x14\x32\x12^[a-z0-9-]{3,100}$R\x04name\x12,\n\naccount_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01H\x00R\taccountId\x88\x01\x01\x42\r\n\x0b_account_id\"\xcc\x01\n$ConvertPersonalToTeamAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\x12\x35\n\x14\x63heckout_session_url\x18\x02 \x01(\tH\x00R\x12\x63heckoutSessionUrl\x88\x01\x01\x12\x35\n\x17new_personal_account_id\x18\x03 \x01(\tR\x14newPersonalAccountIdB\x17\n\x15_checkout_session_url\"\x1b\n\x19SetPersonalAccountRequest\";\n\x1aSetPersonalAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\"A\n\x16IsUserInAccountRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\")\n\x17IsUserInAccountResponse\x12\x0e\n\x02ok\x18\x01 \x01(\x08R\x02ok\"J\n\x1fGetAccountTemporalConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"`\n GetAccountTemporalConfigResponse\x12<\n\x06\x63onfig\x18\x01 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"\x88\x01\n\x1fSetAccountTemporalConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12<\n\x06\x63onfig\x18\x02 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"`\n SetAccountTemporalConfigResponse\x12<\n\x06\x63onfig\x18\x01 \x01(\x0b\x32$.mgmt.v1alpha1.AccountTemporalConfigR\x06\x63onfig\"\x91\x01\n\x15\x41\x63\x63ountTemporalConfig\x12\x19\n\x03url\x18\x01 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x03url\x12%\n\tnamespace\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\tnamespace\x12\x36\n\x13sync_job_queue_name\x18\x03 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x10syncJobQueueName\"I\n\x18\x43reateTeamAccountRequest\x12-\n\x04name\x18\x01 \x01(\tB\x19\xbaH\x16r\x14\x32\x12^[a-z0-9-]{3,100}$R\x04name\"\x8a\x01\n\x19\x43reateTeamAccountResponse\x12\x1d\n\naccount_id\x18\x01 \x01(\tR\taccountId\x12\x35\n\x14\x63heckout_session_url\x18\x02 \x01(\tH\x00R\x12\x63heckoutSessionUrl\x88\x01\x01\x42\x17\n\x15_checkout_session_url\"]\n\x0b\x41\x63\x63ountUser\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n\x05image\x18\x03 \x01(\tR\x05image\x12\x14\n\x05\x65mail\x18\x04 \x01(\tR\x05\x65mail\"G\n\x1cGetTeamAccountMembersRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"Q\n\x1dGetTeamAccountMembersResponse\x12\x30\n\x05users\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.AccountUserR\x05users\"l\n\x1eRemoveTeamAccountMemberRequest\x12!\n\x07user_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x06userId\x12\'\n\naccount_id\x18\x02 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"!\n\x1fRemoveTeamAccountMemberResponse\"h\n\x1eInviteUserToTeamAccountRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12\x1d\n\x05\x65mail\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05\x65mail\"\xdd\x02\n\rAccountInvite\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1d\n\naccount_id\x18\x02 \x01(\tR\taccountId\x12$\n\x0esender_user_id\x18\x03 \x01(\tR\x0csenderUserId\x12\x14\n\x05\x65mail\x18\x04 \x01(\tR\x05\x65mail\x12\x14\n\x05token\x18\x05 \x01(\tR\x05token\x12\x1a\n\x08\x61\x63\x63\x65pted\x18\x06 \x01(\x08R\x08\x61\x63\x63\x65pted\x12\x39\n\ncreated_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x39\n\nupdated_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x39\n\nexpires_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampR\texpiresAt\"W\n\x1fInviteUserToTeamAccountResponse\x12\x34\n\x06invite\x18\x01 \x01(\x0b\x32\x1c.mgmt.v1alpha1.AccountInviteR\x06invite\"G\n\x1cGetTeamAccountInvitesRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"W\n\x1dGetTeamAccountInvitesResponse\x12\x36\n\x07invites\x18\x01 \x03(\x0b\x32\x1c.mgmt.v1alpha1.AccountInviteR\x07invites\":\n\x1eRemoveTeamAccountInviteRequest\x12\x18\n\x02id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\x02id\"!\n\x1fRemoveTeamAccountInviteResponse\"?\n\x1e\x41\x63\x63\x65ptTeamAccountInviteRequest\x12\x1d\n\x05token\x18\x01 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05token\"W\n\x1f\x41\x63\x63\x65ptTeamAccountInviteResponse\x12\x34\n\x07\x61\x63\x63ount\x18\x01 \x01(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x07\x61\x63\x63ount\"\x1d\n\x1bGetSystemInformationRequest\"\xc3\x01\n\x1cGetSystemInformationResponse\x12\x18\n\x07version\x18\x01 \x01(\tR\x07version\x12\x16\n\x06\x63ommit\x18\x02 \x01(\tR\x06\x63ommit\x12\x1a\n\x08\x63ompiler\x18\x03 \x01(\tR\x08\x63ompiler\x12\x1a\n\x08platform\x18\x04 \x01(\tR\x08platform\x12\x39\n\nbuild_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\tbuildDate\"L\n!GetAccountOnboardingConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"d\n\"GetAccountOnboardingConfigResponse\x12>\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\x8c\x01\n!SetAccountOnboardingConfigRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12>\n\x06\x63onfig\x18\x02 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"d\n\"SetAccountOnboardingConfigResponse\x12>\n\x06\x63onfig\x18\x01 \x01(\x0b\x32&.mgmt.v1alpha1.AccountOnboardingConfigR\x06\x63onfig\"\xbb\x02\n\x17\x41\x63\x63ountOnboardingConfig\x12\x41\n\x1dhas_created_source_connection\x18\x01 \x01(\x08R\x1ahasCreatedSourceConnection\x12K\n\"has_created_destination_connection\x18\x02 \x01(\x08R\x1fhasCreatedDestinationConnection\x12&\n\x0fhas_created_job\x18\x03 \x01(\x08R\rhasCreatedJob\x12.\n\x13has_invited_members\x18\x04 \x01(\x08R\x11hasInvitedMembers\x12\x38\n\x18has_completed_onboarding\x18\x05 \x01(\x08R\x16hasCompletedOnboarding\"B\n\x17GetAccountStatusRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\xe5\x01\n\x18GetAccountStatusResponse\x12*\n\x11used_record_count\x18\x01 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x02 \x01(\x04H\x00R\x12\x61llowedRecordCount\x88\x01\x01\x12M\n\x13subscription_status\x18\x03 \x01(\x0e\x32\x1c.mgmt.v1alpha1.BillingStatusR\x12subscriptionStatusB\x17\n\x15_allowed_record_count\"\x9c\x01\n\x1bIsAccountStatusValidRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12\x39\n\x16requested_record_count\x18\x02 \x01(\x04H\x00R\x14requestedRecordCount\x88\x01\x01\x42\x19\n\x17_requested_record_count\"\xc3\x02\n\x1cIsAccountStatusValidResponse\x12\x19\n\x08is_valid\x18\x01 \x01(\x08R\x07isValid\x12\x1b\n\x06reason\x18\x02 \x01(\tH\x00R\x06reason\x88\x01\x01\x12\x1f\n\x0bshould_poll\x18\x03 \x01(\x08R\nshouldPoll\x12*\n\x11used_record_count\x18\x04 \x01(\x04R\x0fusedRecordCount\x12\x35\n\x14\x61llowed_record_count\x18\x05 \x01(\x04H\x01R\x12\x61llowedRecordCount\x88\x01\x01\x12\x43\n\x0e\x61\x63\x63ount_status\x18\x06 \x01(\x0e\x32\x1c.mgmt.v1alpha1.AccountStatusR\raccountStatusB\t\n\x07_reasonB\x17\n\x15_allowed_record_count\"R\n\'GetAccountBillingCheckoutSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"\\\n(GetAccountBillingCheckoutSessionResponse\x12\x30\n\x14\x63heckout_session_url\x18\x01 \x01(\tR\x12\x63heckoutSessionUrl\"P\n%GetAccountBillingPortalSessionRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\"V\n&GetAccountBillingPortalSessionResponse\x12,\n\x12portal_session_url\x18\x01 \x01(\tR\x10portalSessionUrl\"<\n\x19GetBillingAccountsRequest\x12\x1f\n\x0b\x61\x63\x63ount_ids\x18\x01 \x03(\tR\naccountIds\"T\n\x1aGetBillingAccountsResponse\x12\x36\n\x08\x61\x63\x63ounts\x18\x01 \x03(\x0b\x32\x1a.mgmt.v1alpha1.UserAccountR\x08\x61\x63\x63ounts\"\xe2\x01\n\x1bSetBillingMeterEventRequest\x12\'\n\naccount_id\x18\x01 \x01(\tB\x08\xbaH\x05r\x03\xb0\x01\x01R\taccountId\x12&\n\nevent_name\x18\x02 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\teventName\x12\x1d\n\x05value\x18\x03 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x05value\x12\"\n\x08\x65vent_id\x18\x04 \x01(\tB\x07\xbaH\x04r\x02\x10\x01R\x07\x65ventId\x12!\n\ttimestamp\x18\x05 \x01(\x04H\x00R\ttimestamp\x88\x01\x01\x42\x0c\n\n_timestamp\"\x1e\n\x1cSetBillingMeterEventResponse*\x92\x01\n\x0fUserAccountType\x12!\n\x1dUSER_ACCOUNT_TYPE_UNSPECIFIED\x10\x00\x12\x1e\n\x1aUSER_ACCOUNT_TYPE_PERSONAL\x10\x01\x12\x1a\n\x16USER_ACCOUNT_TYPE_TEAM\x10\x02\x12 \n\x1cUSER_ACCOUNT_TYPE_ENTERPRISE\x10\x03*\xa9\x01\n\rBillingStatus\x12\x1e\n\x1a\x42ILLING_STATUS_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42ILLING_STATUS_ACTIVE\x10\x01\x12\x1a\n\x16\x42ILLING_STATUS_EXPIRED\x10\x02\x12\x1f\n\x1b\x42ILLING_STATUS_TRIAL_ACTIVE\x10\x03\x12 \n\x1c\x42ILLING_STATUS_TRIAL_EXPIRED\x10\x04*\x8c\x02\n\rAccountStatus\x12%\n!ACCOUNT_STATUS_REASON_UNSPECIFIED\x10\x00\x12(\n$ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT\x10\x01\x12*\n&ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT\x10\x02\x12+\n\'ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE\x10\x03\x12\'\n#ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE\x10\x04\x12(\n$ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED\x10\x05\x32\xa0\x16\n\x12UserAccountService\x12J\n\x07GetUser\x12\x1d.mgmt.v1alpha1.GetUserRequest\x1a\x1e.mgmt.v1alpha1.GetUserResponse\"\x00\x12J\n\x07SetUser\x12\x1d.mgmt.v1alpha1.SetUserRequest\x1a\x1e.mgmt.v1alpha1.SetUserResponse\"\x00\x12\x62\n\x0fGetUserAccounts\x12%.mgmt.v1alpha1.GetUserAccountsRequest\x1a&.mgmt.v1alpha1.GetUserAccountsResponse\"\x00\x12k\n\x12SetPersonalAccount\x12(.mgmt.v1alpha1.SetPersonalAccountRequest\x1a).mgmt.v1alpha1.SetPersonalAccountResponse\"\x00\x12\x89\x01\n\x1c\x43onvertPersonalToTeamAccount\x12\x32.mgmt.v1alpha1.ConvertPersonalToTeamAccountRequest\x1a\x33.mgmt.v1alpha1.ConvertPersonalToTeamAccountResponse\"\x00\x12h\n\x11\x43reateTeamAccount\x12\'.mgmt.v1alpha1.CreateTeamAccountRequest\x1a(.mgmt.v1alpha1.CreateTeamAccountResponse\"\x00\x12\x62\n\x0fIsUserInAccount\x12%.mgmt.v1alpha1.IsUserInAccountRequest\x1a&.mgmt.v1alpha1.IsUserInAccountResponse\"\x00\x12}\n\x18GetAccountTemporalConfig\x12..mgmt.v1alpha1.GetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.GetAccountTemporalConfigResponse\"\x00\x12}\n\x18SetAccountTemporalConfig\x12..mgmt.v1alpha1.SetAccountTemporalConfigRequest\x1a/.mgmt.v1alpha1.SetAccountTemporalConfigResponse\"\x00\x12t\n\x15GetTeamAccountMembers\x12+.mgmt.v1alpha1.GetTeamAccountMembersRequest\x1a,.mgmt.v1alpha1.GetTeamAccountMembersResponse\"\x00\x12z\n\x17RemoveTeamAccountMember\x12-.mgmt.v1alpha1.RemoveTeamAccountMemberRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountMemberResponse\"\x00\x12z\n\x17InviteUserToTeamAccount\x12-.mgmt.v1alpha1.InviteUserToTeamAccountRequest\x1a..mgmt.v1alpha1.InviteUserToTeamAccountResponse\"\x00\x12t\n\x15GetTeamAccountInvites\x12+.mgmt.v1alpha1.GetTeamAccountInvitesRequest\x1a,.mgmt.v1alpha1.GetTeamAccountInvitesResponse\"\x00\x12z\n\x17RemoveTeamAccountInvite\x12-.mgmt.v1alpha1.RemoveTeamAccountInviteRequest\x1a..mgmt.v1alpha1.RemoveTeamAccountInviteResponse\"\x00\x12z\n\x17\x41\x63\x63\x65ptTeamAccountInvite\x12-.mgmt.v1alpha1.AcceptTeamAccountInviteRequest\x1a..mgmt.v1alpha1.AcceptTeamAccountInviteResponse\"\x00\x12t\n\x14GetSystemInformation\x12*.mgmt.v1alpha1.GetSystemInformationRequest\x1a+.mgmt.v1alpha1.GetSystemInformationResponse\"\x03\x90\x02\x01\x12\x83\x01\n\x1aGetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.GetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.GetAccountOnboardingConfigResponse\"\x00\x12\x83\x01\n\x1aSetAccountOnboardingConfig\x12\x30.mgmt.v1alpha1.SetAccountOnboardingConfigRequest\x1a\x31.mgmt.v1alpha1.SetAccountOnboardingConfigResponse\"\x00\x12h\n\x10GetAccountStatus\x12&.mgmt.v1alpha1.GetAccountStatusRequest\x1a\'.mgmt.v1alpha1.GetAccountStatusResponse\"\x03\x90\x02\x01\x12t\n\x14IsAccountStatusValid\x12*.mgmt.v1alpha1.IsAccountStatusValidRequest\x1a+.mgmt.v1alpha1.IsAccountStatusValidResponse\"\x03\x90\x02\x01\x12\x95\x01\n GetAccountBillingCheckoutSession\x12\x36.mgmt.v1alpha1.GetAccountBillingCheckoutSessionRequest\x1a\x37.mgmt.v1alpha1.GetAccountBillingCheckoutSessionResponse\"\x00\x12\x8f\x01\n\x1eGetAccountBillingPortalSession\x12\x34.mgmt.v1alpha1.GetAccountBillingPortalSessionRequest\x1a\x35.mgmt.v1alpha1.GetAccountBillingPortalSessionResponse\"\x00\x12n\n\x12GetBillingAccounts\x12(.mgmt.v1alpha1.GetBillingAccountsRequest\x1a).mgmt.v1alpha1.GetBillingAccountsResponse\"\x03\x90\x02\x01\x12q\n\x14SetBillingMeterEvent\x12*.mgmt.v1alpha1.SetBillingMeterEventRequest\x1a+.mgmt.v1alpha1.SetBillingMeterEventResponse\"\x00\x42\xcc\x01\n\x11\x63om.mgmt.v1alpha1B\x10UserAccountProtoP\x01ZPgithub.com/nucleuscloud/neosync/backend/gen/go/protos/mgmt/v1alpha1;mgmtv1alpha1\xa2\x02\x03MXX\xaa\x02\rMgmt.V1alpha1\xca\x02\rMgmt\\V1alpha1\xe2\x02\x19Mgmt\\V1alpha1\\GPBMetadata\xea\x02\x0eMgmt::V1alpha1b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -98,10 +98,10 @@ _globals['_USERACCOUNTSERVICE'].methods_by_name['GetBillingAccounts']._serialized_options = b'\220\002\001' _globals['_USERACCOUNTTYPE']._serialized_start=5702 _globals['_USERACCOUNTTYPE']._serialized_end=5848 - _globals['_BILLINGSTATUS']._serialized_start=5850 - _globals['_BILLINGSTATUS']._serialized_end=5952 - _globals['_ACCOUNTSTATUS']._serialized_start=5955 - _globals['_ACCOUNTSTATUS']._serialized_end=6140 + _globals['_BILLINGSTATUS']._serialized_start=5851 + _globals['_BILLINGSTATUS']._serialized_end=6020 + _globals['_ACCOUNTSTATUS']._serialized_start=6023 + _globals['_ACCOUNTSTATUS']._serialized_end=6291 _globals['_GETUSERREQUEST']._serialized_start=113 _globals['_GETUSERREQUEST']._serialized_end=129 _globals['_GETUSERRESPONSE']._serialized_start=131 @@ -208,6 +208,6 @@ _globals['_SETBILLINGMETEREVENTREQUEST']._serialized_end=5667 _globals['_SETBILLINGMETEREVENTRESPONSE']._serialized_start=5669 _globals['_SETBILLINGMETEREVENTRESPONSE']._serialized_end=5699 - _globals['_USERACCOUNTSERVICE']._serialized_start=6143 - _globals['_USERACCOUNTSERVICE']._serialized_end=8991 + _globals['_USERACCOUNTSERVICE']._serialized_start=6294 + _globals['_USERACCOUNTSERVICE']._serialized_end=9142 # @@protoc_insertion_point(module_scope) diff --git a/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi b/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi index 861a1d00b8..7b07ab6d16 100644 --- a/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi +++ b/python/src/neosync/mgmt/v1alpha1/user_account_pb2.pyi @@ -20,6 +20,8 @@ class BillingStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): BILLING_STATUS_UNSPECIFIED: _ClassVar[BillingStatus] BILLING_STATUS_ACTIVE: _ClassVar[BillingStatus] BILLING_STATUS_EXPIRED: _ClassVar[BillingStatus] + BILLING_STATUS_TRIAL_ACTIVE: _ClassVar[BillingStatus] + BILLING_STATUS_TRIAL_EXPIRED: _ClassVar[BillingStatus] class AccountStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): __slots__ = () @@ -27,6 +29,8 @@ class AccountStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT: _ClassVar[AccountStatus] ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT: _ClassVar[AccountStatus] ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE: _ClassVar[AccountStatus] + ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE: _ClassVar[AccountStatus] + ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED: _ClassVar[AccountStatus] USER_ACCOUNT_TYPE_UNSPECIFIED: UserAccountType USER_ACCOUNT_TYPE_PERSONAL: UserAccountType USER_ACCOUNT_TYPE_TEAM: UserAccountType @@ -34,10 +38,14 @@ USER_ACCOUNT_TYPE_ENTERPRISE: UserAccountType BILLING_STATUS_UNSPECIFIED: BillingStatus BILLING_STATUS_ACTIVE: BillingStatus BILLING_STATUS_EXPIRED: BillingStatus +BILLING_STATUS_TRIAL_ACTIVE: BillingStatus +BILLING_STATUS_TRIAL_EXPIRED: BillingStatus ACCOUNT_STATUS_REASON_UNSPECIFIED: AccountStatus ACCOUNT_STATUS_EXCEEDS_ALLOWED_LIMIT: AccountStatus ACCOUNT_STATUS_REQUESTED_EXCEEDS_LIMIT: AccountStatus ACCOUNT_STATUS_ACCOUNT_IN_EXPIRED_STATE: AccountStatus +ACCOUNT_STATUS_ACCOUNT_TRIAL_ACTIVE: AccountStatus +ACCOUNT_STATUS_ACCOUNT_TRIAL_EXPIRED: AccountStatus class GetUserRequest(_message.Message): __slots__ = ()