@@ -16,6 +16,7 @@ import (
1616 plandb "github.com/openmeterio/openmeter/openmeter/ent/db/plan"
1717 "github.com/openmeterio/openmeter/openmeter/ent/db/predicate"
1818 subscriptiondb "github.com/openmeterio/openmeter/openmeter/ent/db/subscription"
19+ "github.com/openmeterio/openmeter/openmeter/streaming"
1920 "github.com/openmeterio/openmeter/pkg/clock"
2021 "github.com/openmeterio/openmeter/pkg/framework/entutils"
2122 "github.com/openmeterio/openmeter/pkg/models"
@@ -127,6 +128,80 @@ func (a *adapter) ListCustomers(ctx context.Context, input customer.ListCustomer
127128 })
128129}
129130
131+ // ListCustomerUsageAttributions lists customers usage attributions
132+ func (a * adapter ) ListCustomerUsageAttributions (ctx context.Context , input customer.ListCustomerUsageAttributionsInput ) (pagination.Result [streaming.CustomerUsageAttribution ], error ) {
133+ if err := input .Validate (); err != nil {
134+ return pagination.Result [streaming.CustomerUsageAttribution ]{}, models .NewGenericValidationError (err )
135+ }
136+
137+ return entutils .TransactingRepo (ctx , a , func (ctx context.Context , repo * adapter ) (pagination.Result [streaming.CustomerUsageAttribution ], error ) {
138+ // Build the database query
139+ now := clock .Now ().UTC ()
140+
141+ query := repo .db .Customer .Query ().
142+ // We only need to select the fields we need for the usage attribution to optimize the query
143+ Select (
144+ customerdb .FieldID ,
145+ customerdb .FieldKey ,
146+ ).
147+ Where (customerdb .Namespace (input .Namespace )).
148+ Order (customerdb .ByID (sql .OrderAsc ()))
149+ query = WithSubjects (query , now )
150+
151+ // Filters
152+ if len (input .CustomerIDs ) > 0 {
153+ query = query .Where (customerdb .IDIn (input .CustomerIDs ... ))
154+ }
155+
156+ // Do not return deleted customers by default
157+ if ! input .IncludeDeleted {
158+ query = query .Where (customerdb .Or (
159+ customerdb .DeletedAtIsNil (),
160+ customerdb .DeletedAtGTE (now ),
161+ ))
162+ }
163+
164+ // Response
165+ response := pagination.Result [streaming.CustomerUsageAttribution ]{
166+ Page : input .Page ,
167+ }
168+
169+ paged , err := query .Paginate (ctx , input .Page )
170+ if err != nil {
171+ return response , err
172+ }
173+
174+ result := make ([]streaming.CustomerUsageAttribution , 0 , len (paged .Items ))
175+ for _ , item := range paged .Items {
176+ if item == nil {
177+ a .logger .WarnContext (ctx , "invalid query result: nil customer received" )
178+ continue
179+ }
180+
181+ subjectKeys , err := subjectKeysFromDBEntity (* item )
182+ if err != nil {
183+ return response , err
184+ }
185+
186+ usageAttribution := streaming.CustomerUsageAttribution {
187+ ID : item .ID ,
188+ SubjectKeys : subjectKeys ,
189+ }
190+
191+ if item .Key != "" {
192+ usageAttribution .Key = & item .Key
193+ }
194+
195+ result = append (result , usageAttribution )
196+ }
197+
198+ response .TotalCount = paged .TotalCount
199+ response .Items = result
200+
201+ return response , nil
202+ })
203+ }
204+
130205// CreateCustomer creates a new customer
131206func (a * adapter ) CreateCustomer (ctx context.Context , input customer.CreateCustomerInput ) (* customer.Customer , error ) {
132207 if err := input .Validate (); err != nil {
0 commit comments