diff --git a/.DS_Store b/.DS_Store
index 953c41e94..eac18c8ef 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..8bc141ad2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+#Hides CSRF key
+.env
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 000000000..105ce2da2
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 000000000..db8786c06
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index b2588bc51..02b468505 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,20 @@
-My groupmembers are:
-- XXXX
-- XXXX
-- XXXX
-- XXXX
+Team Penguin Members:
+- Jo Vinson
+- Andrew Dickerson
+- Ben Karp
+- Arth Chavda
+- Nasmir Pasic
+- Owen Cosner
------------------- Fill in some information about your project under this ------------------
+------------------ Project Summary ------------------
+
+A medical records sharing platform, supporting both emergency sharing and recipient specified sharing.
+
+The program has a web front end, with different portals for doctors and patients. Patients are able to fill in and create medical fields or upload a pdf, which then fills in for a sql table on a database. Patients are also able to search for and share documents with doctors that have public accounts on the site, and patients have the ability to create emergency keys, in the form of qr codes, to enable doctors to access their records without sharing access.
+
+The web app contains an AI tool which helps provide a quick summary of a patient’s medical history for doctors who need quick access to specific information.
+
+Doctors have the ability to edit records which are shared with them, and can access new records using an emergency key.
+
+Both types of accounts can set their privacy status to public or private, to enable or disable new accounts from sharing/accessing documents with them. Accounts are created using an email, which is sent a verification email, and can be deleted.
diff --git a/Requirements Specifications.pdf b/Requirements Specifications.pdf
new file mode 100644
index 000000000..823423f7e
Binary files /dev/null and b/Requirements Specifications.pdf differ
diff --git a/Sprint 1/Flask Backend/.DS_Store b/Sprint 1/Flask Backend/.DS_Store
new file mode 100644
index 000000000..387c0a35d
Binary files /dev/null and b/Sprint 1/Flask Backend/.DS_Store differ
diff --git a/Sprint 1/Flask Backend/.env b/Sprint 1/Flask Backend/.env
new file mode 100644
index 000000000..727096334
--- /dev/null
+++ b/Sprint 1/Flask Backend/.env
@@ -0,0 +1 @@
+CONFIG_KEY="W<0:2e?Qr9)cA{:3|~T*5%ZxS"
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/AssignmentRepo355 b/Sprint 1/Flask Backend/AssignmentRepo355
new file mode 160000
index 000000000..d4c328b20
--- /dev/null
+++ b/Sprint 1/Flask Backend/AssignmentRepo355
@@ -0,0 +1 @@
+Subproject commit d4c328b207cb456c03b281dae9f6b2f9c36dfc1f
diff --git a/Sprint 1/Flask Backend/app.py b/Sprint 1/Flask Backend/app.py
new file mode 100644
index 000000000..3bd6363d6
--- /dev/null
+++ b/Sprint 1/Flask Backend/app.py
@@ -0,0 +1,178 @@
+from flask import Flask, render_template, request, redirect, url_for, jsonify
+from flask_bcrypt import Bcrypt
+from wtforms import StringField, PasswordField, SubmitField, RadioField, validators
+from flask_wtf import FlaskForm, CSRFProtect
+from wtforms.validators import EqualTo, InputRequired
+import jinja2
+import mysql
+from pyModules.sqlpy.connectToDB import connectDatabase
+from pyModules.sqlpy.createAccountRow import addNewUser
+from pyModules.sqlpy.fetchData import fetchUserData
+from pyModules.sqlpy.saveData import saveUserData
+from pyModules.sqlpy.fetchAccessMap import fetchAccessMap
+import os
+from dotenv import load_dotenv
+
+app = Flask(__name__)
+load_dotenv()
+app.config["SECRET_KEY"] = os.getenv("CONFIG_KEY")
+csrf = CSRFProtect(app)
+bcrypt = Bcrypt(app)
+
+@app.route("/")
+def home():
+ return render_template("home.html")
+
+@app.route("/signup_page", methods = ['GET', 'POST'])
+def signup():
+ patient_or_provider = None
+ first_name = None
+ last_name = None
+ phone_number = None
+ user_email = None
+ password = None
+
+ sign_up_form = SignUp()
+ if request.method == "POST":
+ if sign_up_form.validate_on_submit():
+ patient_or_provider = sign_up_form.patient_or_provider.data
+ first_name = sign_up_form.first_name.data
+ last_name = sign_up_form.last_name.data
+ phone_number = sign_up_form.phone_number.data
+ user_email = sign_up_form.user_email.data
+ password = sign_up_form.password.data
+ hashed_password = bcrypt.generate_password_hash(sign_up_form.password.data).decode('utf-8')
+ password = hashed_password
+
+
+ addNewUser(first_name,
+ last_name,
+ user_email,
+ phone_number,
+ password,
+ patient_or_provider,
+ connectDatabase()
+ )
+
+ return render_template("signup_page.html", patient_or_provider = patient_or_provider, first_name = first_name, last_name = last_name,
+ user_email = user_email, phone_number = phone_number, password = password,
+ form = sign_up_form)
+
+@app.route("/login_page", methods = ['GET', 'POST'])
+def login():
+ email_login = None
+ password_login = None
+
+ login_form = LogIn()
+ if request.method == "POST":
+ if login_form.validate_on_submit():
+ email_login = login_form.email_login.data
+ password_login = login_form.password_login.data
+
+ #TODO: We need to validate the email and password against the database here
+ #If validated and the user is a doctor, redirect to doctor page
+ #If validated and the user is a patient, redirect to patient page
+ #Jo work your magic
+
+ return redirect(url_for("provider", email=email_login))
+
+ return render_template("login_page.html", email_login = email_login, password_login = password_login,
+ form = login_form)
+
+@app.route("/edit_record_page")
+def edit_record_page():
+ return render_template("edit_record_page.html")
+
+# Get patient data for edit_record_page
+@app.route("/api/get_patient")
+def api_get_patient():
+ email = request.args.get("email")
+
+ db = connectDatabase()
+ result = fetchUserData(email, db)
+
+ if result:
+ return jsonify(result)
+
+ return jsonify({"error": "Could not fetch user"}), 400
+
+# Save updated patient data from edit_record_page
+@app.route("/api/update_record", methods=["POST"])
+def api_update_record():
+ print("test")
+
+ data = request.get_json()
+ updated_fields = data.get("updated_fields")
+ email = data.get("email")
+
+ for column, value in updated_fields.items():
+ saveUserData(userEmail=email,
+ dbConnection=connectDatabase(),
+ columnToSet=column,
+ valueToSet=value)
+
+ return jsonify({"message": "Record saved"})
+
+@app.route('/provider_portal')
+def provider():
+ doctor_email = request.args.get("email")
+ return render_template('provider_homepage.html', doctor_email=doctor_email)
+
+# Fetch patients or doctors from accessMap
+@app.route("/api/fetch_access_map")
+def api_fetch_access_map():
+ user_email = request.args.get("email")
+ user_type = request.args.get("type", "doctor").lower() # default to doctor
+
+ # Validate type
+ if user_type not in ["doctor", "patient"]:
+ return jsonify({"error": "Invalid type. Use 'doctor' or 'patient'."}), 400
+
+ db = connectDatabase()
+
+ try:
+ result = fetchAccessMap(user_email, db, user_type)
+
+ # Expecting a list of tuples: [("First","Last","email"), ...]
+ return jsonify(result)
+
+ except Exception as e:
+ print("ERROR:", e)
+ return jsonify({"error": "Failed to fetch access map"}), 500
+
+class SignUp(FlaskForm):
+ patient_or_provider = RadioField("Are you a patient or a provider?", choices=[('patient', 'Patient'), ('provider', 'Provider')], validators=[InputRequired()])
+
+ first_name = StringField("Enter your first name", validators = [validators.DataRequired(message = "First name is required")], render_kw = {'placeholder': "John"})
+
+ last_name = StringField("Enter your last name", validators = [validators.DataRequired(message = "Last name is required")], render_kw = {'placeholder': "Doe"})
+
+ phone_number = StringField("Phone number", validators = [validators.DataRequired(message = "Phone number is required"),
+ validators.Length(min = 10, message = "Must be at least 10 characters"),
+ validators.Regexp(r'^\(\d{3}\)\s?\d{3}-\d{4}$',
+ message="Invalid phone number format. Use (123) 456-7890")
+ ], render_kw = {'placeholder': "(000) 000-0000"})
+ user_email = StringField("Email", validators = [validators.DataRequired(), validators.Email("Must be a valid email")], render_kw = {'placeholder': "example@email.com"})
+
+ password = PasswordField("Create a unique password.", validators = [validators.DataRequired(message = "Please enter a password"),
+ validators.Length(min = 8, max = 20, message = "Please enter a password between 8 and 20 characters"),
+ validators.Regexp(r'^(?=.*[A-Z])(?=.*[!@#$%^+=-])(?=.{8,20}$)[^{}[\]<|*&"()]*$', message = "Please enter a valid password. Valid special characters are @, #, !, $, -, or _"),
+ EqualTo('confirm_password', message="Passwords must match")],
+ render_kw = {'placeholder': "8-20 characters long, one capital letter, one special character"})
+
+ confirm_password = PasswordField("Confirm your password", validators = [validators.DataRequired(message="Please confirm your password")
+ ], render_kw={'placeholder': "Re-enter your password"})
+
+ submit_button = SubmitField("Submit")
+
+class LogIn(FlaskForm):
+ email_login = StringField("Email", validators=[validators.DataRequired(message="Please enter your email"),validators.Email("Must be a valid email")],
+ render_kw={'placeholder': "Enter your email"})
+ password_login = PasswordField("Password.", validators = [validators.DataRequired(message = "Please enter your password"),
+ validators.Length(min = 8, max = 20, message = "Must be between 8 and 20 characters"),
+ validators.Regexp(r'^(?=.*[A-Z])(?=.*[!@#$%^+=-])(?=.{8,20}$)[^{}[\]<|*&"()]*$', message = "Invalid format.")], render_kw={'placeholder': "Enter your password"})
+
+ submit_button = SubmitField("Submit")
+
+if __name__ == "__main__":
+ app.run(debug = True)
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/pyModules/__init__.py b/Sprint 1/Flask Backend/pyModules/__init__.py
new file mode 100644
index 000000000..2998d420d
--- /dev/null
+++ b/Sprint 1/Flask Backend/pyModules/__init__.py
@@ -0,0 +1 @@
+__all__ = ["sqlpy"]
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/pyModules/__pycache__/__init__.cpython-313.pyc b/Sprint 1/Flask Backend/pyModules/__pycache__/__init__.cpython-313.pyc
new file mode 100644
index 000000000..89a288e5a
Binary files /dev/null and b/Sprint 1/Flask Backend/pyModules/__pycache__/__init__.cpython-313.pyc differ
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/__init__.py b/Sprint 1/Flask Backend/pyModules/sqlpy/__init__.py
new file mode 100644
index 000000000..1c725632a
--- /dev/null
+++ b/Sprint 1/Flask Backend/pyModules/sqlpy/__init__.py
@@ -0,0 +1 @@
+__all__ = ["connectToDB" "createAccountRow"]
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/__init__.cpython-313.pyc b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/__init__.cpython-313.pyc
new file mode 100644
index 000000000..59dd14f56
Binary files /dev/null and b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/__init__.cpython-313.pyc differ
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/connectToDB.cpython-313.pyc b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/connectToDB.cpython-313.pyc
new file mode 100644
index 000000000..b71298665
Binary files /dev/null and b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/connectToDB.cpython-313.pyc differ
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/createAccountRow.cpython-313.pyc b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/createAccountRow.cpython-313.pyc
new file mode 100644
index 000000000..64e991eae
Binary files /dev/null and b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/createAccountRow.cpython-313.pyc differ
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/fetchAccessMap.cpython-313.pyc b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/fetchAccessMap.cpython-313.pyc
new file mode 100644
index 000000000..ae3d3ee74
Binary files /dev/null and b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/fetchAccessMap.cpython-313.pyc differ
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/fetchData.cpython-313.pyc b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/fetchData.cpython-313.pyc
new file mode 100644
index 000000000..08c3f8fd1
Binary files /dev/null and b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/fetchData.cpython-313.pyc differ
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/saveData.cpython-313.pyc b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/saveData.cpython-313.pyc
new file mode 100644
index 000000000..d024a9d4f
Binary files /dev/null and b/Sprint 1/Flask Backend/pyModules/sqlpy/__pycache__/saveData.cpython-313.pyc differ
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/connectToDB.py b/Sprint 1/Flask Backend/pyModules/sqlpy/connectToDB.py
new file mode 100644
index 000000000..d71ffdef2
--- /dev/null
+++ b/Sprint 1/Flask Backend/pyModules/sqlpy/connectToDB.py
@@ -0,0 +1,25 @@
+from mysql import connector
+
+
+def connectDatabase(user = "root",
+ password = "r39Cfz1BE%n&al",
+ host = "127.0.0.1",
+ database = "medicalrecords",
+ raiseOnWarnings = True
+ ):
+
+ connectionConfig = {
+ 'user': user,
+ 'password': password,
+ 'host': host,
+ 'database': database,
+ 'raise_on_warnings': raiseOnWarnings
+ }
+
+ dbConnection = connector.connect(**connectionConfig)
+
+ return dbConnection
+
+
+def disconnectDatabase(connectionToClose):
+ connectionToClose.close()
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/createAccountRow.py b/Sprint 1/Flask Backend/pyModules/sqlpy/createAccountRow.py
new file mode 100644
index 000000000..469a5e099
--- /dev/null
+++ b/Sprint 1/Flask Backend/pyModules/sqlpy/createAccountRow.py
@@ -0,0 +1,62 @@
+from mysql import connector
+from mysql.connector import errorcode
+import mysql
+
+
+def addNewUser( firstName,
+ lastName,
+ userEmail,
+ phoneNumber,
+ password,
+ PatientOrProvider,
+ dbConnection
+ ):
+
+ returnVal = 1
+
+ addUser = ("INSERT INTO users"
+ "(Email, First_Name, Last_Name, PasswordHash, Phone_Number, PatientOrProvider)"
+ "VALUES ((%(EmailVal)s)," \
+ "(%(First_NameVal)s)," \
+ "(%(Last_NameVal)s)," \
+ "(%(PasswordVal)s)," \
+ "(%(Phone_NumberVal)s)," \
+ "(%(PatientOrProviderVal)s))"
+ )
+
+
+
+
+
+ dataUser = {
+ 'EmailVal': userEmail,
+ 'First_NameVal': firstName,
+ 'Last_NameVal': lastName,
+ 'PasswordVal': password,
+ 'Phone_NumberVal': phoneNumber,
+ 'PatientOrProviderVal': PatientOrProvider
+ }
+
+
+ cursor = dbConnection.cursor()
+
+ try:
+ cursor.execute(addUser, dataUser)
+ except mysql.connector.Error as err:
+ if err.errno == 1062:
+ returnVal = 2
+
+ try:
+ dbConnection.commit()
+ except mysql.connector.Error as err:
+ if err.errno == 1062:
+ returnVal = 3
+
+ cursor.close() # close cursor
+ dbConnection.close() # close connection
+
+ return returnVal
+
+
+def addNewUserTest():
+ print("import successful! :)")
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/fetchAccessMap.py b/Sprint 1/Flask Backend/pyModules/sqlpy/fetchAccessMap.py
new file mode 100644
index 000000000..aba2c12d9
--- /dev/null
+++ b/Sprint 1/Flask Backend/pyModules/sqlpy/fetchAccessMap.py
@@ -0,0 +1,45 @@
+from mysql import connector
+
+def fetchAccessMap(userEmail,
+ dbConnection,
+ patientOrDoctor # "doctor" or "patient"
+ ):
+
+ cursor = dbConnection.cursor()
+
+ if patientOrDoctor == "doctor":
+ query = ("SELECT u.First_Name, u.Last_Name, u.Email FROM users u "
+ "JOIN accessMap AM "
+ "ON AM.patient = u.Email "
+ "WHERE AM.doctor = %(EmailVal)s"
+ )
+ else:
+ query = ("SELECT u.First_Name, u.Last_Name, u.Email FROM users u "
+ "JOIN accessMap AM "
+ "ON AM.doctor = u.Email "
+ "WHERE AM.patient = %(EmailVal)s"
+ )
+
+
+ queryData = {
+ 'EmailVal': userEmail
+ } # user primary key
+
+ try:
+ cursor.execute(query, queryData) # execute the changes
+ except:
+ return 2 #errorval
+
+
+ returnList = []
+ for (First_Name, Last_Name, Email) in cursor:
+ # iterate through a set of tuples
+ # the tuples are the rows
+ returnList.append((First_Name, Last_Name, Email))
+
+
+ cursor.close() # close cursor
+ dbConnection.close() # close connection
+
+ return returnList #return the map
+
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/fetchData.py b/Sprint 1/Flask Backend/pyModules/sqlpy/fetchData.py
new file mode 100644
index 000000000..bedc7984b
--- /dev/null
+++ b/Sprint 1/Flask Backend/pyModules/sqlpy/fetchData.py
@@ -0,0 +1,48 @@
+from mysql import connector
+
+def fetchUserData(userEmail,
+ dbConnection
+ ):
+
+ cursor = dbConnection.cursor()
+
+ query = ("SELECT First_Name, Last_Name, Age, Phone_Number, Sex, Weight, Height, Medications, Allergies, Active_Problems, "
+ "Medical_History, Family_History, Date_Updated FROM users "
+ "WHERE Email = %(emailVal)s") # fetch user data
+
+ queryData = {
+ 'emailVal': userEmail
+ } # user primary key
+
+ try:
+ cursor.execute(query, queryData) # execute the changes
+ except:
+ return 2 #errorval
+
+ returnMap = {}
+ for (First_Name, Last_Name, Age, Phone_Number, Sex, Weight, Height, Medications, Allergies, Active_Problems, Medical_History,
+ Family_History, Date_Updated) in cursor:
+ # iterate through a set of tuples
+ # the tuples are the rows, but we only fetched one
+ returnMap = {
+ 'First_Name': First_Name,
+ 'Last_Name': Last_Name,
+ 'Age': Age,
+ 'Phone_Number': Phone_Number,
+ 'Sex' : Sex,
+ 'Weight': Weight,
+ 'Height': Height,
+ 'Medications': Medications,
+ 'Allergies': Allergies,
+ 'Active_Problems': Active_Problems,
+ 'Medical_History': Medical_History,
+ 'Family_History': Family_History,
+ 'Date_Updated': Date_Updated
+ } # make a return map for the row
+
+
+ cursor.close() # close cursor
+ dbConnection.close() # close connection
+
+ # Updated to stop it from sorting alphabetically
+ return [{"field": k, "value": v} for k, v in returnMap.items()]
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/pyModules/sqlpy/saveData.py b/Sprint 1/Flask Backend/pyModules/sqlpy/saveData.py
new file mode 100644
index 000000000..a7cdd2591
--- /dev/null
+++ b/Sprint 1/Flask Backend/pyModules/sqlpy/saveData.py
@@ -0,0 +1,48 @@
+from mysql import connector
+
+def saveUserData(userEmail,
+ dbConnection,
+ columnToSet,
+ valueToSet
+ ):
+
+
+ # 1. WHITELIST columns (CRITICALLY IMPORTANT)
+ allowed_columns = {"First_Name", "Last_Name", "Phone_Number", "Age", "Address", "PasswordHash", "Sex", "Weight", "Height",
+ "Medications", "Allergies", "Active_Problems", "Medical_History", "Family_History", "Date_Updated"}
+ if columnToSet not in allowed_columns:
+ raise ValueError(f"Invalid or unsafe column name: {columnToSet}")
+
+
+ cursor = dbConnection.cursor() # make cursor
+
+ query = ("UPDATE users "
+ f"SET {columnToSet} = %(changeVal)s "
+ "WHERE Email = %(emailVal)s") # sql update stmt
+
+ queryData = {
+ 'changeVal': valueToSet,
+ 'emailVal': userEmail
+ } # sql updata vals
+
+ try:
+ cursor.execute(query, queryData) # execute stmt
+ except:
+ return 2
+
+ if cursor.rowcount == 0:
+ print("no rows")
+ return {"status": 4, "error": "No user with that email"}
+
+
+ try:
+ dbConnection.commit()
+ except:
+ return 3
+
+ cursor.close() # close cursor
+ dbConnection.close() # close connection
+
+
+ return 1
+
diff --git a/Sprint 1/Flask Backend/templates/edit_record_page.html b/Sprint 1/Flask Backend/templates/edit_record_page.html
new file mode 100644
index 000000000..7a018baf0
--- /dev/null
+++ b/Sprint 1/Flask Backend/templates/edit_record_page.html
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading patient record...
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/templates/home.html b/Sprint 1/Flask Backend/templates/home.html
new file mode 100644
index 000000000..1506c5684
--- /dev/null
+++ b/Sprint 1/Flask Backend/templates/home.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Penguin Care
+
+
+
+
Welcome to Penguin Care
+
+
+
+
+ Sign Up
+ Login
+
+
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/templates/login_page.html b/Sprint 1/Flask Backend/templates/login_page.html
new file mode 100644
index 000000000..10b41897d
--- /dev/null
+++ b/Sprint 1/Flask Backend/templates/login_page.html
@@ -0,0 +1,39 @@
+
+
+
+
+ Login
+
+
+ Welcome back
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/templates/patient_homepage.html b/Sprint 1/Flask Backend/templates/patient_homepage.html
new file mode 100644
index 000000000..f8290610a
--- /dev/null
+++ b/Sprint 1/Flask Backend/templates/patient_homepage.html
@@ -0,0 +1,24 @@
+
+
+
+
+ Patient Homepage
+
+
+
+
+
+
Welcome To Your Homepage!
+
+
+
+
+
+
+
diff --git a/Sprint 1/Flask Backend/templates/provider_homepage.html b/Sprint 1/Flask Backend/templates/provider_homepage.html
new file mode 100644
index 000000000..0c0bfa6f7
--- /dev/null
+++ b/Sprint 1/Flask Backend/templates/provider_homepage.html
@@ -0,0 +1,181 @@
+
+
+
+
+ Provider Portal
+
+
+
+ Provider Portal
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sprint 1/Flask Backend/templates/signup_page.html b/Sprint 1/Flask Backend/templates/signup_page.html
new file mode 100644
index 000000000..37953f983
--- /dev/null
+++ b/Sprint 1/Flask Backend/templates/signup_page.html
@@ -0,0 +1,78 @@
+
+
+
+
+ Signup
+
+
+ Enter your information below
+
+
+
+
\ No newline at end of file
diff --git a/Sprint 1/codePlaceHolder.txt b/Sprint 1/codePlaceHolder.txt
deleted file mode 100644
index e69de29bb..000000000
diff --git a/Sprint 1/demoForSprint1.mkv b/Sprint 1/demoForSprint1.mkv
new file mode 100644
index 000000000..d3f5a12fa
--- /dev/null
+++ b/Sprint 1/demoForSprint1.mkv
@@ -0,0 +1 @@
+
diff --git a/Sprint 1/sqlCode/addNewUserFields.sql b/Sprint 1/sqlCode/addNewUserFields.sql
new file mode 100644
index 000000000..892ab6a8f
--- /dev/null
+++ b/Sprint 1/sqlCode/addNewUserFields.sql
@@ -0,0 +1,11 @@
+ALTER TABLE users ADD COLUMN Sex VARCHAR(20);
+ALTER TABLE users ADD COLUMN Weight VARCHAR(20);
+ALTER TABLE users ADD COLUMN Height VARCHAR(20);
+
+ALTER TABLE users ADD COLUMN Medications TEXT;
+ALTER TABLE users ADD COLUMN Allergies TEXT;
+ALTER TABLE users ADD COLUMN Active_Problems TEXT;
+ALTER TABLE users ADD COLUMN Medical_History TEXT;
+ALTER TABLE users ADD COLUMN Family_History TEXT;
+
+ALTER TABLE users ADD COLUMN Date_Updated DATETIME;
\ No newline at end of file
diff --git a/Sprint 1/sqlCode/createAccessTable.sql b/Sprint 1/sqlCode/createAccessTable.sql
new file mode 100644
index 000000000..e1343d98f
--- /dev/null
+++ b/Sprint 1/sqlCode/createAccessTable.sql
@@ -0,0 +1,7 @@
+CREATE TABLE accessMap (
+ connectionUID VARCHAR(50) PRIMARY KEY,
+
+ doctor VARCHAR(50) NOT NULL,
+
+ patient VARCHAR(50) NOT NULL
+)
\ No newline at end of file
diff --git a/Sprint 1/sqlCode/createDB.sql b/Sprint 1/sqlCode/createDB.sql
new file mode 100644
index 000000000..4750c1869
--- /dev/null
+++ b/Sprint 1/sqlCode/createDB.sql
@@ -0,0 +1 @@
+CREATE DATABASE MedicalRecords;
\ No newline at end of file
diff --git a/Sprint 1/sqlCode/createUsersTable.sql b/Sprint 1/sqlCode/createUsersTable.sql
new file mode 100644
index 000000000..a15129458
--- /dev/null
+++ b/Sprint 1/sqlCode/createUsersTable.sql
@@ -0,0 +1,29 @@
+CREATE TABLE users (
+ Email VARCHAR(50) PRIMARY KEY,
+ IsRegistered BOOLEAN,
+
+ First_Name VARCHAR(50),
+ MiddleNameOrInitial VARCHAR(50),
+ Last_Name VARCHAR(50),
+
+ PasswordHash VARCHAR(100) NOT NULL,
+
+ Age INT,
+
+ Phone_Number VARCHAR(15),
+
+ PatientOrProvider VARCHAR(8),
+
+ Sex VARCHAR(20),
+
+ Weight VARCHAR(20),
+ Height VARCHAR(20),
+
+ Medications TEXT,
+ Allergies TEXT,
+ Active_Problems TEXT,
+ Medical_History TEXT,
+ Family_History TEXT,
+
+ Date_Updated DATETIME
+)
\ No newline at end of file
diff --git a/Sprint 1/sqlCode/fillDbForTests.sql b/Sprint 1/sqlCode/fillDbForTests.sql
new file mode 100644
index 000000000..a5f021671
--- /dev/null
+++ b/Sprint 1/sqlCode/fillDbForTests.sql
@@ -0,0 +1,13 @@
+INSERT INTO users (Email, First_Name, Last_Name, PatientOrProvider, PasswordHash)
+
+VALUES ('bob@bob.com', 'Bobf', 'Bobl', 'patient', '$2b$12$Vam60GL5xHEvpq/6EfMINOByfVe/7.tBwWBY/jhIPgroXT28yxUmO'),
+ ('sally@sally.com', 'Sallyf', 'Sallyl', 'provider', '$2b$12$Vam60GL5xHEvpq/6EfMINOByfVe/7.tBwWBY/jhIPgroXT28yxUmO'),
+ ('jimothy@jimothy.com', 'jimothyf', 'jimmothyl', 'patient', '$2b$12$Vam60GL5xHEvpq/6EfMINOByfVe/7.tBwWBY/jhIPgroXT28yxUmO');
+
+
+
+INSERT INTO accessMap (connectionUID, doctor, patient)
+
+VALUES ('1', 'sally@sally.com','bob@bob.com'),
+ ('2','sally@sally.com','jimothy@jimothy.com');
+
diff --git a/Sprint 1/testCases.pdf b/Sprint 1/testCases.pdf
new file mode 100644
index 000000000..1e337cbff
Binary files /dev/null and b/Sprint 1/testCases.pdf differ
diff --git a/Sprint 1/videoPlaceholder.txt b/Sprint 1/videoPlaceholder.txt
deleted file mode 100644
index e69de29bb..000000000
diff --git a/Sprint 2/Sprint 2 Test Cases.pdf b/Sprint 2/Sprint 2 Test Cases.pdf
new file mode 100644
index 000000000..9c57422f7
Binary files /dev/null and b/Sprint 2/Sprint 2 Test Cases.pdf differ
diff --git a/Sprint 2/Sprint2TestCases.mkv b/Sprint 2/Sprint2TestCases.mkv
new file mode 100644
index 000000000..91bd17aa1
Binary files /dev/null and b/Sprint 2/Sprint2TestCases.mkv differ
diff --git a/Sprint 2/TestCasesPlaceholder.txt b/Sprint 2/TestCasesPlaceholder.txt
deleted file mode 100644
index e69de29bb..000000000
diff --git a/Sprint 2/codePlaceHolder.txt b/Sprint 2/codePlaceHolder.txt
deleted file mode 100644
index e69de29bb..000000000
diff --git a/Sprint 2/videoPlaceholder.txt b/Sprint 2/videoPlaceholder.txt
deleted file mode 100644
index e69de29bb..000000000
diff --git a/documentation/planning.txt b/documentation/planning.txt
new file mode 100644
index 000000000..c7ae27009
--- /dev/null
+++ b/documentation/planning.txt
@@ -0,0 +1,4 @@
+Web framework: flask
+Database: SQLite/PostgreSQL
+RestApi: flask-restful/restx/other
+Python sql toolkit: SQLAlchemy
diff --git a/documentation/process diagrams/coding and testing process.pdf b/documentation/process diagrams/coding and testing process.pdf
new file mode 100644
index 000000000..2cdd9cddb
Binary files /dev/null and b/documentation/process diagrams/coding and testing process.pdf differ
diff --git a/documentation/process diagrams/deployment process.pdf b/documentation/process diagrams/deployment process.pdf
new file mode 100644
index 000000000..252f40706
Binary files /dev/null and b/documentation/process diagrams/deployment process.pdf differ
diff --git a/documentation/process diagrams/requirements design process.pdf b/documentation/process diagrams/requirements design process.pdf
new file mode 100644
index 000000000..7f9d20134
Binary files /dev/null and b/documentation/process diagrams/requirements design process.pdf differ
diff --git a/documentation/process diagrams/software design process.pdf b/documentation/process diagrams/software design process.pdf
new file mode 100644
index 000000000..7ed00d7a9
Binary files /dev/null and b/documentation/process diagrams/software design process.pdf differ
diff --git a/Sprint 1/TestCasesPlaceholder.txt b/documentation/requirements specifications/requirements.txt
similarity index 100%
rename from Sprint 1/TestCasesPlaceholder.txt
rename to documentation/requirements specifications/requirements.txt
diff --git a/documentation/requirements specifications/requirementsSpecificationRawPDF.pdf b/documentation/requirements specifications/requirementsSpecificationRawPDF.pdf
new file mode 100644
index 000000000..b7785aaaa
Binary files /dev/null and b/documentation/requirements specifications/requirementsSpecificationRawPDF.pdf differ