project-standalo-todo-super/app/lib/db/store.ts

367 lines
8.5 KiB
TypeScript

/**
* In-memory data store for MVP implementation
*/
import {
User,
Transaction,
Task,
UserTask,
Badge,
UserBadge,
Quiz,
Referral,
TaskType,
RequirementType,
TransactionType
} from '../types';
// In-memory storage
const users: User[] = [];
const transactions: Transaction[] = [];
const tasks: Task[] = [];
const userTasks: UserTask[] = [];
const badges: Badge[] = [];
const userBadges: UserBadge[] = [];
const quizzes: Quiz[] = [];
const referrals: Referral[] = [];
// ID generators
let userIdCounter = 1;
let transactionIdCounter = 1;
let taskIdCounter = 1;
let userTaskIdCounter = 1;
let badgeIdCounter = 1;
let userBadgeIdCounter = 1;
let quizIdCounter = 1;
let referralIdCounter = 1;
// Helper: Generate IDs
const generateId = (prefix: string, counter: number): string =>
`${prefix}_${String(counter).padStart(6, '0')}`;
// User operations
export const findUser = (id: string): User | undefined => {
return users.find(u => u.id === id);
};
export const findUserByEmail = (email: string): User | undefined => {
return users.find(u => u.email.toLowerCase() === email.toLowerCase());
};
export const createUser = (email: string, passwordHash: string, name: string): User => {
const user: User = {
id: generateId('user', userIdCounter++),
email,
passwordHash,
name,
createdAt: new Date(),
updatedAt: new Date()
};
users.push(user);
return user;
};
export const updateUser = (id: string, updates: Partial<User>): User | null => {
const user = findUser(id);
if (!user) return null;
Object.assign(user, { ...updates, updatedAt: new Date() });
return user;
};
export const getAllUsers = (): User[] => {
return [...users];
};
// Transaction operations
export const createTransaction = (
userId: string,
amount: number,
type: TransactionType,
source: string
): Transaction => {
const transaction: Transaction = {
id: generateId('txn', transactionIdCounter++),
userId,
amount,
type,
source,
createdAt: new Date()
};
transactions.push(transaction);
return transaction;
};
export const getUserTransactions = (userId: string): Transaction[] => {
return transactions.filter(t => t.userId === userId);
};
export const getUserBalance = (userId: string): number => {
const userTxns = getUserTransactions(userId);
return userTxns.reduce((balance, txn) => {
return txn.type === TransactionType.EARNED
? balance + txn.amount
: balance - txn.amount;
}, 0);
};
// Task operations
export const findTask = (id: string): Task | undefined => {
return tasks.find(t => t.id === id);
};
export const getActiveTasks = (): Task[] => {
return tasks.filter(t => t.isActive);
};
export const createTask = (task: Omit<Task, 'id' | 'createdAt' | 'updatedAt'>): Task => {
const newTask: Task = {
...task,
id: generateId('task', taskIdCounter++),
createdAt: new Date(),
updatedAt: new Date()
};
tasks.push(newTask);
return newTask;
};
// UserTask operations
export const createUserTask = (
userId: string,
taskId: string,
pointsEarned: number
): UserTask => {
const userTask: UserTask = {
id: generateId('utask', userTaskIdCounter++),
userId,
taskId,
completedAt: new Date(),
pointsEarned
};
userTasks.push(userTask);
return userTask;
};
export const getUserCompletedTasks = (userId: string): UserTask[] => {
return userTasks.filter(ut => ut.userId === userId);
};
export const hasUserCompletedTask = (userId: string, taskId: string): boolean => {
return userTasks.some(ut => ut.userId === userId && ut.taskId === taskId);
};
// Badge operations
export const findBadge = (id: string): Badge | undefined => {
return badges.find(b => b.id === id);
};
export const getAllBadges = (): Badge[] => {
return [...badges];
};
export const createBadge = (badge: Omit<Badge, 'id'>): Badge => {
const newBadge: Badge = {
...badge,
id: generateId('badge', badgeIdCounter++)
};
badges.push(newBadge);
return newBadge;
};
// UserBadge operations
export const createUserBadge = (userId: string, badgeId: string): UserBadge => {
const userBadge: UserBadge = {
id: generateId('ubadge', userBadgeIdCounter++),
userId,
badgeId,
earnedAt: new Date()
};
userBadges.push(userBadge);
return userBadge;
};
export const getUserBadges = (userId: string): UserBadge[] => {
return userBadges.filter(ub => ub.userId === userId);
};
export const hasUserEarnedBadge = (userId: string, badgeId: string): boolean => {
return userBadges.some(ub => ub.userId === userId && ub.badgeId === badgeId);
};
// Quiz operations
export const findQuiz = (id: string): Quiz | undefined => {
return quizzes.find(q => q.id === id);
};
export const findQuizByTaskId = (taskId: string): Quiz | undefined => {
return quizzes.find(q => q.taskId === taskId);
};
export const createQuiz = (quiz: Omit<Quiz, 'id'>): Quiz => {
const newQuiz: Quiz = {
...quiz,
id: generateId('quiz', quizIdCounter++)
};
quizzes.push(newQuiz);
return newQuiz;
};
// Referral operations
export const createReferral = (
referrerId: string,
referredId: string,
bonusPoints: number
): Referral => {
const referral: Referral = {
id: generateId('ref', referralIdCounter++),
referrerId,
referredId,
bonusPoints,
createdAt: new Date()
};
referrals.push(referral);
return referral;
};
export const getUserReferrals = (userId: string): Referral[] => {
return referrals.filter(r => r.referrerId === userId);
};
// Seed data
export const seedDatabase = () => {
// Clear existing data
users.length = 0;
transactions.length = 0;
tasks.length = 0;
userTasks.length = 0;
badges.length = 0;
userBadges.length = 0;
quizzes.length = 0;
referrals.length = 0;
// Reset counters
userIdCounter = 1;
transactionIdCounter = 1;
taskIdCounter = 1;
userTaskIdCounter = 1;
badgeIdCounter = 1;
userBadgeIdCounter = 1;
quizIdCounter = 1;
referralIdCounter = 1;
// Seed tasks
const dailyCheckin = createTask({
type: TaskType.CHECKIN,
title: 'Daily Check-in',
description: 'Check in daily to earn points',
pointsReward: 10,
isActive: true
});
const watchAd = createTask({
type: TaskType.AD,
title: 'Watch Advertisement',
description: 'Watch a short video ad',
pointsReward: 5,
isActive: true
});
const takeSurvey = createTask({
type: TaskType.SURVEY,
title: 'Complete Survey',
description: 'Share your opinion in a quick survey',
pointsReward: 20,
isActive: true
});
const quizTask = createTask({
type: TaskType.QUIZ,
title: 'General Knowledge Quiz',
description: 'Test your knowledge and earn points',
pointsReward: 15,
isActive: true
});
const videoTask = createTask({
type: TaskType.VIDEO,
title: 'Watch Educational Video',
description: 'Watch a 5-minute educational video',
pointsReward: 8,
isActive: true
});
const readingTask = createTask({
type: TaskType.READING,
title: 'Read Article',
description: 'Read an interesting article',
pointsReward: 12,
isActive: true
});
// Seed quiz for quiz task
createQuiz({
taskId: quizTask.id,
question: 'What is the capital of France?',
options: ['London', 'Berlin', 'Paris', 'Madrid'],
correctAnswer: 2
});
// Seed badges
createBadge({
name: 'First Steps',
description: 'Complete your first task',
icon: '🎯',
requirementType: RequirementType.TASKS_COMPLETED,
requirementValue: 1
});
createBadge({
name: 'Point Collector',
description: 'Earn 100 points',
icon: '💰',
requirementType: RequirementType.POINTS_TOTAL,
requirementValue: 100
});
createBadge({
name: 'Dedicated',
description: 'Complete 10 tasks',
icon: '⭐',
requirementType: RequirementType.TASKS_COMPLETED,
requirementValue: 10
});
createBadge({
name: 'Week Warrior',
description: 'Maintain a 7-day streak',
icon: '🔥',
requirementType: RequirementType.STREAK_DAYS,
requirementValue: 7
});
createBadge({
name: 'Referral Master',
description: 'Refer 5 friends',
icon: '🤝',
requirementType: RequirementType.REFERRALS,
requirementValue: 5
});
createBadge({
name: 'Point Millionaire',
description: 'Earn 1000 points',
icon: '💎',
requirementType: RequirementType.POINTS_TOTAL,
requirementValue: 1000
});
console.log('Database seeded successfully');
console.log(`- ${tasks.length} tasks`);
console.log(`- ${badges.length} badges`);
console.log(`- ${quizzes.length} quizzes`);
};
// Initialize seed data
seedDatabase();