11import { AnalyticsEvent } from '@codebuff/common/constants/analytics-events'
2+ import { getReferralLink } from '@codebuff/common/util/referral'
23import { NextResponse } from 'next/server'
34
45import type { TrackEventFn } from '@codebuff/common/types/contracts/analytics'
@@ -9,7 +10,16 @@ import type { NextRequest } from 'next/server'
910import { VALID_USER_INFO_FIELDS } from '@/db/user'
1011import { extractApiKeyFromHeader } from '@/util/auth'
1112
12- type ValidField = ( typeof VALID_USER_INFO_FIELDS ) [ number ]
13+ const DERIVED_USER_INFO_FIELDS = [ 'referral_link' ] as const
14+
15+ type DerivedField = ( typeof DERIVED_USER_INFO_FIELDS ) [ number ]
16+ type ValidDbField = ( typeof VALID_USER_INFO_FIELDS ) [ number ]
17+ type ValidField = ValidDbField | DerivedField
18+
19+ const ALL_USER_INFO_FIELDS = [
20+ ...VALID_USER_INFO_FIELDS ,
21+ ...DERIVED_USER_INFO_FIELDS ,
22+ ] as const
1323
1424export async function getMe ( params : {
1525 req : NextRequest
@@ -41,15 +51,15 @@ export async function getMe(params: {
4151 if ( requestedFields . length === 0 ) {
4252 return NextResponse . json (
4353 {
44- error : `Invalid fields: empty. Valid fields are: ${ VALID_USER_INFO_FIELDS . join ( ', ' ) } ` ,
54+ error : `Invalid fields: empty. Valid fields are: ${ ALL_USER_INFO_FIELDS . join ( ', ' ) } ` ,
4555 } ,
4656 { status : 400 } ,
4757 )
4858 }
4959
5060 // Validate that all requested fields are valid
5161 const invalidFields = requestedFields . filter (
52- ( f ) => ! VALID_USER_INFO_FIELDS . includes ( f as ValidField ) ,
62+ ( f ) => ! ALL_USER_INFO_FIELDS . includes ( f as ValidField ) ,
5363 )
5464 if ( invalidFields . length > 0 ) {
5565 trackEvent ( {
@@ -63,7 +73,7 @@ export async function getMe(params: {
6373 } )
6474 return NextResponse . json (
6575 {
66- error : `Invalid fields: ${ invalidFields . join ( ', ' ) } . Valid fields are: ${ VALID_USER_INFO_FIELDS . join ( ', ' ) } ` ,
76+ error : `Invalid fields: ${ invalidFields . join ( ', ' ) } . Valid fields are: ${ ALL_USER_INFO_FIELDS . join ( ', ' ) } ` ,
6777 } ,
6878 { status : 400 } ,
6979 )
@@ -74,10 +84,29 @@ export async function getMe(params: {
7484 fields = [ 'id' ]
7585 }
7686
87+ // Build database field selection (exclude derived fields, always include id)
88+ const dbFieldsSet = new Set < ValidDbField > ( )
89+
90+ for ( const field of fields ) {
91+ if ( VALID_USER_INFO_FIELDS . includes ( field as ValidDbField ) ) {
92+ dbFieldsSet . add ( field as ValidDbField )
93+ }
94+ }
95+
96+ // Always include id for tracking
97+ dbFieldsSet . add ( 'id' )
98+
99+ // If referral_link is requested, ensure we also fetch referral_code
100+ if ( fields . includes ( 'referral_link' ) && ! dbFieldsSet . has ( 'referral_code' ) ) {
101+ dbFieldsSet . add ( 'referral_code' )
102+ }
103+
104+ const dbFields = Array . from ( dbFieldsSet )
105+
77106 // Get user info
78107 const userInfo = await getUserInfoFromApiKey ( {
79108 apiKey,
80- fields,
109+ fields : dbFields ,
81110 logger,
82111 } )
83112
@@ -98,5 +127,22 @@ export async function getMe(params: {
98127 logger,
99128 } )
100129
101- return NextResponse . json ( userInfo )
130+ // Build response including derived fields
131+ const userInfoRecord = userInfo as Partial < Record < ValidDbField , string | null > >
132+
133+ const responseBody : Record < string , unknown > = { }
134+
135+ for ( const field of fields ) {
136+ if ( field === 'referral_link' ) {
137+ const referralCode = userInfoRecord . referral_code ?? null
138+ responseBody . referral_link =
139+ typeof referralCode === 'string' && referralCode . length > 0
140+ ? getReferralLink ( referralCode )
141+ : null
142+ } else {
143+ responseBody [ field ] = userInfoRecord [ field as ValidDbField ] ?? null
144+ }
145+ }
146+
147+ return NextResponse . json ( responseBody )
102148}
0 commit comments