recommendation flow implemented

POC phase compleated
This commit is contained in:
dimitar committed 2025-11-20 19:10:16 +01:00
1 parent 118efad70f
commit 8b4cef33dc
10 files changed
+802 -17

No files matched your search

+108 -13
View File
@@ -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;