Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ export async function ensureIndexes(): Promise<void> {
await prs.createIndex({ state: 1 });
await prs.createIndex({ merged_at: -1 });
await prs.createIndex({ created_at: -1 });
// Full-text index over content, enabling {$text: {$search: ...}} topic queries.
await prs.createIndex({ title: "text", body: "text" });

const issues = await getCollection("issues");
await issues.createIndex({ repo: 1, number: 1 }, { unique: true });
await issues.createIndex({ "user.login": 1 });
await issues.createIndex({ state: 1 });
await issues.createIndex({ created_at: -1 });
await issues.createIndex({ title: "text", body: "text" });

const users = await getUsersCollection();
await users.createIndex({ login: 1 }, { unique: true });
Expand Down
4 changes: 2 additions & 2 deletions src/synthesis/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ ${schemaContext}
- Use ONLY fields that appear in the schema above. Never invent fields.
- Pick the single collection that best answers the question.
- Allowed pipeline stages: $match, $sort, $limit, $count, $group, $project, $unwind.
- Allowed filter operators: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $and, $or, $not, $exists, $size, $elemMatch.
- Do NOT use $regex on free-text fields (title, body, comments.body). Match exact field values instead.
- Allowed filter operators: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $and, $or, $not, $exists, $size, $elemMatch, $text.
- For topic/keyword search over PR or issue content, use a text search: put {$text: {$search: "keywords"}} inside a $match (backed by a text index on title + body). Combine it with other filters in the SAME $match (author login, state, dates). Use a phrase like "\"code review\"" for exact phrases. Never use $regex on text fields. $text searches only title and body.
- Timestamps are ISO-8601 strings; ISO strings sort lexicographically, so compare them directly with $gte/$lte.
- For relative dates ("today", "last week", "past 3 days"), compute the cutoff from the "Current time" given in the user message — never guess the current date.
- A PR is "merged" when merged is true (or merged_at is not null). "Open"/"closed" use the state field.
Expand Down
2 changes: 2 additions & 0 deletions src/validation/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const ALLOWED_OPERATORS = new Set([
// query operators
"$eq", "$ne", "$gt", "$gte", "$lt", "$lte", "$in", "$nin",
"$and", "$or", "$not", "$nor", "$exists", "$size", "$elemMatch",
// full-text search (backed by the title/body text index)
"$text", "$search", "$language", "$caseSensitive", "$diacriticSensitive",
// accumulators / group expressions
"$sum", "$avg", "$min", "$max", "$first", "$last", "$push", "$addToSet",
]);
Expand Down