@@ -100,10 +100,70 @@ const createApp = async (externalId: string, isBrowser: boolean, name = ''): Pro
100100 return id
101101}
102102
103+ export interface AppWithLastUsed extends AppDb {
104+ last_used ?: string
105+ activity_count ?: number
106+ }
107+
108+ const getRecentlyUsedApps = async ( limit = 100 , offset = 0 ) : Promise < AppWithLastUsed [ ] > => {
109+ const monitorDb = await MonitorDb . getMonitorDb ( )
110+ const query = `
111+ SELECT
112+ a.*,
113+ MAX(act.timestamp) as last_used,
114+ COUNT(act.id) as activity_count
115+ FROM app a
116+ LEFT JOIN activity act ON act.app_id = a.id
117+ GROUP BY a.id
118+ HAVING last_used IS NOT NULL
119+ ORDER BY last_used DESC
120+ LIMIT ${ limit } OFFSET ${ offset }
121+ `
122+ return await monitorDb . select < AppWithLastUsed [ ] > ( query )
123+ }
124+
125+ const deleteApp = async ( appId : string ) : Promise < void > => {
126+ const monitorDb = await MonitorDb . getMonitorDb ( )
127+ // Delete related records first (in order of foreign key dependencies)
128+ // 1. Delete activity_state_tag records that reference app_tag
129+ await monitorDb . execute ( `DELETE FROM activity_state_tag WHERE app_tag_id IN (SELECT id FROM app_tag WHERE app_id = '${ appId } ')` )
130+ // 2. Delete activities
131+ await monitorDb . execute ( `DELETE FROM activity WHERE app_id = '${ appId } '` )
132+ // 3. Delete app_tag records
133+ await monitorDb . execute ( `DELETE FROM app_tag WHERE app_id = '${ appId } '` )
134+ // 4. Delete the app itself
135+ await monitorDb . execute ( `DELETE FROM app WHERE id = '${ appId } '` )
136+ }
137+
138+ const deleteApps = async ( appIds : string [ ] ) : Promise < void > => {
139+ if ( appIds . length === 0 ) return
140+ const monitorDb = await MonitorDb . getMonitorDb ( )
141+ const placeholders = appIds . map ( ( ) => '?' ) . join ( ',' )
142+ // Delete in order of foreign key dependencies
143+ // 1. Delete activity_state_tag records that reference app_tag
144+ await monitorDb . execute ( `DELETE FROM activity_state_tag WHERE app_tag_id IN (SELECT id FROM app_tag WHERE app_id IN (${ placeholders } ))` , appIds )
145+ // 2. Delete activities
146+ await monitorDb . execute ( `DELETE FROM activity WHERE app_id IN (${ placeholders } )` , appIds )
147+ // 3. Delete app_tag records
148+ await monitorDb . execute ( `DELETE FROM app_tag WHERE app_id IN (${ placeholders } )` , appIds )
149+ // 4. Delete the app itself
150+ await monitorDb . execute ( `DELETE FROM app WHERE id IN (${ placeholders } )` , appIds )
151+ }
152+
153+ const getAppCount = async ( ) : Promise < number > => {
154+ const monitorDb = await MonitorDb . getMonitorDb ( )
155+ const result = await monitorDb . select < [ { count : number } ] > ( 'SELECT COUNT(DISTINCT app_id) as count FROM activity WHERE app_id IS NOT NULL' )
156+ return result [ 0 ] ?. count || 0
157+ }
158+
103159export const AppRepo = {
104160 setAppTag,
105161 getApps,
106162 getAppsByIds,
107163 getAppsByCategoryTags,
108- createApp
164+ createApp,
165+ getRecentlyUsedApps,
166+ deleteApp,
167+ deleteApps,
168+ getAppCount,
109169}
0 commit comments