recommendation flow implemented
POC phase compleated
This commit is contained in:
1 parent
118efad70f
commit
8b4cef33dc
10 files changed
+802
-17
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import Database from 'better-sqlite3'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import { IDatabase, User, Client, FitnessProfile, Attendance, DatabaseConfig } from './types'
|
||||
import { IDatabase, User, Client, FitnessProfile, Attendance, Recommendation, DatabaseConfig } from './types'
|
||||
|
||||
export class SQLiteDatabase implements IDatabase {
|
||||
private db: Database.Database | null = null
|
||||
@@ -120,6 +120,24 @@ export class SQLiteDatabase implements IDatabase {
|
||||
)
|
||||
`)
|
||||
|
||||
// Recommendations table
|
||||
this.db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS recommendations (
|
||||
id TEXT PRIMARY KEY,
|
||||
userId TEXT NOT NULL,
|
||||
type TEXT NOT NULL CHECK (type IN ('short_term', 'medium_term', 'long_term')),
|
||||
content TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('pending', 'completed')),
|
||||
createdAt DATETIME NOT NULL,
|
||||
updatedAt DATETIME NOT NULL,
|
||||
FOREIGN KEY (userId) REFERENCES users (id) ON DELETE CASCADE
|
||||
)
|
||||
`)
|
||||
|
||||
this.db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_recommendations_userId ON recommendations(userId);
|
||||
`)
|
||||
|
||||
this.db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_attendance_clientId ON attendance(clientId);
|
||||
CREATE INDEX IF NOT EXISTS idx_attendance_checkInTime ON attendance(checkInTime);
|
||||
@@ -141,8 +159,8 @@ export class SQLiteDatabase implements IDatabase {
|
||||
}
|
||||
|
||||
const stmt = this.db.prepare(
|
||||
`INSERT INTO users (id, email, firstName, lastName, password, phone, role, createdAt, updatedAt)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
`INSERT INTO users(id, email, firstName, lastName, password, phone, role, createdAt, updatedAt)
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
)
|
||||
|
||||
stmt.run(
|
||||
@@ -191,7 +209,7 @@ export class SQLiteDatabase implements IDatabase {
|
||||
values.push(new Date().toISOString()) // updatedAt
|
||||
values.push(id)
|
||||
|
||||
const stmt = this.db.prepare(`UPDATE users SET ${setClause}, updatedAt = ? WHERE id = ?`)
|
||||
const stmt = this.db.prepare(`UPDATE users SET ${setClause}, updatedAt = ? WHERE id = ? `)
|
||||
stmt.run(values)
|
||||
|
||||
return this.getUserById(id)
|
||||
@@ -227,8 +245,8 @@ export class SQLiteDatabase implements IDatabase {
|
||||
const client: Client = { id, ...clientData }
|
||||
|
||||
const stmt = this.db.prepare(
|
||||
`INSERT INTO clients (id, userId, membershipType, membershipStatus, joinDate)
|
||||
VALUES (?, ?, ?, ?, ?)`
|
||||
`INSERT INTO clients(id, userId, membershipType, membershipStatus, joinDate)
|
||||
VALUES(?, ?, ?, ?, ?)`
|
||||
)
|
||||
|
||||
stmt.run(
|
||||
@@ -273,7 +291,7 @@ export class SQLiteDatabase implements IDatabase {
|
||||
const values = fields.map(field => (updates as any)[field])
|
||||
values.push(id)
|
||||
|
||||
const stmt = this.db.prepare(`UPDATE clients SET ${setClause} WHERE id = ?`)
|
||||
const stmt = this.db.prepare(`UPDATE clients SET ${setClause} WHERE id = ? `)
|
||||
stmt.run(values)
|
||||
|
||||
return this.getClientById(id)
|
||||
@@ -299,10 +317,10 @@ export class SQLiteDatabase implements IDatabase {
|
||||
}
|
||||
|
||||
const stmt = this.db.prepare(
|
||||
`INSERT INTO fitness_profiles
|
||||
(userId, height, weight, age, gender, activityLevel, fitnessGoals,
|
||||
`INSERT INTO fitness_profiles
|
||||
(userId, height, weight, age, gender, activityLevel, fitnessGoals,
|
||||
exerciseHabits, dietHabits, medicalConditions, allergies, injuries, createdAt, updatedAt)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
)
|
||||
|
||||
stmt.run(
|
||||
@@ -346,7 +364,7 @@ export class SQLiteDatabase implements IDatabase {
|
||||
values.push(new Date().toISOString()) // updatedAt
|
||||
values.push(userId)
|
||||
|
||||
const stmt = this.db.prepare(`UPDATE fitness_profiles SET ${setClause}, updatedAt = ? WHERE userId = ?`)
|
||||
const stmt = this.db.prepare(`UPDATE fitness_profiles SET ${setClause}, updatedAt = ? WHERE userId = ? `)
|
||||
stmt.run(values)
|
||||
|
||||
return this.getFitnessProfileByUserId(userId)
|
||||
@@ -377,8 +395,8 @@ export class SQLiteDatabase implements IDatabase {
|
||||
}
|
||||
|
||||
const stmt = this.db.prepare(
|
||||
`INSERT INTO attendance (id, clientId, checkInTime, type, notes, createdAt)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`
|
||||
`INSERT INTO attendance(id, clientId, checkInTime, type, notes, createdAt)
|
||||
VALUES(?, ?, ?, ?, ?, ?)`
|
||||
)
|
||||
|
||||
stmt.run(
|
||||
@@ -490,6 +508,83 @@ export class SQLiteDatabase implements IDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
// Recommendation operations
|
||||
async createRecommendation(data: Omit<Recommendation, 'createdAt' | 'updatedAt'>): Promise<Recommendation> {
|
||||
if (!this.db) throw new Error('Database not connected')
|
||||
|
||||
const now = new Date()
|
||||
const recommendation: Recommendation = {
|
||||
...data,
|
||||
createdAt: now,
|
||||
updatedAt: now
|
||||
}
|
||||
|
||||
const stmt = this.db.prepare(
|
||||
`INSERT INTO recommendations (id, userId, type, content, status, createdAt, updatedAt)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
||||
)
|
||||
|
||||
stmt.run(
|
||||
recommendation.id, recommendation.userId, recommendation.type,
|
||||
recommendation.content, recommendation.status,
|
||||
recommendation.createdAt.toISOString(), recommendation.updatedAt.toISOString()
|
||||
)
|
||||
|
||||
return recommendation
|
||||
}
|
||||
|
||||
async getRecommendationsByUserId(userId: string): Promise<Recommendation[]> {
|
||||
if (!this.db) throw new Error('Database not connected')
|
||||
|
||||
const stmt = this.db.prepare('SELECT * FROM recommendations WHERE userId = ? ORDER BY createdAt DESC')
|
||||
const rows = stmt.all(userId)
|
||||
|
||||
return rows.map(row => this.mapRowToRecommendation(row))
|
||||
}
|
||||
|
||||
async updateRecommendation(id: string, updates: Partial<Recommendation>): Promise<Recommendation | null> {
|
||||
if (!this.db) throw new Error('Database not connected')
|
||||
|
||||
const fields = Object.keys(updates).filter(key => key !== 'id' && key !== 'userId')
|
||||
if (fields.length === 0) {
|
||||
const stmt = this.db.prepare('SELECT * FROM recommendations WHERE id = ?')
|
||||
const row = stmt.get(id)
|
||||
return row ? this.mapRowToRecommendation(row) : null
|
||||
}
|
||||
|
||||
const setClause = fields.map(field => `${field} = ?`).join(', ')
|
||||
const values = fields.map(field => (updates as any)[field])
|
||||
values.push(new Date().toISOString()) // updatedAt
|
||||
values.push(id)
|
||||
|
||||
const stmt = this.db.prepare(`UPDATE recommendations SET ${setClause}, updatedAt = ? WHERE id = ?`)
|
||||
stmt.run(values)
|
||||
|
||||
const getStmt = this.db.prepare('SELECT * FROM recommendations WHERE id = ?')
|
||||
const row = getStmt.get(id)
|
||||
return row ? this.mapRowToRecommendation(row) : null
|
||||
}
|
||||
|
||||
async deleteRecommendation(id: string): Promise<boolean> {
|
||||
if (!this.db) throw new Error('Database not connected')
|
||||
|
||||
const stmt = this.db.prepare('DELETE FROM recommendations WHERE id = ?')
|
||||
const result = stmt.run(id)
|
||||
return (result.changes || 0) > 0
|
||||
}
|
||||
|
||||
private mapRowToRecommendation(row: any): Recommendation {
|
||||
return {
|
||||
id: row.id,
|
||||
userId: row.userId,
|
||||
type: row.type,
|
||||
content: row.content,
|
||||
status: row.status,
|
||||
createdAt: new Date(row.createdAt),
|
||||
updatedAt: new Date(row.updatedAt)
|
||||
}
|
||||
}
|
||||
|
||||
async getDashboardStats(): Promise<{
|
||||
totalUsers: number;
|
||||
activeClients: number;
|
||||
|
||||
Reference in new issue
Block a user