diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000..13566b81b0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
new file mode 100644
index 0000000000..03518d64e9
--- /dev/null
+++ b/.idea/checkstyle-idea.xml
@@ -0,0 +1,15 @@
+
+
+
+ 10.21.3
+ JavaOnly
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000..8d66637cb9
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000000..0e1c4ec56e
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000..db0dbf211e
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000..ffe66c2d43
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/team3-10-child-therapy-database.iml b/.idea/team3-10-child-therapy-database.iml
new file mode 100644
index 0000000000..d6ebd48059
--- /dev/null
+++ b/.idea/team3-10-child-therapy-database.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000..35eb1ddfbb
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 5582fd65c2..02544e558f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,11 @@
# Spring 2025 CS 3200 Project Template Repository
-This repo is a template for your semester project. It includes most of the infrastructure setup (containers), sample databases, and example UI pages. Explore it fully and ask questions!
+This repo is a template for your semester project. It includes most of the infrastructure setup (containers), sample
+databases, and example UI pages. Explore it fully and ask questions!
+
+## Overview
+
+Our project is a Child Therapist Database built around our five personas: a therapist, an art therapist specialist, a child, a guardian, and an art therapist specialist. We incorporated numerous attributes with these entities, including phone numbers, emails, names, and unique identifiers. Our database's purpose is to assist matching virtual children with therapists based on their individual art preferences, chronic conditions, personality traits, and context-aware replies.
## Prerequisites
@@ -19,12 +24,18 @@ Currently, there are three major components that will each run in their own Dock
## Suggestion for Learning the Project Code Base
-If you are not familiar with web app development, this code base might be confusing. But don't worry, it's not that bad. Here are some suggestions for learning the code base:
+If you are not familiar with web app development, this code base might be confusing. But don't worry, it's not that bad.
+Here are some suggestions for learning the code base:
-1. Have two versions of the template repo - one for you to individually explore and lear and another for the team's project implementation.
-1. Start by exploring the `./app` directory. This is where the Streamlit app is located. The Streamlit app is a Python-based web app that is used to interact with the user. It's a great way to build a simple web app without having to learn a lot of web development.
-1. Next, explore the `./api` directory. This is where the Flask REST API is located. The REST API is used to interact with the database and perform other server-side tasks.
-1. Finally, explore the `./database-files` directory. This is where the SQL scripts are located that will be used to initialize the MySQL database.
+1. Have two versions of the template repo - one for you to individually explore and lear and another for the team's
+ project implementation.
+1. Start by exploring the `./app` directory. This is where the Streamlit app is located. The Streamlit app is a
+ Python-based web app that is used to interact with the user. It's a great way to build a simple web app without
+ having to learn a lot of web development.
+1. Next, explore the `./api` directory. This is where the Flask REST API is located. The REST API is used to interact
+ with the database and perform other server-side tasks.
+1. Finally, explore the `./database-files` directory. This is where the SQL scripts are located that will be used to
+ initialize the MySQL database.
### Setting Up Your Personal Repo
@@ -32,54 +43,88 @@ If you are not familiar with web app development, this code base might be confus
1. When prompted, give the new repo a unique name, perhaps including your last name and the word 'personal'.
1. Once the fork has been created, clone YOUR forked version of the repo to your computer.
1. Set up the `.env` file in the `api` folder based on the `.env.template` file.
-1. For running the testing containers (for your personal repo), you will tell `docker compose` to use a different configuration file named `docker-compose-testing.yaml`.
- 1. `docker compose -f docker-compose-testing.yaml up -d` to start all the containers in the background
- 1. `docker compose -f docker-compose-testing.yaml down` to shutdown and delete the containers
- 1. `docker compose -f docker-compose-testing.yaml up db -d` only start the database container (replace db with api or app for the other two services as needed)
- 1. `docker compose -f docker-compose-testing.yaml stop` to "turn off" the containers but not delete them.
+1. For running the testing containers (for your personal repo), you will tell `docker compose` to use a different
+ configuration file named `docker-compose-testing.yaml`.
+ 1. `docker compose -f docker-compose-testing.yaml up -d` to start all the containers in the background
+ 1. `docker compose -f docker-compose-testing.yaml down` to shutdown and delete the containers
+ 1. `docker compose -f docker-compose-testing.yaml up db -d` only start the database container (replace db with api
+ or app for the other two services as needed)
+ 1. `docker compose -f docker-compose-testing.yaml stop` to "turn off" the containers but not delete them.
### Setting Up Your Team's Repo
**Before you start**: As a team, one person needs to assume the role of _Team Project Repo Owner_.
-1. The Team Project Repo Owner needs to fork this template repo into their own GitHub account **and give the repo a name consistent with your project's name**. If you're worried that the repo is public, don't. Every team is doing a different project.
-1. In the newly forked team repo, the Team Project Repo Owner should go to the **Settings** tab, choose **Collaborators and Teams** on the left-side panel. Add each of your team members to the repository with Write access.
+1. The Team Project Repo Owner needs to fork this template repo into their own GitHub account **and give the repo a name
+ consistent with your project's name**. If you're worried that the repo is public, don't. Every team is doing a
+ different project.
+1. In the newly forked team repo, the Team Project Repo Owner should go to the **Settings** tab, choose **Collaborators
+ and Teams** on the left-side panel. Add each of your team members to the repository with Write access.
**Remaining Team Members**
1. Each of the other team members will receive an invitation to join. Obviously accept the invite.
-1. Once that process is complete, each team member, including the repo owner, should clone the Team's Repo to their local machines (in a different location your Personal Project Repo).
+1. Once that process is complete, each team member, including the repo owner, should clone the Team's Repo to their
+ local machines (in a different location your Personal Project Repo).
1. Set up the `.env` file in the `api` folder based on the `.env.template` file.
1. For running the testing containers (for your team's repo):
- 1. `docker compose up -d` to start all the containers in the background
- 1. `docker compose down` to shutdown and delete the containers
- 1. `docker compose up db -d` only start the database container (replace db with api or app for the other two services as needed)
- 1. `docker compose stop` to "turn off" the containers but not delete them.
+ 1. `docker compose up -d` to start all the containers in the background
+ 1. `docker compose down` to shutdown and delete the containers
+ 1. `docker compose up db -d` only start the database container (replace db with api or app for the other two
+ services as needed)
+ 1. `docker compose stop` to "turn off" the containers but not delete them.
**Note:** You can also use the Docker Desktop GUI to start and stop the containers after the first initial run.
## Handling User Role Access and Control
-In most applications, when a user logs in, they assume a particular role. For instance, when one logs in to a stock price prediction app, they may be a single investor, a portfolio manager, or a corporate executive (of a publicly traded company). Each of those _roles_ will likely present some similar features as well as some different features when compared to the other roles. So, how do you accomplish this in Streamlit? This is sometimes called Role-based Access Control, or **RBAC** for short.
+In most applications, when a user logs in, they assume a particular role. For instance, when one logs in to a stock
+price prediction app, they may be a single investor, a portfolio manager, or a corporate executive (of a publicly traded
+company). Each of those _roles_ will likely present some similar features as well as some different features when
+compared to the other roles. So, how do you accomplish this in Streamlit? This is sometimes called Role-based Access
+Control, or **RBAC** for short.
-The code in this project demonstrates how to implement a simple RBAC system in Streamlit but without actually using user authentication (usernames and passwords). The Streamlit pages from the original template repo are split up among 3 roles - Political Strategist, USAID Worker, and a System Administrator role (this is used for any sort of system tasks such as re-training ML model, etc.). It also demonstrates how to deploy an ML model.
+The code in this project demonstrates how to implement a simple RBAC system in Streamlit but without actually using user
+authentication (usernames and passwords). The Streamlit pages from the original template repo are split up among 3
+roles - Political Strategist, USAID Worker, and a System Administrator role (this is used for any sort of system tasks
+such as re-training ML model, etc.). It also demonstrates how to deploy an ML model.
Wrapping your head around this will take a little time and exploration of this code base. Some highlights are below.
### Getting Started with the RBAC
-1. We need to turn off the standard panel of links on the left side of the Streamlit app. This is done through the `app/src/.streamlit/config.toml` file. So check that out. We are turning it off so we can control directly what links are shown.
-1. Then I created a new python module in `app/src/modules/nav.py`. When you look at the file, you will se that there are functions for basically each page of the application. The `st.sidebar.page_link(...)` adds a single link to the sidebar. We have a separate function for each page so that we can organize the links/pages by role.
-1. Next, check out the `app/src/Home.py` file. Notice that there are 3 buttons added to the page and when one is clicked, it redirects via `st.switch_page(...)` to that Roles Home page in `app/src/pages`. But before the redirect, I set a few different variables in the Streamlit `session_state` object to track role, first name of the user, and that the user is now authenticated.
-1. Notice near the top of `app/src/Home.py` and all other pages, there is a call to `SideBarLinks(...)` from the `app/src/nav.py` module. This is the function that will use the role set in `session_state` to determine what links to show the user in the sidebar.
-1. The pages are organized by Role. Pages that start with a `0` are related to the _Political Strategist_ role. Pages that start with a `1` are related to the _USAID worker_ role. And, pages that start with a `2` are related to The _System Administrator_ role.
+1. We need to turn off the standard panel of links on the left side of the Streamlit app. This is done through the
+ `app/src/.streamlit/config.toml` file. So check that out. We are turning it off so we can control directly what links
+ are shown.
+1. Then I created a new python module in `app/src/modules/nav.py`. When you look at the file, you will se that there are
+ functions for basically each page of the application. The `st.sidebar.page_link(...)` adds a single link to the
+ sidebar. We have a separate function for each page so that we can organize the links/pages by role.
+1. Next, check out the `app/src/Home.py` file. Notice that there are 3 buttons added to the page and when one is
+ clicked, it redirects via `st.switch_page(...)` to that Roles Home page in `app/src/pages`. But before the redirect,
+ I set a few different variables in the Streamlit `session_state` object to track role, first name of the user, and
+ that the user is now authenticated.
+1. Notice near the top of `app/src/Home.py` and all other pages, there is a call to `SideBarLinks(...)` from the
+ `app/src/nav.py` module. This is the function that will use the role set in `session_state` to determine what links
+ to show the user in the sidebar.
+1. The pages are organized by Role. Pages that start with a `0` are related to the _Political Strategist_ role. Pages
+ that start with a `1` are related to the _USAID worker_ role. And, pages that start with a `2` are related to The
+ _System Administrator_ role.
## (VERY Optional) Adding an ML Model to your App
_Note_: This project only contains the infrastructure for a hypothetical ML model.
1. Build, train, and test your ML model in a Jupyter Notebook.
-1. Once you're happy with the model's performance, convert your Jupyter Notebook code for the ML model to a pure python script. You can include the `training` and `testing` functionality as well as the `prediction` functionality. You may or may not need to include data cleaning, though.
-1. Check out the `api/backend/ml_models` module. In this folder, I've put a sample (read _fake_) ML model in `model01.py`. The `predict` function will be called by the Flask REST API to perform '_real-time_' prediction based on model parameter values that are stored in the database. **Important**: you would never want to hard code the model parameter weights directly in the prediction function. tl;dr - take some time to look over the code in `model01.py`.
-1. The prediction route for the REST API is in `api/backend/customers/customer_routes.py`. Basically, it accepts two URL parameters and passes them to the `prediction` function in the `ml_models` module. The `prediction` route/function packages up the value(s) it receives from the model's `predict` function and send its back to Streamlit as JSON.
-1. Back in streamlit, check out `app/src/pages/11_Prediction.py`. Here, I create two numeric input fields. When the button is pressed, it makes a request to the REST API URL `/c/prediction/.../...` function and passes the values from the two inputs as URL parameters. It gets back the results from the route and displays them. Nothing fancy here.
+1. Once you're happy with the model's performance, convert your Jupyter Notebook code for the ML model to a pure python
+ script. You can include the `training` and `testing` functionality as well as the `prediction` functionality. You may
+ or may not need to include data cleaning, though.
+1. Check out the `api/backend/ml_models` module. In this folder, I've put a sample (read _fake_) ML model in
+ `model01.py`. The `predict` function will be called by the Flask REST API to perform '_real-time_' prediction based
+ on model parameter values that are stored in the database. **Important**: you would never want to hard code the model
+ parameter weights directly in the prediction function. tl;dr - take some time to look over the code in `model01.py`.
+1. The prediction route for the REST API is in `api/backend/customers/customer_routes.py`. Basically, it accepts two URL
+ parameters and passes them to the `prediction` function in the `ml_models` module. The `prediction` route/function
+ packages up the value(s) it receives from the model's `predict` function and send its back to Streamlit as JSON.
+1. Back in streamlit, check out `app/src/pages/11_Prediction.py`. Here, I create two numeric input fields. When the
+ button is pressed, it makes a request to the REST API URL `/c/prediction/.../...` function and passes the values from
+ the two inputs as URL parameters. It gets back the results from the route and displays them. Nothing fancy here.
diff --git a/api/.env.template b/api/.env
similarity index 100%
rename from api/.env.template
rename to api/.env
diff --git a/api/backend/rest_entry.py b/api/backend/rest_entry.py
index d8d78502d9..340ef2780f 100644
--- a/api/backend/rest_entry.py
+++ b/api/backend/rest_entry.py
@@ -7,6 +7,13 @@
import os
from dotenv import load_dotenv
+from backend.therapy.trainingSupervisor_routes import supervisors
+from backend.therapy.therapist_routes import therapists
+from backend.therapy.guardian_routes import guardians
+from backend.therapy.specialist_routes import specialists
+from backend.therapy.child_routes import children
+from backend.therapy.artTherapy_routes import artTherapies
+
def create_app():
app = Flask(__name__)
@@ -43,6 +50,13 @@ def create_app():
app.register_blueprint(customers, url_prefix='/c')
app.register_blueprint(products, url_prefix='/p')
+ app.register_blueprint(supervisors)
+ app.register_blueprint(therapists)
+ app.register_blueprint(guardians)
+ app.register_blueprint(specialists)
+ app.register_blueprint(children)
+ app.register_blueprint(artTherapies)
+
# Don't forget to return the app object
return app
diff --git a/api/backend/therapy/artTherapy_routes.py b/api/backend/therapy/artTherapy_routes.py
new file mode 100644
index 0000000000..c311fdc730
--- /dev/null
+++ b/api/backend/therapy/artTherapy_routes.py
@@ -0,0 +1,70 @@
+from flask import Blueprint, request, jsonify, make_response, current_app
+from backend.db_connection import db
+
+artTherapies = Blueprint('artTherapy', __name__)
+
+@artTherapies.route('/art-therapies', methods=['GET'])
+def get_art_therapies():
+ cursor = db.get_db().cursor()
+ cursor.execute('SELECT * FROM Art_Therapy')
+ theData = cursor.fetchall()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@artTherapies.route('/art-therapies', methods=['POST'])
+def post_art_therapy():
+ current_app.logger.info('POST /art-therapies route hit')
+
+ new_art_therapy = request.json
+ therapy_id = new_art_therapy['Therapy_ID']
+ name = new_art_therapy['Name']
+ description = new_art_therapy['Description']
+
+ insert_query = '''INSERT INTO Art_Therapy
+ (Therapy_ID, Name, Description) VALUES
+ (%s, %s, %s)'''
+
+ data = (therapy_id, name, description)
+
+ cursor = db.get_db().cursor()
+ cursor.execute(insert_query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Art therapy added", "id": therapy_id}), 201)
+
+ return response
+
+@artTherapies.route('/art-therapies/', methods=['GET'])
+def get_art_therapy(artTherapyID):
+ cursor = db.get_db().cursor()
+ cursor.execute('SELECT * FROM Art_Therapy WHERE Therapy_ID = %s', (artTherapyID,))
+ theData = cursor.fetchone()
+ if not theData:
+ return make_response(jsonify({"error": "Art therapy not found"}), 404)
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@artTherapies.route('/art-therapies/', methods=['PUT'])
+def update_art_therapy(artTherapyID):
+ current_app.logger.info('PUT /art-therapies route hit')
+
+ updated_art_therapy = request.json
+ name = updated_art_therapy['Name']
+ description = updated_art_therapy['Description']
+
+ query = '''UPDATE Art_Therapy SET
+ Name = %s,
+ Description = %s
+ WHERE
+ Therapy_ID = %s
+ '''
+
+ data = (name, description, artTherapyID)
+
+ cursor = db.get_db().cursor()
+ cursor.execute(query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Art therapy updated",
+ "Therapy ID": artTherapyID}), 200)
+ return response
\ No newline at end of file
diff --git a/api/backend/therapy/child_routes.py b/api/backend/therapy/child_routes.py
new file mode 100644
index 0000000000..fafd5f08e4
--- /dev/null
+++ b/api/backend/therapy/child_routes.py
@@ -0,0 +1,69 @@
+from flask import Blueprint, request, jsonify, make_response, current_app
+from backend.db_connection import db
+
+children = Blueprint('children', __name__)
+
+@children.route('/children', methods=['GET'])
+def get_children():
+ cursor = db.get_db().cursor()
+ cursor.execute('SELECT * FROM Children')
+ theData = cursor.fetchall()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@children.route('/children', methods=['POST'])
+def post_child():
+ current_app.logger.info('POST /children route hit')
+
+ new_child = request.json
+ child_id = new_child['Child_ID']
+ name = new_child['Name']
+ age = new_child['Age']
+ guardian = new_child['Guardian']
+
+ insert_query = '''INSERT INTO Children
+ (Child_ID, Name, Age, Guardian) VALUES
+ (%s, %s, %s, %s)'''
+
+ data = (child_id, name, age, guardian)
+
+ cursor = db.get_db().cursor()
+ cursor.execute(insert_query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Child added", "id": child_id}), 201)
+
+ return response
+
+@children.route('/children/', methods=['GET'])
+def get_child(id):
+ cursor = db.get_db().cursor()
+ cursor.execute('SELECT * FROM Children WHERE Child_ID = %s', (id,))
+ theData = cursor.fetchone()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@children.route('/children/', methods=['PUT'])
+def update_child(id):
+ current_app.logger.info('PUT /children/ route hit')
+
+ updated_child = request.json
+ name = updated_child['Name']
+ age = updated_child['Age']
+ guardian = updated_child['Guardian']
+
+ update_query = '''UPDATE Children SET
+ Name = %s,
+ Age = %s,
+ Guardian = %s
+ WHERE Child_ID = %s'''
+
+ data = (name, age, guardian, id)
+
+ cursor = db.get_db().cursor()
+ cursor.execute(update_query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Child updated", "id": id}), 200)
+
+ return response
\ No newline at end of file
diff --git a/api/backend/therapy/guardian_routes.py b/api/backend/therapy/guardian_routes.py
new file mode 100644
index 0000000000..9207446c51
--- /dev/null
+++ b/api/backend/therapy/guardian_routes.py
@@ -0,0 +1,80 @@
+from flask import request
+from flask import Blueprint
+from flask import jsonify
+from flask import make_response
+from flask import current_app
+from backend.db_connection import db
+
+guardians = Blueprint('guardians', __name__)
+
+@guardians.route('/guardians', methods=['GET'])
+def get_guardians():
+ cursor = db.get_db().cursor()
+ cursor.execute('''SELECT * FROM Guardian''')
+ theData = cursor.fetchall()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@guardians.route('/guardians', methods=['POST'])
+def post_guardians():
+ current_app.logger.info('POST /guardians route hit')
+
+ new_guardian = request.json
+ guardianID = new_guardian['Guardian_ID']
+ name = new_guardian['Name']
+ email = new_guardian['Email']
+ phone = new_guardian['Phone']
+ relationship = new_guardian['Relationship']
+ personalInfo = new_guardian['Personal_Info']
+
+ insert_query = '''INSERT INTO Guardian
+ (Guardian_ID, Name, Email, Phone, Relationship, Personal_Info VALUES
+ (%s, %s, %s, %s, %s, %s)'''
+
+ data = (guardianID, name, email, phone, relationship, personalInfo)
+
+ cursor = db.get_db().cursor()
+ cursor.execute(insert_query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message" : "Guardian added", "id" : guardianID}), 201)
+ return response
+
+@guardians.route('/guardians/', methods=['GET'])
+def get_guardian(gID):
+ cursor = db.get_db().cursor()
+ cursor.execute('''SELECT * FROM Guardian WHERE Guardian_ID = %s,)''', (gID,))
+ theData = cursor.fetchone()
+
+ the_response = make_response(theData, 200)
+ return the_response
+
+@guardians.route('/guardians/', methods=['PUT'])
+def update_guardian(guardianID):
+ cursor = db.get_db().cursor()
+ new_g = request.json
+ name = new_g['Name']
+ email = new_g['Email']
+ phone = new_g['Phone']
+ relationship = new_g['Relationship']
+ personalInfo = new_g['Personal_Info']
+
+ query = '''UPDATE Guardian SET
+ Name = %s,
+ Email = %s,
+ Phone = %s,
+ Relationship = %s,
+ Personal_Info = %s
+ WHERE
+ Guardian_ID = %s
+ '''
+
+ data = (name, email, phone, relationship, personalInfo, guardianID)
+
+ cursor.execute(query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"Message" : "guardian updated",
+ "Guardian ID" : guardianID}), 200)
+ return response
+
+
diff --git a/api/backend/therapy/specialist_routes.py b/api/backend/therapy/specialist_routes.py
new file mode 100644
index 0000000000..624c4a6038
--- /dev/null
+++ b/api/backend/therapy/specialist_routes.py
@@ -0,0 +1,77 @@
+from flask import request, Blueprint, jsonify, make_response, current_app
+from backend.db_connection import db
+
+specialists = Blueprint('specialists', __name__)
+
+@specialists.route('/specialists', methods=['GET'])
+def get_specialists():
+ cursor = db.get_db().cursor()
+ cursor.execute('''SELECT * FROM Specialist''')
+ theData = cursor.fetchall()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@specialists.route('/specialists', methods=['POST'])
+def post_specialists():
+ current_app.logger.info('POST /specialists route hit')
+
+ new_specialist = request.json
+ specialistID = new_specialist['Specialist_ID']
+ name = new_specialist['Name']
+ email = new_specialist['Email']
+ phone = new_specialist['Phone']
+ expertise = new_specialist['Expertise']
+ bio = new_specialist['Bio']
+
+ insert_query = '''INSERT INTO Specialist
+ (Specialist_ID, Name, Email, Phone, Expertise, Bio) VALUES
+ (%s, %s, %s, %s, %s, %s)'''
+
+ data = (specialistID, name, email, phone, expertise, bio)
+
+ cursor = db.get_db().cursor()
+ cursor.execute(insert_query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Specialist added", "id": specialistID}), 201)
+ return response
+
+@specialists.route('/specialists/', methods=['GET'])
+def get_specialist(specialistID):
+ cursor = db.get_db().cursor()
+ cursor.execute('''SELECT * FROM Specialist WHERE Specialist_ID = %s''', (specialistID,))
+ theData = cursor.fetchone()
+
+ if not theData:
+ return make_response(jsonify({"error": "Specialist not found"}), 404)
+
+ the_response = make_response(jsonify(theData), 200)
+ return the_response
+
+@specialists.route('/specialists/', methods=['PUT'])
+def update_specialist(specialistID):
+ cursor = db.get_db().cursor()
+ updated_specialist = request.json
+ name = updated_specialist['Name']
+ email = updated_specialist['Email']
+ phone = updated_specialist['Phone']
+ expertise = updated_specialist['Expertise']
+ bio = updated_specialist['Bio']
+
+ query = '''UPDATE Specialist SET
+ Name = %s,
+ Email = %s,
+ Phone = %s,
+ Expertise = %s,
+ Bio = %s
+ WHERE
+ Specialist_ID = %s
+ '''
+
+ data = (name, email, phone, expertise, bio, specialistID)
+
+ cursor.execute(query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Specialist updated",
+ "Specialist ID": specialistID}), 200)
+ return response
\ No newline at end of file
diff --git a/api/backend/therapy/therapist_routes.py b/api/backend/therapy/therapist_routes.py
new file mode 100644
index 0000000000..ae009f32e1
--- /dev/null
+++ b/api/backend/therapy/therapist_routes.py
@@ -0,0 +1,118 @@
+from flask import request
+from flask import Blueprint
+from flask import jsonify
+from flask import make_response
+from flask import current_app
+from backend.db_connection import db
+
+therapists = Blueprint('therapists', __name__)
+
+@therapists.route('/therapists', methods=['GET'])
+def get_therapists():
+ cursor = db.get_db().cursor()
+ cursor.execute('''SELECT * FROM Therapist''')
+ theData = cursor.fetchall()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@therapists.route('/therapists', methods=['POST'])
+def post_therapists():
+ current_app.logger.info('POST /therapists route hit')
+ new_sup = request.json
+ licenseNumber = new_sup['License_Number']
+ name = new_sup['Name']
+ email = new_sup['Email']
+ phone = new_sup['Phone']
+ age = new_sup['Age']
+ gender = new_sup['Gender']
+ personalInfo = new_sup['Personal_Info']
+ preferredArtForm = new_sup['Preferred_Art_Form']
+ techniqueConfidence = new_sup['Technique_Confidence']
+ specialization = new_sup['Specialization']
+
+ insert_query = '''INSERT INTO Training_Supervisor
+ (License_Number, Name, Email, Phone, Age, Gender,
+ Personal_Info, Preferred_Art_Form, Technique_Confidence,
+ Specialization) VALUES
+ (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'''
+
+ data = (licenseNumber,
+ name,
+ email,
+ phone,
+ age,
+ gender,
+ personalInfo,
+ preferredArtForm,
+ techniqueConfidence,
+ specialization)
+
+ cursor = db.get_db().cursor()
+ r = cursor.execute(insert_query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Therapist added", "id": licenseNumber}), 201)
+
+ return response
+
+@therapists.route('/therapists/', methods=['GET'])
+def get_therapist(userID):
+ cursor = db.get_db().cursor()
+ cursor.execute('SELECT * FROM Therapist WHERE License_Number = %s', (userID,))
+
+ theData = cursor.fetchone()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+
+ return the_response
+
+@therapists.route('/therapists/', methods=['PUT'])
+def update_therapist(userID):
+ current_app.logger.info('PUT /therapist route')
+
+ new_therapist = request.json
+ name = new_therapist['Name']
+ email = new_therapist['Email']
+ phone = new_therapist['Phone']
+ age = new_therapist['Age']
+ gender = new_therapist['Gender']
+ personalInfo = new_therapist['Personal_Info']
+ preferredArtForm = new_therapist['Preferred_Art_Form']
+ techniqueConfidence = new_therapist['Technique_Confidence']
+ specialization = new_therapist['Specialization']
+
+ query = '''UPDATE Therapist SET
+ name = %s
+ email = %s
+ phone = %s
+ age = %s
+ gender = %s
+ personalInfo = %s
+ preferredArtForm = %s
+ techniqueConfidence = %s
+ specialization = %s
+ WHERE
+ LicenseNumber = %s
+ '''
+
+ data = (name, email, phone, age, gender, personalInfo, preferredArtForm, techniqueConfidence, specialization)
+
+ cursor = db.get_db().cursor()
+ r = cursor.execute(query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"Message" : "Therapist updated", "TherapistLicense" : userID}),200)
+ return response
+
+@therapists.route('/therapists/', methods=['DELETE'])
+def delete_therapist(userID):
+ current_app.logger.info('DELETE /therapist route')
+
+ query = '''DELETE FROM Therapist WHERE licenseNumber = $s'''
+
+ cursor = db.get_db().cursor()
+ r = cursor.execute(query)
+ db.get_db().commit()
+ response = make_response(jsonify({"Message" : "Deleted", "licenseID" : userID}))
+ return response
+
+
diff --git a/api/backend/therapy/trainingSupervisor_routes.py b/api/backend/therapy/trainingSupervisor_routes.py
new file mode 100644
index 0000000000..7aea72c7a9
--- /dev/null
+++ b/api/backend/therapy/trainingSupervisor_routes.py
@@ -0,0 +1,80 @@
+from flask import request
+from flask import Blueprint
+from flask import jsonify
+from flask import make_response
+from flask import current_app
+from backend.db_connection import db
+
+supervisors = Blueprint('supervisors', __name__)
+
+@supervisors.route('/training-supervisors', methods=['GET'])
+def get_supervisors():
+ cursor = db.get_db().cursor()
+ cursor.execute('''SELECT * FROM Training_Supervisor''')
+ theData = cursor.fetchall()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@supervisors.route('/training-supervisors', methods=['POST'])
+def post_supervisors():
+ current_app.logger.info('POST /supervisors route hit')
+
+ new_sup = request.json
+ sup_id = new_sup['Supervisor_ID']
+ name = new_sup['Name']
+ email = new_sup['Email']
+ phone = new_sup['Phone']
+ personalInfo = new_sup['Personal_Info']
+
+ insert_query = '''INSERT INTO Training_Supervisor
+ (Supervisor_ID, Name, Email, Phone, Personal_Info) VALUES
+ (%s, %s, %s, %s, %s)'''
+
+ data = (sup_id, name, email, phone, personalInfo)
+
+ cursor = db.get_db().cursor()
+ r = cursor.execute(insert_query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"message": "Supervisor added", "id": sup_id}), 201)
+
+ return response
+
+@supervisors.route('/training-supervisors/', methods=['GET'])
+def get_supervisor(userID):
+ cursor = db.get_db().cursor()
+ cursor.execute('SELECT * FROM Training_Supervisor WHERE Supervisor_ID = %s', (userID,))
+
+ theData = cursor.fetchone()
+ the_response = make_response(jsonify(theData))
+ the_response.status_code = 200
+ return the_response
+
+@supervisors.route('/training-supervisors/', methods=['PUT'])
+def update_supervisor(userID):
+ current_app.logger.info('PUT /supervisor route')
+
+ new_sup = request.json
+ sup_id = new_sup['Supervisor_ID']
+ name = new_sup['Name']
+ email = new_sup['Email']
+ phone = new_sup['Phone']
+ personalInfo = new_sup['Personal_Info']
+
+ query = '''UPDATE Training_Supervisor SET
+ name = %s,
+ email = %s,
+ phone = %s,
+ personalInfo = %s
+ WHERE
+ Supervisor_ID = %s
+ '''
+
+ data = (name, email, phone, personalInfo, userID)
+
+ cursor = db.get_db().cursor()
+ r = cursor.execute(query, data)
+ db.get_db().commit()
+ response = make_response(jsonify({"Message" : "supervisor updated",
+ "Supervisor ID" : userID}), 200)
+ return response
\ No newline at end of file
diff --git a/app/src/Home.py b/app/src/Home.py
index ef0f7b19ad..63db10c186 100644
--- a/app/src/Home.py
+++ b/app/src/Home.py
@@ -34,7 +34,7 @@
# set the title of the page and provide a simple prompt.
logger.info("Loading the Home page of the app")
-st.title('CS 3200 Sample Semester Project App')
+st.title('Child Therapy Management System')
st.write('\n\n')
st.write('### HI! As which user would you like to log in?')
diff --git a/app/src/pages/04_Prediction.py b/app/src/pages/PredictionModel.py
similarity index 99%
rename from app/src/pages/04_Prediction.py
rename to app/src/pages/PredictionModel.py
index a5a322a2f4..08712760a6 100644
--- a/app/src/pages/04_Prediction.py
+++ b/app/src/pages/PredictionModel.py
@@ -35,4 +35,4 @@
use_container_width=True):
results = requests.get(f'http://api:4000/c/prediction/{var_01}/{var_02}').json()
st.dataframe(results)
-
\ No newline at end of file
+