diff --git a/.eslint-results-explicit.json b/.eslint-results-explicit.json deleted file mode 100644 index 99c6a55..0000000 --- a/.eslint-results-explicit.json +++ /dev/null @@ -1,324 +0,0 @@ -[ - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/App.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/Chatbot.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/Dashboard.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/FactChecker.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/FloatingChatbot.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/LocationFinder.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/MealAnalyzer.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/PlanGenerator.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/Sidebar.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/Button.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/Card.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/Icons.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/LoadingSpinner.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/MarkdownRenderer.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/hooks/useGeolocation.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/index.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/services/geminiService.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/tests/Sidebar.test.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/types.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/utils/audioUtils.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/vite.config.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/vitest.config.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/vitest.setup.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - } -] diff --git a/.eslint-results-monorepo.json b/.eslint-results-monorepo.json deleted file mode 100644 index 779eb4d..0000000 --- a/.eslint-results-monorepo.json +++ /dev/null @@ -1 +0,0 @@ -[{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/disputes/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/layout.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/revenue/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/users/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/next-env.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/next.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/tailwind.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/clients/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/layout.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/meal-plans/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/next-env.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/next.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/tailwind.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/packages/backend/socketio/server.js","messages":[{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":47,"column":1,"nodeType":"MemberExpression","messageId":"unexpected","endLine":47,"endColumn":12,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[1286,1327],"text":""},"desc":"Remove the console.log()."}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":72,"column":3,"nodeType":"MemberExpression","messageId":"unexpected","endLine":72,"endColumn":14,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[1890,1945],"text":""},"desc":"Remove the console.log()."}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":80,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":80,"endColumn":16,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[2124,2191],"text":""},"desc":"Remove the console.log()."}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":86,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":86,"endColumn":16,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[2300,2365],"text":""},"desc":"Remove the console.log()."}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":153,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":153,"endColumn":16,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[3938,4028],"text":""},"desc":"Remove the console.log()."}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":169,"column":1,"nodeType":"MemberExpression","messageId":"unexpected","endLine":169,"endColumn":12,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[4296,4385],"text":""},"desc":"Remove the console.log()."}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":175,"column":3,"nodeType":"MemberExpression","messageId":"unexpected","endLine":175,"endColumn":14,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[4446,4497],"text":""},"desc":"Remove the console.log()."}]}],"suppressedMessages":[],"errorCount":7,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { createAdapter } from '@socket.io/redis-adapter';\nimport dotenv from 'dotenv';\nimport * as admin from 'firebase-admin';\nimport fs from 'node:fs';\nimport { createClient } from 'redis';\nimport { Server } from 'socket.io';\n\ndotenv.config({ path: '../.env' });\n\n// Initialize Firebase Admin\nconst serviceAccountPath = process.env.FIREBASE_SERVICE_ACCOUNT_PATH;\nif (serviceAccountPath) {\n try {\n const credentials = fs.readFileSync(serviceAccountPath, 'utf8');\n const serviceAccount = JSON.parse(credentials);\n admin.initializeApp({\n credential: admin.credential.cert(serviceAccount),\n });\n } catch (err) {\n console.warn(\n 'Unable to initialize Firebase Admin with provided service account path:',\n err.message\n );\n }\n}\n\n// Initialize Socket.io server\nconst io = new Server(\n Number.parseInt(process.env.SOCKETIO_PORT || '3001', 10),\n {\n cors: {\n origin: process.env.SOCKETIO_CORS_ORIGINS?.split(',') || [\n 'http://localhost:3000',\n ],\n credentials: true,\n },\n }\n);\n\n// Redis adapter for horizontal scaling\nconst pubClient = createClient({ url: process.env.REDIS_URL });\nconst subClient = pubClient.duplicate();\n\nawait pubClient.connect();\nawait subClient.connect();\nio.adapter(createAdapter(pubClient, subClient));\nconsole.log('Redis adapter initialized');\n\n// Authentication middleware\nio.use(async (socket, next) => {\n const token = socket.handshake.auth.token;\n\n if (!token) {\n return next(new Error('Authentication token required'));\n }\n\n try {\n const decodedToken = await admin.auth().verifyIdToken(token);\n socket.data.user = {\n uid: decodedToken.uid,\n email: decodedToken.email,\n };\n next();\n } catch (error) {\n console.error('Authentication error:', error);\n next(new Error('Invalid authentication token'));\n }\n});\n\n// Connection handler\nio.on('connection', (socket) => {\n console.log(`User connected: ${socket.data.user.uid}`);\n\n // Join user's personal room\n socket.join(`user:${socket.data.user.uid}`);\n\n // Join chat room\n socket.on('join_chat', (chatId) => {\n socket.join(`chat:${chatId}`);\n console.log(`User ${socket.data.user.uid} joined chat: ${chatId}`);\n });\n\n // Leave chat room\n socket.on('leave_chat', (chatId) => {\n socket.leave(`chat:${chatId}`);\n console.log(`User ${socket.data.user.uid} left chat: ${chatId}`);\n });\n\n // Send message\n socket.on('send_message', (data) => {\n const { chatId, message, timestamp } = data;\n\n // Broadcast to chat room\n io.to(`chat:${chatId}`).emit('new_message', {\n chatId,\n message,\n sender: socket.data.user,\n timestamp,\n });\n });\n\n // Typing indicator\n socket.on('typing_start', (chatId) => {\n socket.to(`chat:${chatId}`).emit('user_typing', {\n chatId,\n user: socket.data.user,\n });\n });\n\n socket.on('typing_stop', (chatId) => {\n socket.to(`chat:${chatId}`).emit('user_stopped_typing', {\n chatId,\n user: socket.data.user,\n });\n });\n\n // Workout tracking events\n socket.on('workout_started', (data) => {\n const { workoutId, timestamp } = data;\n\n // Notify trainers/nutritionists monitoring this user\n io.to(`user:${socket.data.user.uid}`).emit('workout_status', {\n status: 'started',\n workoutId,\n timestamp,\n });\n });\n\n socket.on('workout_completed', (data) => {\n const { workoutId, duration, caloriesBurned, timestamp } = data;\n\n io.to(`user:${socket.data.user.uid}`).emit('workout_status', {\n status: 'completed',\n workoutId,\n duration,\n caloriesBurned,\n timestamp,\n });\n });\n\n // Real-time notifications\n socket.on('notification', (data) => {\n const { targetUserId, notification } = data;\n\n io.to(`user:${targetUserId}`).emit('notification_received', {\n ...notification,\n timestamp: new Date().toISOString(),\n });\n });\n\n // Disconnect handler\n socket.on('disconnect', (reason) => {\n console.log(\n `User disconnected: ${socket.data.user.uid} - Reason: ${reason}`\n );\n });\n\n // Error handler\n socket.on('error', (error) => {\n console.error(`Socket error for user ${socket.data.user.uid}:`, error);\n });\n});\n\n// Global error handler\nio.engine.on('connection_error', (error) => {\n console.error('Connection error:', error);\n});\n\nconsole.log(\n `Socket.io server running on port ${process.env.SOCKETIO_PORT || 3001}`\n);\n\n// Graceful shutdown\nprocess.on('SIGTERM', async () => {\n console.log('SIGTERM received, closing server...');\n await Promise.all([io.close(), pubClient.quit(), subClient.quit()]);\n process.exit(0);\n});\n","usedDeprecatedRules":[{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]}] \ No newline at end of file diff --git a/.eslint-results.json b/.eslint-results.json deleted file mode 100644 index 99c6a55..0000000 --- a/.eslint-results.json +++ /dev/null @@ -1,324 +0,0 @@ -[ - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/App.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/Chatbot.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/Dashboard.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/FactChecker.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/FloatingChatbot.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/LocationFinder.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/MealAnalyzer.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/PlanGenerator.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/Sidebar.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/Button.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/Card.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/Icons.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/LoadingSpinner.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/components/common/MarkdownRenderer.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/hooks/useGeolocation.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/index.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/services/geminiService.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/tests/Sidebar.test.tsx", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/types.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/utils/audioUtils.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/vite.config.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/vitest.config.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - }, - { - "filePath": "/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/vitest.setup.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { "ruleId": "no-extra-semi", "replacedBy": [] }, - { "ruleId": "no-mixed-spaces-and-tabs", "replacedBy": [] } - ] - } -] diff --git a/.github/workflows/fortress-pipeline.yml b/.github/workflows/fortress-pipeline.yml index 84e5293..a5357a3 100644 --- a/.github/workflows/fortress-pipeline.yml +++ b/.github/workflows/fortress-pipeline.yml @@ -109,15 +109,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: javascript, python - queries: security-extended - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - - name: Run npm audit run: | npm ci diff --git a/.gitignore b/.gitignore index d447aaf..b04ef1f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,9 @@ __pycache__/ .DS_Store .vscode/* !.vscode/extensions.json + +# ESLint result files +.eslint-results*.json + +# Security scan reports +bandit-report.json diff --git a/gymgenius-monorepo/.eslint-results-monorepo.json b/gymgenius-monorepo/.eslint-results-monorepo.json deleted file mode 100644 index b95b5c4..0000000 --- a/gymgenius-monorepo/.eslint-results-monorepo.json +++ /dev/null @@ -1 +0,0 @@ -[{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/disputes/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/layout.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/revenue/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/app/users/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/next-env.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/next.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/admin-panel/tailwind.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/clients/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/layout.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/meal-plans/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/app/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/next-env.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/next.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/apps/nutritionist-panel/tailwind.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/morningstar/Downloads/fitai_-your-personal-fitness-coach/gymgenius-monorepo/packages/backend/socketio/server.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]}] \ No newline at end of file diff --git a/gymgenius-monorepo/packages/backend/socketio/package.json b/gymgenius-monorepo/packages/backend/socketio/package.json index 7ff72cc..a72f61a 100644 --- a/gymgenius-monorepo/packages/backend/socketio/package.json +++ b/gymgenius-monorepo/packages/backend/socketio/package.json @@ -13,7 +13,7 @@ "@socket.io/redis-adapter": "^8.1.0", "redis": "^4.6.5", "dotenv": "^16.3.1", - "firebase-admin": "^11.11.1", + "firebase-admin": "^13.6.0", "cors": "^2.8.5" }, "devDependencies": { diff --git a/gymgenius/backend/Dockerfile b/gymgenius/backend/Dockerfile index fa0d541..59bc7f1 100644 --- a/gymgenius/backend/Dockerfile +++ b/gymgenius/backend/Dockerfile @@ -2,6 +2,7 @@ FROM python:3.11-slim ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 +ENV PYTHONPATH=/app WORKDIR /app diff --git a/gymgenius/backend/__init__.py b/gymgenius/backend/__init__.py new file mode 100644 index 0000000..a025d4c --- /dev/null +++ b/gymgenius/backend/__init__.py @@ -0,0 +1 @@ +# GymGenius Backend Package diff --git a/gymgenius/backend/main.py b/gymgenius/backend/main.py index da1f990..ff2084c 100644 --- a/gymgenius/backend/main.py +++ b/gymgenius/backend/main.py @@ -172,9 +172,7 @@ def get_ai_provider( ) try: - return create_ai_provider( - provider_type, api_key, generate_request.model - ) + return create_ai_provider(provider_type, api_key, generate_request.model) except ValueError as e: logger.error( f"PROVIDER_CREATION_ERROR: {str(e)} | " @@ -244,12 +242,8 @@ async def health_check(): "status": "healthy", "timestamp": datetime.now(timezone.utc).isoformat(), "api_keys": { - "google": ( - "configured" if google_key_configured else "not_configured" - ), - "openai": ( - "configured" if openai_key_configured else "not_configured" - ), + "google": ("configured" if google_key_configured else "not_configured"), + "openai": ("configured" if openai_key_configured else "not_configured"), }, "default_provider": default_provider, } diff --git a/gymgenius/backend/payment_service.py b/gymgenius/backend/payment_service.py index 3cf1e0e..26412c2 100644 --- a/gymgenius/backend/payment_service.py +++ b/gymgenius/backend/payment_service.py @@ -72,9 +72,7 @@ def _require_signature_if_configured( ): """Enforce that a webhook signature exists when a secret is configured.""" if webhook_secret and not webhook_signature: - raise HTTPException( - status_code=400, detail=MISSING_WEBHOOK_SIGNATURE - ) + raise HTTPException(status_code=400, detail=MISSING_WEBHOOK_SIGNATURE) def _verify_signature( @@ -89,13 +87,9 @@ def _verify_signature( webhook_secret.encode(), webhook_body, digestmod=hashlib.sha256 ).hexdigest() if expected != webhook_signature: - raise HTTPException( - status_code=400, detail=INVALID_WEBHOOK_SIGNATURE - ) + raise HTTPException(status_code=400, detail=INVALID_WEBHOOK_SIGNATURE) except Exception: - raise HTTPException( - status_code=400, detail=INVALID_WEBHOOK_SIGNATURE - ) + raise HTTPException(status_code=400, detail=INVALID_WEBHOOK_SIGNATURE) def _parse_event(webhook_body: bytes): @@ -131,9 +125,9 @@ def _handle_subscription_charged(event_data: dict): payload = event_data["payload"].get("subscription", {}) user_id = payload.get("user_id") or payload.get("customer_id") if user_id and user_id in SUBSCRIPTIONS_STORE: - SUBSCRIPTIONS_STORE[user_id]["last_charged_at"] = ( - datetime.now(timezone.utc).isoformat() - ) + SUBSCRIPTIONS_STORE[user_id]["last_charged_at"] = datetime.now( + timezone.utc + ).isoformat() SUBSCRIPTIONS_STORE[user_id]["active"] = True @@ -145,7 +139,6 @@ def _handle_subscription_cancelled(event_data: dict): if user_id and user_id in SUBSCRIPTIONS_STORE: SUBSCRIPTIONS_STORE[user_id]["active"] = False - def _dispatch_webhook_event( webhook_body: bytes, webhook_signature: Optional[str], @@ -248,9 +241,7 @@ async def create_payment_order( "starter_yearly": 10000, } if order_request.subscription_plan not in SUPPORTED_PLANS: - raise HTTPException( - status_code=400, detail="Invalid subscription plan" - ) + raise HTTPException(status_code=400, detail="Invalid subscription plan") # NOTE: Order creation is a placeholder; stores no DB record yet # order_data = { # "amount": order_request.amount, @@ -342,8 +333,7 @@ async def verify_payment( if not os.getenv("RAZORPAY_KEY_SECRET"): # If no secret configured, log and accept for now (test/stub mode) logger.warning( - "PAYMENT_VERIFY: Missing RAZORPAY_KEY_SECRET; " - "skipping verification" + "PAYMENT_VERIFY: Missing RAZORPAY_KEY_SECRET; skipping verification" ) else: _msg = ( @@ -362,12 +352,7 @@ async def verify_payment( ).hexdigest() if generated_signature != verify_request.razorpay_signature: - raise HTTPException( - status_code=400, detail="Invalid payment signature" - ) - # (Legacy commented-out implementation removed; using runtime - # verification above.) - # above.) + raise HTTPException(status_code=400, detail="Invalid payment signature") # NOTE: Update order/subscription in in-memory store order = ORDERS_STORE.get(verify_request.razorpay_order_id) @@ -478,6 +463,4 @@ async def payment_webhook(request: Request): f"error={str(e)} | " f"trace_id={trace_id}" ) - raise HTTPException( - status_code=400, detail="Webhook processing failed" - ) + raise HTTPException(status_code=400, detail="Webhook processing failed") diff --git a/gymgenius/backend/requirements.txt b/gymgenius/backend/requirements.txt index ded8d53..f05e963 100644 --- a/gymgenius/backend/requirements.txt +++ b/gymgenius/backend/requirements.txt @@ -7,7 +7,7 @@ fastapi==0.109.0 uvicorn[standard]==0.27.0 pydantic==2.5.3 -python-multipart==0.0.6 +python-multipart==0.0.20 # ============================================================================ # AI Provider SDKs @@ -19,7 +19,7 @@ google-generativeai==0.8.3 # Security & Rate Limiting # ============================================================================ slowapi==0.1.9 -python-jose[cryptography]==3.3.0 +python-jose[cryptography]==3.5.0 passlib[bcrypt]==1.7.4 # ============================================================================ @@ -40,7 +40,7 @@ httpx==0.27.0 # ============================================================================ # Code Quality & Linting # ============================================================================ -black==24.1.1 +black==25.11.0 flake8==7.0.0 pylint==3.0.3 mypy==1.8.0 diff --git a/gymgenius/backend/socketio_service.py b/gymgenius/backend/socketio_service.py index 5f37c15..a131533 100644 --- a/gymgenius/backend/socketio_service.py +++ b/gymgenius/backend/socketio_service.py @@ -171,9 +171,7 @@ async def send_chat_message(self, sender_id: str, recipient_id: str, message: st # ) await asyncio.sleep(0) - logger.info( - f"SOCKET_CHAT: Message sent | from={sender_id} | to={recipient_id}" - ) + logger.info(f"SOCKET_CHAT: Message sent | from={sender_id} | to={recipient_id}") return _event_data async def broadcast_booking_update(self, booking_id: str, status: str): diff --git a/gymgenius/backend/tests/__init__.py b/gymgenius/backend/tests/__init__.py new file mode 100644 index 0000000..e4c2b03 --- /dev/null +++ b/gymgenius/backend/tests/__init__.py @@ -0,0 +1 @@ +# GymGenius Backend Tests Package diff --git a/gymgenius/backend/tests/test_main_endpoints.py b/gymgenius/backend/tests/test_main_endpoints.py index cdc2a0d..c310128 100644 --- a/gymgenius/backend/tests/test_main_endpoints.py +++ b/gymgenius/backend/tests/test_main_endpoints.py @@ -10,6 +10,7 @@ def __init__(self): async def generate_response(self, prompt: str, trace_id=None): import asyncio + await asyncio.sleep(0) return f"echo: {prompt}" diff --git a/gymgenius/backend/tests/test_payment_service.py b/gymgenius/backend/tests/test_payment_service.py index 2cf1cf7..b6bd594 100644 --- a/gymgenius/backend/tests/test_payment_service.py +++ b/gymgenius/backend/tests/test_payment_service.py @@ -25,7 +25,9 @@ def create_test_app(): async def test_create_payment_order_success(): app = create_test_app() # Use async httpx client with ASGI transport for compatibility. - async with HTTPXAsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + async with HTTPXAsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as client: payload = { "amount": 1000, "currency": "INR", @@ -46,12 +48,14 @@ async def test_verify_payment_success(): app = create_test_app() # Set a temporary secret for generating a valid signature os.environ["RAZORPAY_KEY_SECRET"] = "test-secret" - async with HTTPXAsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + async with HTTPXAsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as client: payload = { - "razorpay_order_id": "order_test_123", - "razorpay_payment_id": "pay_test_123", - "user_id": "user-1234", - } + "razorpay_order_id": "order_test_123", + "razorpay_payment_id": "pay_test_123", + "user_id": "user-1234", + } _msg = ( f"{payload['razorpay_order_id']}|{payload['razorpay_payment_id']}" @@ -87,9 +91,7 @@ async def test_webhook_acknowledge(): else: headers["X-Razorpay-Signature"] = "sig-placeholder" - resp = await client.post( - "/api/payments/webhook", content=body, headers=headers - ) + resp = await client.post("/api/payments/webhook", content=body, headers=headers) assert resp.status_code == 200 body = resp.json() assert body.get("status") == "acknowledged" diff --git a/gymgenius/backend/tests/test_payment_service_storage.py b/gymgenius/backend/tests/test_payment_service_storage.py index 361928e..18539a6 100644 --- a/gymgenius/backend/tests/test_payment_service_storage.py +++ b/gymgenius/backend/tests/test_payment_service_storage.py @@ -71,15 +71,11 @@ async def test_verify_updates_subscription_and_order(): digestmod=hashlib.sha256, ).hexdigest() - resp = await client.post( - "/api/payments/verify-payment", json=verify_payload - ) + resp = await client.post("/api/payments/verify-payment", json=verify_payload) assert resp.status_code == 200 assert ps.ORDERS_STORE[order_id]["status"] == "completed" assert verify_payload["user_id"] in ps.SUBSCRIPTIONS_STORE - assert ( - ps.SUBSCRIPTIONS_STORE[verify_payload["user_id"]]["active"] is True - ) + assert ps.SUBSCRIPTIONS_STORE[verify_payload["user_id"]]["active"] is True async def test_webhook_signature_verification(): @@ -99,9 +95,7 @@ async def test_webhook_signature_verification(): digestmod=hashlib.sha256, ).hexdigest() headers = {"X-Razorpay-Signature": signature} - resp = await client.post( - "/api/payments/webhook", content=body, headers=headers - ) + resp = await client.post("/api/payments/webhook", content=body, headers=headers) assert resp.status_code == 200 assert resp.json().get("status") == "acknowledged" @@ -134,9 +128,7 @@ async def test_webhook_captures_existing_order(): digestmod=hashlib.sha256, ).hexdigest() headers = {"X-Razorpay-Signature": signature} - resp = await client.post( - "/api/payments/webhook", content=body, headers=headers - ) + resp = await client.post("/api/payments/webhook", content=body, headers=headers) assert resp.status_code == 200 assert ps.ORDERS_STORE[order_id]["status"] == "captured" @@ -180,9 +172,7 @@ async def test_verify_with_invalid_signature_returns_400(): "user_id": "user-1234", } - resp = await client.post( - "/api/payments/verify-payment", json=verify_payload - ) + resp = await client.post("/api/payments/verify-payment", json=verify_payload) assert resp.status_code == 400 diff --git a/gymgenius/backend/tests/test_socketio_and_main.py b/gymgenius/backend/tests/test_socketio_and_main.py index 2857906..72b4c07 100644 --- a/gymgenius/backend/tests/test_socketio_and_main.py +++ b/gymgenius/backend/tests/test_socketio_and_main.py @@ -24,17 +24,14 @@ def test_broadcast_has_timestamp_and_logs(caplog): ) # Check it logs trainer id assert any( - "trainer_id=trainer-1" in rec.getMessage() - or "trainer-1" in rec.getMessage() + "trainer_id=trainer-1" in rec.getMessage() or "trainer-1" in rec.getMessage() for rec in caplog.records ) def test_chat_message_timestamp_message_id(capsys): # send a chat message and ensure it sets timestamp and id - asyncio.run( - socketio_service.send_chat_message("user-1", "user-2", "Hello") - ) + asyncio.run(socketio_service.send_chat_message("user-1", "user-2", "Hello")) # We can't easily access the event payload, but the method logs a message diff --git a/gymgenius/backend/tests/test_socketio_service.py b/gymgenius/backend/tests/test_socketio_service.py index 486759d..cc04b6e 100644 --- a/gymgenius/backend/tests/test_socketio_service.py +++ b/gymgenius/backend/tests/test_socketio_service.py @@ -10,14 +10,11 @@ async def test_broadcast_trainer_status_logs(caplog): service = SocketIOService() # The method should complete without error and log an event - await service.broadcast_trainer_status( - "trainer-1", "online", {"uptime": 100} - ) + await service.broadcast_trainer_status("trainer-1", "online", {"uptime": 100}) # Ensure log contains trainer id assert any( - "trainer_id=trainer-1" in rec.getMessage() - or "trainer-1" in rec.getMessage() + "trainer_id=trainer-1" in rec.getMessage() or "trainer-1" in rec.getMessage() for rec in caplog.records ) @@ -49,15 +46,11 @@ async def test_connect_and_broadcast_timestamp(caplog): assert service.active_connections[sid] == "test-user" # broadcast should return event payload with timestamp - evt = await service.broadcast_trainer_status( - "trainer-1", "online", {"uptime": 1} - ) + evt = await service.broadcast_trainer_status("trainer-1", "online", {"uptime": 1}) assert isinstance(evt.get("timestamp"), str) assert "trainer_id" in evt # booking update payload has booking_id and timestamp - booking_evt = await service.broadcast_booking_update( - "booking-1", "confirmed" - ) + booking_evt = await service.broadcast_booking_update("booking-1", "confirmed") assert booking_evt["booking_id"] == "booking-1" assert "timestamp" in booking_evt @@ -79,6 +72,4 @@ async def test_subscribe_trainer_logs(caplog): service = SocketIOService() sid = "sid-sub" await service.subscribe_trainer(sid, {"trainer_id": "t-1"}) - assert any( - "SOCKET_SUBSCRIBE" in rec.getMessage() for rec in caplog.records - ) + assert any("SOCKET_SUBSCRIBE" in rec.getMessage() for rec in caplog.records) diff --git a/package.json b/package.json index ff7b954..6478540 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ ], "*.py": [ "black", - "flake8" + "flake8 --max-line-length=88 --exclude=__pycache__,venv" ] } }