@@ -3,7 +3,8 @@ import { cookies } from "next/headers";
33import { eq , sql } from "drizzle-orm" ;
44import { config , assertEnv } from "@/lib/config" ;
55import { db } from "@/lib/db/client" ;
6- import { usageRecords } from "@/lib/db/schema" ;
6+ import { authFileMappings , usageRecords } from "@/lib/db/schema" ;
7+ import { toAuthFileMappings } from "@/lib/auth-files" ;
78import { parseUsagePayload , toUsageRecords } from "@/lib/usage" ;
89
910export const runtime = "nodejs" ;
@@ -47,6 +48,44 @@ async function isAuthorized(request: Request) {
4748 return false ;
4849}
4950
51+ async function syncAuthFileMappings ( pulledAt : Date ) {
52+ const authFilesUrl = `${ config . cliproxy . baseUrl . replace ( / \/ $ / , "" ) } /auth-files` ;
53+
54+ const response = await fetch ( authFilesUrl , {
55+ headers : {
56+ Authorization : `Bearer ${ config . cliproxy . apiKey } ` ,
57+ "Content-Type" : "application/json"
58+ } ,
59+ cache : "no-store"
60+ } ) ;
61+
62+ if ( ! response . ok ) {
63+ throw new Error ( `Failed to fetch auth-files: ${ response . status } ${ response . statusText } ` ) ;
64+ }
65+
66+ const json = await response . json ( ) ;
67+ const rows = toAuthFileMappings ( json , pulledAt ) ;
68+ if ( rows . length === 0 ) return 0 ;
69+
70+ await db
71+ . insert ( authFileMappings )
72+ . values ( rows )
73+ . onConflictDoUpdate ( {
74+ target : authFileMappings . authId ,
75+ set : {
76+ name : sql `coalesce(nullif(excluded.name, ''), ${ authFileMappings . name } )` ,
77+ label : sql `coalesce(nullif(excluded.label, ''), ${ authFileMappings . label } )` ,
78+ provider : sql `coalesce(nullif(excluded.provider, ''), ${ authFileMappings . provider } )` ,
79+ source : sql `coalesce(nullif(excluded.source, ''), ${ authFileMappings . source } )` ,
80+ email : sql `coalesce(nullif(excluded.email, ''), ${ authFileMappings . email } )` ,
81+ updatedAt : sql `coalesce(excluded.updated_at, ${ authFileMappings . updatedAt } )` ,
82+ syncedAt : pulledAt
83+ }
84+ } ) ;
85+
86+ return rows . length ;
87+ }
88+
5089async function performSync ( request : Request ) {
5190 if ( ! config . password && ! config . cronSecret && ! PASSWORD ) return missingPassword ( ) ;
5291 if ( ! ( await isAuthorized ( request ) ) ) return unauthorized ( ) ;
@@ -89,16 +128,31 @@ async function performSync(request: Request) {
89128
90129 const rows = toUsageRecords ( payload , pulledAt ) ;
91130
131+ let authFilesSynced = 0 ;
132+ let authFilesWarning : string | undefined ;
133+ try {
134+ authFilesSynced = await syncAuthFileMappings ( pulledAt ) ;
135+ } catch ( error ) {
136+ authFilesWarning = "auth-files sync failed" ;
137+ console . warn ( "/api/sync auth-files sync failed:" , error ) ;
138+ }
139+
92140 if ( rows . length === 0 ) {
93- return NextResponse . json ( { status : "ok" , inserted : 0 , message : "No usage data" } ) ;
141+ return NextResponse . json ( {
142+ status : "ok" ,
143+ inserted : 0 ,
144+ message : "No usage data" ,
145+ authFilesSynced,
146+ ...( authFilesWarning ? { authFilesWarning } : { } )
147+ } ) ;
94148 }
95149
96150 let insertedRows : Array < { id : number } > ;
97151 try {
98152 insertedRows = await db
99153 . insert ( usageRecords )
100154 . values ( rows )
101- . onConflictDoNothing ( { target : [ usageRecords . occurredAt , usageRecords . route , usageRecords . model ] } )
155+ . onConflictDoNothing ( { target : [ usageRecords . occurredAt , usageRecords . route , usageRecords . model , usageRecords . source ] } )
102156 . returning ( { id : usageRecords . id } ) ;
103157 } catch ( dbError ) {
104158 console . error ( "/api/sync database insert failed:" , dbError ) ;
@@ -119,7 +173,13 @@ async function performSync(request: Request) {
119173 inserted = Number ( fallback ?. [ 0 ] ?. count ?? 0 ) ;
120174 }
121175
122- return NextResponse . json ( { status : "ok" , inserted, attempted : rows . length } ) ;
176+ return NextResponse . json ( {
177+ status : "ok" ,
178+ inserted,
179+ attempted : rows . length ,
180+ authFilesSynced,
181+ ...( authFilesWarning ? { authFilesWarning } : { } )
182+ } ) ;
123183}
124184
125185export async function POST ( request : Request ) {
0 commit comments