Skip to content

Commit 4023496

Browse files
committed
pass in logger to org-monitoring
1 parent 1361894 commit 4023496

File tree

1 file changed

+120
-72
lines changed

1 file changed

+120
-72
lines changed

packages/billing/src/org-monitoring.ts

Lines changed: 120 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { AnalyticsEvent } from '@codebuff/common/constants/analytics-events'
33
import db from '@codebuff/common/db'
44
import * as schema from '@codebuff/common/db/schema'
55
import { getNextQuotaReset } from '@codebuff/common/util/dates'
6-
import { logger } from '@codebuff/common/util/logger'
6+
import { getErrorObject } from '@codebuff/common/util/error'
77
import { eq } from 'drizzle-orm'
88

99
import { calculateOrganizationUsageAndBalance } from './org-billing'
@@ -25,16 +25,6 @@ export interface OrganizationCreditAlert {
2525
metadata?: Record<string, any>
2626
}
2727

28-
export interface OrganizationUsageMetrics {
29-
organizationId: string
30-
totalCreditsConsumed: number
31-
uniqueUsers: number
32-
repositoryCount: number
33-
averageCreditsPerUser: number
34-
topRepository: string
35-
timeframe: 'daily' | 'weekly' | 'monthly'
36-
}
37-
3828
export interface OrganizationAlert {
3929
id: string
4030
type:
@@ -137,31 +127,44 @@ export async function getOrganizationAlerts(params: {
137127
* Sends alerts for organization credit issues
138128
*/
139129
export async function sendOrganizationAlert(
140-
alert: OrganizationCreditAlert,
130+
params: OrganizationCreditAlert & {
131+
logger: Logger
132+
},
141133
): Promise<void> {
134+
const {
135+
organizationId,
136+
alertType,
137+
currentBalance,
138+
threshold,
139+
usageAmount,
140+
error,
141+
metadata,
142+
logger,
143+
} = params
144+
142145
try {
143146
// Log the alert
144147
logger.warn(
145148
{
146-
organizationId: alert.organizationId,
147-
alertType: alert.alertType,
148-
currentBalance: alert.currentBalance,
149-
threshold: alert.threshold,
150-
usageAmount: alert.usageAmount,
151-
error: alert.error,
152-
metadata: alert.metadata,
149+
organizationId,
150+
alertType,
151+
currentBalance,
152+
threshold,
153+
usageAmount,
154+
error: error,
155+
metadata: metadata,
153156
},
154-
`Organization alert: ${alert.alertType}`,
157+
`Organization alert: ${alertType}`,
155158
)
156159

157160
// Track analytics event
158161
trackEvent({
159162
event: AnalyticsEvent.CREDIT_GRANT,
160-
userId: alert.organizationId,
163+
userId: organizationId,
161164
properties: {
162-
alertType: alert.alertType,
163-
currentBalance: alert.currentBalance,
164-
threshold: alert.threshold,
165+
alertType,
166+
currentBalance,
167+
threshold,
165168
},
166169
logger,
167170
})
@@ -172,18 +175,18 @@ export async function sendOrganizationAlert(
172175
// - Dashboard notifications
173176
// - SMS alerts for critical issues
174177

175-
switch (alert.alertType) {
178+
switch (alertType) {
176179
case 'low_balance':
177-
await handleLowBalanceAlert(alert)
180+
await handleLowBalanceAlert(params)
178181
break
179182
case 'high_usage':
180-
await handleHighUsageAlert(alert)
183+
await handleHighUsageAlert(params)
181184
break
182185
case 'failed_consumption':
183-
await handleFailedConsumptionAlert(alert)
186+
await handleFailedConsumptionAlert(params)
184187
break
185188
case 'billing_setup_required':
186-
await handleBillingSetupAlert(alert)
189+
await handleBillingSetupAlert(params)
187190
break
188191
}
189192
} catch (error) {
@@ -192,67 +195,91 @@ export async function sendOrganizationAlert(
192195
}
193196

194197
async function handleLowBalanceAlert(
195-
alert: OrganizationCreditAlert,
198+
params: OrganizationCreditAlert & {
199+
logger: Logger
200+
},
196201
): Promise<void> {
202+
const { organizationId, currentBalance, logger } = params
203+
197204
// TODO: Send email to organization owners about low balance
198205
// TODO: Suggest auto-topup or manual credit purchase
199206
logger.info(
200-
{ organizationId: alert.organizationId, balance: alert.currentBalance },
207+
{ organizationId, balance: currentBalance },
201208
'Low balance alert sent to organization owners',
202209
)
203210
}
204211

205212
async function handleHighUsageAlert(
206-
alert: OrganizationCreditAlert,
213+
params: OrganizationCreditAlert & {
214+
logger: Logger
215+
},
207216
): Promise<void> {
217+
const { organizationId, usageAmount, logger } = params
218+
208219
// TODO: Send usage spike notification
209220
// TODO: Provide usage breakdown and recommendations
210221
logger.info(
211-
{ organizationId: alert.organizationId, usage: alert.usageAmount },
222+
{ organizationId, usage: usageAmount },
212223
'High usage alert sent to organization admins',
213224
)
214225
}
215226

216227
async function handleFailedConsumptionAlert(
217-
alert: OrganizationCreditAlert,
228+
params: OrganizationCreditAlert & {
229+
logger: Logger
230+
},
218231
): Promise<void> {
232+
const { organizationId, error, logger } = params
233+
219234
// TODO: Send immediate notification about failed credit consumption
220235
// TODO: Provide troubleshooting steps
221236
logger.error(
222-
{ organizationId: alert.organizationId, error: alert.error },
237+
{ organizationId, error },
223238
'Failed consumption alert sent to organization owners',
224239
)
225240
}
226241

227242
async function handleBillingSetupAlert(
228-
alert: OrganizationCreditAlert,
243+
params: OrganizationCreditAlert & {
244+
logger: Logger
245+
},
229246
): Promise<void> {
247+
const { organizationId, logger } = params
248+
230249
// TODO: Send setup reminder to organization owners
231250
// TODO: Provide setup instructions and links
232251
logger.info(
233-
{ organizationId: alert.organizationId },
252+
{ organizationId },
234253
'Billing setup reminder sent to organization owners',
235254
)
236255
}
237256

238257
/**
239258
* Monitors organization credit consumption and sends alerts when needed
240259
*/
241-
export async function monitorOrganizationCredits(
242-
organizationId: string,
243-
currentBalance: number,
244-
recentUsage: number,
245-
organizationName?: string,
246-
): Promise<void> {
260+
export async function monitorOrganizationCredits(params: {
261+
organizationId: string
262+
currentBalance: number
263+
recentUsage: number
264+
organizationName?: string
265+
logger: Logger
266+
}): Promise<void> {
267+
const {
268+
organizationId,
269+
currentBalance,
270+
recentUsage,
271+
organizationName,
272+
logger,
273+
} = params
274+
247275
const LOW_BALANCE_THRESHOLD = 100 // Credits
248276
const HIGH_USAGE_THRESHOLD = 1000 // Credits per day
249277

250278
try {
251279
// Check for low balance
252280
if (currentBalance < LOW_BALANCE_THRESHOLD) {
253281
await sendOrganizationAlert({
254-
organizationId,
255-
organizationName,
282+
...params,
256283
alertType: 'low_balance',
257284
currentBalance,
258285
threshold: LOW_BALANCE_THRESHOLD,
@@ -262,8 +289,7 @@ export async function monitorOrganizationCredits(
262289
// Check for high usage
263290
if (recentUsage > HIGH_USAGE_THRESHOLD) {
264291
await sendOrganizationAlert({
265-
organizationId,
266-
organizationName,
292+
...params,
267293
alertType: 'high_usage',
268294
usageAmount: recentUsage,
269295
threshold: HIGH_USAGE_THRESHOLD,
@@ -273,8 +299,7 @@ export async function monitorOrganizationCredits(
273299
// Check for negative balance (debt)
274300
if (currentBalance < 0) {
275301
await sendOrganizationAlert({
276-
organizationId,
277-
organizationName,
302+
...params,
278303
alertType: 'failed_consumption',
279304
currentBalance,
280305
error: 'Organization has negative credit balance',
@@ -291,33 +316,51 @@ export async function monitorOrganizationCredits(
291316
/**
292317
* Tracks organization usage metrics for analytics
293318
*/
294-
export async function trackOrganizationUsageMetrics(
295-
metrics: OrganizationUsageMetrics,
296-
): Promise<void> {
319+
export async function trackOrganizationUsageMetrics(params: {
320+
organizationId: string
321+
totalCreditsConsumed: number
322+
uniqueUsers: number
323+
repositoryCount: number
324+
averageCreditsPerUser: number
325+
topRepository: string
326+
timeframe: 'daily' | 'weekly' | 'monthly'
327+
logger: Logger
328+
}): Promise<void> {
329+
const {
330+
organizationId,
331+
totalCreditsConsumed,
332+
uniqueUsers,
333+
repositoryCount,
334+
averageCreditsPerUser,
335+
topRepository,
336+
timeframe,
337+
logger,
338+
} = params
339+
297340
try {
298341
logger.info(
299342
{
300-
organizationId: metrics.organizationId,
301-
totalCreditsConsumed: metrics.totalCreditsConsumed,
302-
uniqueUsers: metrics.uniqueUsers,
303-
repositoryCount: metrics.repositoryCount,
304-
averageCreditsPerUser: metrics.averageCreditsPerUser,
305-
topRepository: metrics.topRepository,
306-
timeframe: metrics.timeframe,
343+
organizationId,
344+
totalCreditsConsumed,
345+
uniqueUsers,
346+
repositoryCount,
347+
averageCreditsPerUser,
348+
topRepository,
349+
timeframe,
307350
},
308351
'Organization usage metrics tracked',
309352
)
310353

311354
// Track analytics event
312355
trackEvent({
313356
event: AnalyticsEvent.CREDIT_GRANT,
314-
userId: metrics.organizationId,
357+
userId: organizationId,
315358
properties: {
316359
type: 'usage_metrics',
317-
timeframe: metrics.timeframe,
318-
totalCreditsConsumed: metrics.totalCreditsConsumed,
319-
uniqueUsers: metrics.uniqueUsers,
320-
repositoryCount: metrics.repositoryCount,
360+
timeframe,
361+
totalCreditsConsumed,
362+
uniqueUsers,
363+
repositoryCount,
321364
},
322365
logger,
323366
})
@@ -326,23 +369,28 @@ export async function trackOrganizationUsageMetrics(
326369
// TODO: Generate usage reports
327370
// TODO: Identify usage patterns and optimization opportunities
328371
} catch (error) {
329-
logger.error(
330-
{ metrics, error },
331-
'Failed to track organization usage metrics',
332-
)
372+
const obj: any = {
373+
...params,
374+
error: getErrorObject(error),
375+
}
376+
delete obj.logger
377+
logger.error(obj, 'Failed to track organization usage metrics')
333378
}
334379
}
335380

336381
/**
337382
* Validates organization billing health
338383
*/
339-
export async function validateOrganizationBillingHealth(
340-
organizationId: string,
341-
): Promise<{
384+
export async function validateOrganizationBillingHealth(params: {
385+
organizationId: string
386+
logger: Logger
387+
}): Promise<{
342388
healthy: boolean
343389
issues: string[]
344390
recommendations: string[]
345391
}> {
392+
const { organizationId, logger } = params
393+
346394
const issues: string[] = []
347395
const recommendations: string[] = []
348396

@@ -368,7 +416,7 @@ export async function validateOrganizationBillingHealth(
368416
return { healthy, issues, recommendations }
369417
} catch (error) {
370418
logger.error(
371-
{ organizationId, error },
419+
{ organizationId, error: getErrorObject(error) },
372420
'Error validating organization billing health',
373421
)
374422
return {

0 commit comments

Comments
 (0)