Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions Backend/cache/context_default.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"current_week": 40,
"location": "Updated City",
"age": 25,
"weight": 67,
"due_date": "2024-10-01",
"lmp": "2024-01-01",
"cycle_length": 28,
"period_length": 5,
"current_week": 1,
"location": "United States",
"age": 30,
"weight": 65,
"due_date": "2026-10-04",
"lmp": "2025-12-16",
"cycle_length": 40,
"period_length": 2,
"tracking_data": {
"weight": [
{
Expand Down Expand Up @@ -101,5 +101,5 @@
"blood_pressure": [],
"discharge": []
},
"last_updated": "2025-09-10T06:44:27.424436"
"last_updated": "2026-01-02T21:29:17.600560"
}
32 changes: 22 additions & 10 deletions Backend/routes/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,13 @@ def get_profile():
return jsonify({"error": "Profile not found"}), 404

return jsonify({
"due_date": profile[7],
"location": profile[6]
"lmp": profile[1],
"cycle_length": profile[2],
"period_length": profile[3],
"age": profile[4],
"weight": profile[5],
"location": profile[6],
"due_date": profile[7]
Comment on lines +63 to +69
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix API naming inconsistency between get_profile and update_profile.

The response uses snake_case field names (cycle_length, period_length), but update_profile (lines 104-105) expects camelCase (cycleLength, periodLength). This inconsistency breaks the API contract and forces frontend code to transform keys differently for reads vs. writes.

Additionally, hardcoded tuple indices (profile[1], profile[2], etc.) are fragile and will break if the database schema changes or columns are reordered.

πŸ”§ Proposed fix: Use consistent camelCase naming and dict-based access

First, configure the database connection to return rows as dictionaries. In db/db.py, update open_db():

def open_db():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row  # Enable dict-like access
    return conn

Then update the response to use consistent camelCase:

     return jsonify({
-        "lmp": profile[1],
-        "cycle_length": profile[2],
-        "period_length": profile[3],
-        "age": profile[4],
-        "weight": profile[5],
-        "location": profile[6],
-        "due_date": profile[7]
+        "lmp": profile['lmp'],
+        "cycleLength": profile['cycleLength'],
+        "periodLength": profile['periodLength'],
+        "age": profile['age'],
+        "weight": profile['weight'],
+        "location": profile['user_location'],
+        "dueDate": profile['dueDate']
     }), 200

Committable suggestion skipped: line range outside the PR's diff.

πŸ€– Prompt for AI Agents
In @Backend/routes/profile.py around lines 63 - 69, The get_profile response
uses snake_case and fragile tuple indexing, causing inconsistency with
update_profile which expects camelCase; change DB rows to dict-like access by
enabling a row factory in open_db (e.g., set sqlite3.Row) and update get_profile
to build the response using camelCase keys (e.g., lmp, cycleLength,
periodLength, age, weight, location, dueDate) by accessing columns by name
instead of profile[<index>], ensuring names match update_profile and avoiding
brittle positional indexing.

}), 200

except sqlite3.OperationalError:
Expand Down Expand Up @@ -89,21 +94,28 @@ def update_profile():
db = open_db()

try:
db.execute('SELECT * FROM profile')
# Check if profile exists
profile = db.execute('SELECT * FROM profile').fetchone()
if profile is None:
return jsonify({"error": "Profile not found"}), 404

data = request.json
lmp = data.get('lmp')
cycle_length = data.get('cycle_length')
period_length = data.get('period_length')
cycle_length = data.get('cycleLength')
period_length = data.get('periodLength')
age = data.get('age')
weight = data.get('weight')
location = data.get('location')

if not lmp or not location:
return jsonify({"error": "Last menstrual period and location are required"}), 400

# Recalculate due date based on new LMP and cycle length
due_date = calculate_due_date(lmp, cycle_length)

db.execute(
'UPDATE profile SET due_date = ?, user_location = ?',
(lmp, cycle_length, period_length, age, weight, location)
'UPDATE profile SET lmp = ?, cycleLength = ?, periodLength = ?, age = ?, weight = ?, user_location = ?, dueDate = ?',
(lmp, cycle_length, period_length, age, weight, location, due_date)
)
db.commit()

Expand All @@ -112,6 +124,6 @@ def update_profile():
agent = get_agent(db_path)
agent.update_cache(data_type="profile", operation="update")

return jsonify({"status": "success", "message": "Profile updated successfully"}), 200
except sqlite3.OperationalError:
return jsonify({"error": "Database Error"}), 500
return jsonify({"status": "success", "message": "Profile updated successfully", "dueDate": due_date}), 200
except sqlite3.OperationalError as error:
return jsonify({"error": str(error)}), 500
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

Avoid exposing raw database error messages to clients.

Returning str(error) exposes internal database details (table names, column names, SQL syntax) which could aid attackers. Return a generic error message instead.

πŸ”Ž Proposed fix
     except sqlite3.OperationalError as error:    
-        return jsonify({"error": str(error)}), 500
+        print(f"Database error in update_profile: {error}")  # Log internally
+        return jsonify({"error": "Database error occurred"}), 500
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
except sqlite3.OperationalError as error:
return jsonify({"error": str(error)}), 500
except sqlite3.OperationalError as error:
print(f"Database error in update_profile: {error}") # Log internally
return jsonify({"error": "Database error occurred"}), 500
πŸ€– Prompt for AI Agents
In Backend/routes/profile.py around lines 128-129, the except block currently
returns the raw sqlite3.OperationalError string to the client; change it to
return a generic error message (e.g., {"error": "Internal server error"}) with a
500 status to avoid leaking DB details, and log the full exception internally
(using app.logger.exception(...) or logging.exception(...)) so developers still
have the stack trace for debugging while clients only receive the generic
message.

11 changes: 7 additions & 4 deletions Frontend/src/Screens/AllTasksScreen.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useCallback } from 'react';
import {
SafeAreaView,
ScrollView,
Expand All @@ -11,16 +11,19 @@ import {
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { BASE_URL } from '@env';
import { useFocusEffect } from '@react-navigation/native';

export default function AllTasksScreen({ navigation, route }) {
const [tasks, setTasks] = useState([]);
const [refreshing, setRefreshing] = useState(false);
const [currentWeek, setCurrentWeek] = useState(route.params?.week || 1);
const [filter, setFilter] = useState('all'); // all, pending, completed

useEffect(() => {
fetchTasks();
}, []);
useFocusEffect(
useCallback(() => {
fetchTasks();
}, [])
);

const fetchTasks = async () => {
try {
Expand Down
11 changes: 7 additions & 4 deletions Frontend/src/Screens/BloodPressureScreen.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react';
import React, {useState, useEffect, useCallback} from 'react';
import {
View,
ScrollView,
Expand All @@ -11,6 +11,7 @@ import Icon from 'react-native-vector-icons/Ionicons';
import {TextInput, Button, Card, Portal, Dialog} from 'react-native-paper';
import HeaderWithBack from '../Components/HeaderWithBack';
import {BASE_URL} from '@env';
import {useFocusEffect} from '@react-navigation/native';

export default function BloodPressureScreen() {
const [week, setWeek] = useState('');
Expand All @@ -35,9 +36,11 @@ export default function BloodPressureScreen() {
}
};

useEffect(() => {
fetchBPLogs();
}, []);
useFocusEffect(
useCallback(() => {
fetchBPLogs();
}, [])
);

const handleRefresh = async () => {
setRefreshing(true);
Expand Down
Loading