File size: 4,364 Bytes
ec9f00b
 
 
 
 
 
 
4d2efbd
ec9f00b
 
4d2efbd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec9f00b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0c378b9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec9f00b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { MongoClient, Db } from 'mongodb'

let client: MongoClient | null = null
let db: Db | null = null

export async function getMongo() {
  if (client && db) return { client, db }
  
  const uri = process.env.MONGO_URI
  const dbName = process.env.MONGO_DB || 'studybuddy'
  
  console.log('[MONGO_DEBUG] Environment check:')
  console.log('[MONGO_DEBUG] MONGO_URI exists:', !!uri)
  console.log('[MONGO_DEBUG] MONGO_DB:', dbName)
  console.log('[MONGO_DEBUG] MONGO_URI starts with:', uri?.substring(0, 20) + '...')
  
  if (!uri) {
    console.error('[MONGO_DEBUG] MONGO_URI is required but not set')
    throw new Error('MONGO_URI is required')
  }
  
  try {
    console.log('[MONGO_DEBUG] Creating MongoClient...')
    client = new MongoClient(uri)
    console.log('[MONGO_DEBUG] Connecting to MongoDB...')
    await client.connect()
    console.log('[MONGO_DEBUG] MongoDB connected successfully')
    
    db = client.db(dbName)
    console.log('[MONGO_DEBUG] Database selected:', dbName)
    
    // Test the connection
    console.log('[MONGO_DEBUG] Testing connection with ping...')
    await db.command({ ping: 1 })
    console.log('[MONGO_DEBUG] Ping successful')
    
    return { client, db }
  } catch (error) {
    console.error('[MONGO_DEBUG] MongoDB connection failed:', error)
    console.error('[MONGO_DEBUG] Error details:', {
      name: error instanceof Error ? error.name : 'Unknown',
      message: error instanceof Error ? error.message : String(error),
      stack: error instanceof Error ? error.stack : undefined
    })
    throw error
  }
}

export const VECTOR_DIM = 384

export async function storeCards(cards: any[]) {
  const { db } = await getMongo()
  if (!cards || !cards.length) return
  for (const c of cards) {
    if (!c.embedding || c.embedding.length !== VECTOR_DIM) {
      throw new Error(`Invalid embedding length; expected ${VECTOR_DIM}`)
    }
  }
  await db.collection('chunks').insertMany(cards, { ordered: false })
}

export async function upsertFileSummary(user_id: string, project_id: string, filename: string, summary: string) {
  const { db } = await getMongo()
  await db.collection('files').updateOne(
    { user_id, project_id, filename },
    { $set: { summary } },
    { upsert: true }
  )
}

export async function listFiles(user_id: string, project_id: string) {
  const { db } = await getMongo()
  const cursor = db.collection('files').find({ user_id, project_id }, { projection: { _id: 0, filename: 1, summary: 1 } }).sort({ filename: 1 })
  return cursor.toArray()
}

export async function getFileChunks(user_id: string, project_id: string, filename: string, limit = 20) {
  const { db } = await getMongo()
  const cursor = db.collection('chunks').find({ user_id, project_id, filename }).limit(limit)
  const out: any[] = []
  for await (const doc of cursor) {
    const d: any = {}
    for (const [k, v] of Object.entries(doc as any)) {
      if (k === '_id') d[k] = String(v)
      // @ts-ignore
      else if (v && typeof v === 'object' && typeof (v as any).toISOString === 'function') d[k] = (v as any).toISOString()
      else d[k] = v as any
    }
    out.push(d)
  }
  return out
}

export async function deleteFileData(user_id: string, project_id: string, filename: string) {
  const { db } = await getMongo()
  await db.collection('chunks').deleteMany({ user_id, project_id, filename })
  await db.collection('files').deleteMany({ user_id, project_id, filename })
}

export async function ensureIndexes() {
  const { db } = await getMongo()
  console.log('[MONGO_DEBUG] Ensuring indexes...')
  
  try {
    await db.collection('chunks').createIndex({ user_id: 1, project_id: 1, filename: 1 }, { unique: false })
    console.log('[MONGO_DEBUG] Chunks index created/verified')
  } catch (error: any) {
    if (error.code === 86) {
      console.log('[MONGO_DEBUG] Chunks index already exists with different options, skipping')
    } else {
      throw error
    }
  }
  
  try {
    await db.collection('files').createIndex({ user_id: 1, project_id: 1, filename: 1 }, { unique: false })
    console.log('[MONGO_DEBUG] Files index created/verified')
  } catch (error: any) {
    if (error.code === 86) {
      console.log('[MONGO_DEBUG] Files index already exists with different options, skipping')
    } else {
      throw error
    }
  }
  
  console.log('[MONGO_DEBUG] Indexes ensured')
}