Separated weight tracking

This commit is contained in:
AG
2025-11-29 12:13:12 +02:00
parent 78930f6b80
commit d86abd6b1b
11 changed files with 300 additions and 22 deletions

View File

@@ -6,6 +6,7 @@ import exerciseRoutes from './routes/exercises';
import sessionRoutes from './routes/sessions';
import planRoutes from './routes/plans';
import aiRoutes from './routes/ai';
import weightRoutes from './routes/weight';
import bcrypt from 'bcryptjs';
import { PrismaClient } from '@prisma/client';
@@ -59,6 +60,7 @@ app.use('/api/exercises', exerciseRoutes);
app.use('/api/sessions', sessionRoutes);
app.use('/api/plans', planRoutes);
app.use('/api/ai', aiRoutes);
app.use('/api/weight', weightRoutes);
app.get('/', (req, res) => {
res.send('GymFlow AI API is running');

View File

@@ -0,0 +1,21 @@
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
const JWT_SECRET = process.env.JWT_SECRET || 'secret';
export const authenticateToken = (req: Request, res: Response, next: NextFunction) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res.sendStatus(401);
}
jwt.verify(token, JWT_SECRET, (err: any, user: any) => {
if (err) {
return res.sendStatus(403);
}
(req as any).user = user;
next();
});
};

View File

@@ -0,0 +1,78 @@
import express from 'express';
import { PrismaClient } from '@prisma/client';
import { authenticateToken } from '../middleware/auth';
const router = express.Router();
const prisma = new PrismaClient();
// Get weight history
router.get('/', authenticateToken, async (req, res) => {
try {
const userId = (req as any).user.userId;
const weights = await prisma.bodyWeightRecord.findMany({
where: { userId },
orderBy: { date: 'desc' },
take: 365 // Limit to last year for now
});
res.json(weights);
} catch (error) {
console.error('Error fetching weight history:', error);
res.status(500).json({ error: 'Failed to fetch weight history' });
}
});
// Log weight
router.post('/', authenticateToken, async (req, res) => {
try {
const userId = (req as any).user.userId;
const { weight, dateStr } = req.body;
if (!weight || !dateStr) {
return res.status(400).json({ error: 'Weight and dateStr are required' });
}
// Upsert: Update if exists for this day, otherwise create
const record = await prisma.bodyWeightRecord.upsert({
where: {
userId_dateStr: {
userId,
dateStr
}
},
update: {
weight: parseFloat(weight),
date: new Date(dateStr) // Update date object just in case
},
create: {
userId,
weight: parseFloat(weight),
dateStr,
date: new Date(dateStr)
}
});
// Also update the user profile weight to the latest logged weight
// But only if the logged date is today or in the future (or very recent)
// For simplicity, let's just update the profile weight if it's the most recent record
// Or we can just update it always if the user considers this their "current" weight.
// Let's check if this is the latest record by date.
const latestRecord = await prisma.bodyWeightRecord.findFirst({
where: { userId },
orderBy: { date: 'desc' }
});
if (latestRecord && latestRecord.id === record.id) {
await prisma.userProfile.update({
where: { userId },
data: { weight: parseFloat(weight) }
});
}
res.json(record);
} catch (error) {
console.error('Error logging weight:', error);
res.status(500).json({ error: 'Failed to log weight' });
}
});
export default router;