| name | database-dev |
| description | Expert in MongoDB operations, database schema design, and data modeling for this SAT prep platform. Use when working with user data, practice questions, shop items, or any database-related tasks. |
Database Development Agent
Expert guidance for MongoDB operations and database schema design.
Tech Stack Context
This project uses:
- MongoDB with native mongodb driver
- Upstash Redis for caching and rate limiting
- Collections:
users, math, english
Database Structure
Users Collection
{
_id: ObjectId,
name: string,
email: string,
image: string,
currency: number,
points: number,
correctAnswers: number,
wrongAnswers: number,
currentStreak: number,
longestStreak: number,
referralCode: string,
referredBy: string | null,
referralCount: number,
itemsBought: string[],
studyPlan: StudyPlan | null,
createdAt: Date,
updatedAt: Date
}
Math Questions Collection
{
_id: ObjectId,
category: "advanced-math" | "problem-solving" | "geometry" | "algebra",
difficulty: "easy" | "medium" | "hard",
question: string,
options: string[],
correctAnswer: number,
explanation: string,
createdAt: Date
}
English Questions Collection
{
_id: ObjectId,
category: "information-ideas" | "standard-english" | "expression-ideas" | "craft-structure",
difficulty: "easy" | "medium" | "hard",
passage: string,
question: string,
options: string[],
correctAnswer: number,
explanation: string,
createdAt: Date
}
Database Connection Pattern
import { MongoClient } from "mongodb";
const uri = process.env.MONGO_URL!;
const client = new MongoClient(uri);
export async function getDatabase() {
await client.connect();
return client.db("DailySAT");
}
export async function getUsers() {
const db = await getDatabase();
return db.collection("users");
}
Common Patterns
Find User by Email
export async function findUserByEmail(email: string) {
const users = await getUsers();
return users.findOne({ email });
}
Update User Currency
export async function addCoins(userId: string, amount: number) {
const users = await getUsers();
return users.updateOne(
{ _id: new ObjectId(userId) },
{ $inc: { currency: amount } },
);
}
Add Question (Admin)
export async function addMathQuestion(
question: Omit<MathQuestion, "_id" | "createdAt">,
) {
const math = await getMathQuestions();
return math.insertOne({
...question,
createdAt: new Date(),
});
}
Rate Limiting with Redis
import { Redis } from "@upstash/redis";
const redis = new Redis({
url: process.env.REDIS_URL!,
token: process.env.REDIS_TOKEN!,
});
export async function checkRateLimit(identifier: string) {
const key = `rate:${identifier}`;
const current = await redis.get<number>(key);
if (current && current >= 5) {
return false;
}
await redis.incr(key);
await redis.expire(key, 300);
return true;
}
Environment Variables
MONGO_URL=mongodb://localhost:27017/
REDIS_URL=https://your-redis.upstash.io
REDIS_TOKEN=your-redis-token
Best Practices
- Always use environment variables for connection strings
- Handle connections properly - Reuse client when possible
- Use ObjectId for MongoDB IDs, not strings
- Index frequently queried fields - email, category, difficulty
- Validate data before inserting/updating
- Use projections to fetch only needed fields