• Update Operation
  • Delete Operation
  • What I Learned
  • Next Steps
  • Conclusion
  • Wellness Waypoints Feature Write-up

    Description

    Wellness Waypoints is a feature that helps travelers find medical care facilities based on their specific needs. Users can select from a variety of medical conditions/injuries and find appropriate care locations (hospitals, pharmacies, or recovery centers) in their desired city. The system allows users to:

    • Check in to care locations
    • Rate their experience
    • View others’ ratings
    • Check out when they’re done

    This blog explains the technical implementation and key features of the Wellness Waypoints system.

    Wellness Waypoints CPT Documentation

    1. Input Handling

    Explanation:
    Input handling ensures the program correctly receives and processes user data. In Wellness Waypoints, users input their injury type and location to find suitable healthcare facilities, which the system then uses to provide relevant results.

    // Frontend: Capturing user input for a new check-in
    async function createCheckIn(injury, location, address) {
        const response = await fetch(`${pythonURI}/api/waypoints`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify({
                injury: injury,
                location: location,
                address: address
            })
        });
        return await response.json();
    }
    

    2. Use of Lists/Data Abstraction

    Explanation

    • Using lists or similar data structures (like database tables) allows the program to store and manage data efficiently, simplifying the logic. In this project, a database table acts as a collection of “waypoint” entries (user check-ins), which is an example of data abstraction.
    # Backend: Storing waypoints (check-in) data in a database model
    @token_required()
    def get(self):
        """
        Retrieve a single waypoint by ID.
        """
        # Obtain and validate the request data sent by the RESTful client API
        current_user = g.current_user
        waypointsuser = WaypointsUser.query.filter_by(_user_id=current_user.id)
    
        if waypointsuser is None:
            return {'message': 'Waypoint not found'}, 404
    
        # Convert Python object to JSON format 
        waypointsusers = waypointsuser.all()
        json_waypointsuser = [waypointsuser.to_dict() for waypointsuser in waypointsusers]
        
        return jsonify(json_waypointsuser)
    
    
    ## 3. Procedures with Parameters & Return Types
    **Explanation**
    - Defining procedures (functions) that have parameters and return values makes the program modular and reusable. By passing in parameters, the same function can handle different data, and by returning a value, the function provides a result that other parts of the program can use.
    
    ```python
    # Backend: Retrieving the latest rating for a given address
    @staticmethod
    def get_last_rating(address):
        waypoint = WaypointsUser.query \
            .filter_by(address=address) \
            .order_by(WaypointsUser.id.desc()) \
            .first()
        return {
            "rating": waypoint.rating if waypoint else None,
            "total_ratings": WaypointsUser.query.filter_by(address=address).count()
        }
    

    4. Algorithm with Sequencing, Selection & Iteration

    Explanation

    • A key algorithm in the program should demonstrate sequencing (executing steps in order), selection (making decisions with conditionals), and iteration (repeating actions in loops).

    Sequencing

    1. The user selects an injury and a city to find the nearest care centers.
    2. A request is sent to the backend to retrieve relevant care centers.
    3. The user may check in to a facility and provide a rating.
    4. The UI updates dynamically with new check-ins and ratings.

    Selection

    • Error handling is implemented to return messages when input data is missing.
    • If a user does not provide a rating, a default value is assigned.
    • If an invalid location is entered, an error message is displayed.
    ## Backend: Updating a waypoint's rating (algorithm with sequencing, selection, iteration)
    @token_required()
    def put(self):
        data = request.get_json()                              # 1. Sequencing: get data from request
        waypointsuser = WaypointsUser.query.get(data['waypoint_id'])
        
        if waypointsuser is None:                              # 2. Selection: decision-making
            return {'message': 'WaypointUser not found'}, 404
        
        waypointsuser.rating = data['rating']
        waypointsuser.update()                                 # 3. Sequencing: update the record
        return jsonify(waypointsuser.read())
    

    Iteration

    • When retrieving check-ins, the system loops through database records to display all available data.
    • Ratings are dynamically updated based on user feedback.
    def get_facility_ratings():
        facilities = {}
        try:
            waypoints = WaypointsUser.query.all()
            
            for waypoint in waypoints:
                facility_key = f"{waypoint.facility}_{waypoint.city}"  # Unique key for each facility
                
                if facility_key not in facilities:
                    facilities[facility_key] = {
                        'facility': waypoint.facility,
                        'city': waypoint.city,
                        'total_ratings': 0,
                        'rating_sum': 0,
                        'visits': 0
                    }
                
                facilities[facility_key]['visits'] += 1
                facilities[facility_key]['rating_sum'] += waypoint.rating
                facilities[facility_key]['total_ratings'] += 1
                facilities[facility_key]['avg_rating'] = round(
                    facilities[facility_key]['rating_sum'] / facilities[facility_key]['total_ratings'], 
                    2
                )
    
            return [facility_data for facility_data in facilities.values()]
        
        except Exception as e:
            print(f"Error in get_facility_ratings: {str(e)}")
            return []
    

    5. Output Handling

    Explanation

    • Output handling is about presenting information to the user correctly after processing. In Wellness Waypoints, this could mean updating the user interface based on new data from the backend.
    // Frontend: Displaying facility rating with colored stars
    function updateStarDisplay(waypointId, rating) {
        const stars = document.querySelectorAll(`[data-waypointid="${waypointId}"] .rating-star`);
        stars.forEach((star, index) => {
            if (index < rating) {
                star.classList.add('active');            // mark star as filled/active
                if (index < 2) star.classList.add('red');      // 1-2 stars = red (poor rating)
                else if (index < 4) star.classList.add('yellow'); // 3-4 stars = yellow (average)
                else star.classList.add('green');        // 5 stars = green (good rating)
            }
        });
    }
    

    CRUD Operations

    ””” The backend of Wellness Waypoints is powered by a Flask REST API, with frontend requests managed through JavaScript fetch API calls. “””

    Create Operation

    Frontend: Creating a new check-in

    create_check_in_js = 
    async function createCheckIn(injury, location, address) {
        const response = await fetch(`${pythonURI}/api/waypoints`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify({
                injury: injury,
                location: location,
                address: address
            })
        });
        return await response.json();
    }
    

    Backend: Create endpoint

    create_check_in_py = 
    @token_required()
    def post(self):
        current_user = g.current_user
        data = request.get_json()
        waypointsuser = WaypointsUser(
            data['injury'], 
            data['location'], 
            data['address'], 
            data.get('rating', 5),  # Default rating of 5
            current_user.id
        )
        waypointsuser.create()
        return jsonify(waypointsuser.read())
    

    Read Operation

    Frontend: Fetching check-ins

    get_check_ins_js = 
    async function getCheckIns() {
        const response = await fetch(`${pythonURI}/api/waypoints`, {
            method: 'GET',
            headers: {
                'Authorization': `Bearer ${token}`
            }
        });
        const data = await response.json();
        return data;
    }
    

    Backend: Read endpoint

    get_check_ins_py = 
    @token_required()
    def get(self):
        current_user = g.current_user
        waypointsuser = WaypointsUser.query.filter_by(_user_id=current_user.id)
        waypointsusers = waypointsuser.all()
        json_waypointsuser = [waypointsuser.to_dict() for waypointsuser in waypointsusers]
        return jsonify(json_waypointsuser)
    

    Update Operation

    Frontend: Updating ratings

    update_rating_js = 
    async function updateRating(waypointId, rating) {
        const response = await fetch(`${pythonURI}/api/waypoints`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify({
                waypoint_id: waypointId,
                rating: rating
            })
        });
        return await response.json();
    }
    

    Backend: Update endpoint

    update_rating_py = 
    @token_required()
    def put(self):
        data = request.get_json()
        waypointsuser = WaypointsUser.query.get(data['waypoint_id'])
        if waypointsuser:
            waypointsuser._rating = data['rating']
            waypointsuser.update()
            return jsonify(waypointsuser.read())
        return {'message': 'Waypoint not found'}, 404
    

    Delete Operation

    Frontend: Check-out/delete

    delete_check_in_js = 
    async function deleteCheckIn(waypointId) {
        const response = await fetch(`${pythonURI}/api/waypoints?waypoint_id=${waypointId}`, {
            method: 'DELETE',
            headers: {
                'Authorization': `Bearer ${token}`
            }
        });
        return response.ok;
    }
    

    Backend: Delete endpoint

    delete_check_in_py = 
    @token_required()
    def delete(self):
        waypoint_id = request.args.get('waypoint_id')
        waypointsuser = WaypointsUser.query.filter_by(id=waypoint_id).first()
        if waypointsuser:
            waypointsuser.delete()
            return jsonify({"message": "Waypoint deleted"})
        return {'message': 'Waypoint not found'}, 404
    

    What I Learned

    Technical Skills:

    • Frontend: JavaScript async/await, DOM manipulation, API integration.
    • Backend: Flask API, SQLAlchemy ORM, JWT authentication.
    • Database: Query optimization, relationship modeling.

    Soft Skills:

    • Problem Solving: Debugging errors in API requests.
    • Project Management: Prioritizing features and organizing development timelines.

    Next Steps

    1. Implement detailed user reviews for facilities.
    2. Add emergency contact numbers for each facility.
    3. Improve search filtering (e.g., insurance coverage, operating hours).
    4. Expand coverage to include more international locations.

    Conclusion

    Wellness Waypoints helps travelers and locals find the right healthcare facilities with ease. By integrating real-time maps, user ratings, and location-based services, it simplifies the process of finding quality medical care. The application will continue to evolve, incorporating more features to enhance user experience and accessibility.