Giter Club home page Giter Club logo

dolphin-flashcard-app's Introduction

Flashcard-App

1. Broad Overview

This app is designed to improve simiar apps like Quizlet and Anki by implementing a spaced repetition system in an easy to use and visually pleasing UI. The website, which is in development, can be seen here

Contributors are welcome! More information is in CONTRIBUTING.md

the dolphin landing page

2. USPs and Points of Differentiation

  • Flashcard app with nice UI
  • Spaced Repetition
  • Gamified with lots of "juice"

Anki solely fills the second point, while Quizlet serves the first point. None fully cover all points. This would provide a unique opportunity for this app

See the planned features

3. Broad Overview

A broad overview of the planned features to be made

3.1. Flashcard System

  • Log into account
  • Create account
  • Users should be able to see a tree list of all the cards they have added. They should be able to see which folders everything is in
  • There should be an indicator like Anki showing how many cards are there to learn, recap and revise in each folder and set
  • You can click a three dot menu to view all cards in the set, not just the ones you need to learn. You can access the same options as below
  • When you click this menu, you can also choose to create a card
  • When you click on a card or a folder, you view all the cards you need to learn or revise in it as a list
  • Flashcards
  • Multiple choice QU
  • With each qu, you can see whether you know a little, whether you know it well, or not at all
  • Cards have HTML code which can be rendered. Images or text can be uploaded
  • Folders can be created or deleted. Cards can be created, deleted or moved around
  • Anki-Like Algorithm
  • More details to follow

3.2. Gamified Features

  • Streak, XP
  • Leader board with multiple levels. Completing a level in the top 5 pushes you to the next level
  • Quests - things like learn x cards, add x cards, get an x day Streak etc
  • When you win them you get a badge on your profile
  • When you complete one the variable x increases
  • When you win it again the badge looks the same but it has a different number associated with it - the badge number
  • Quests give you gold

3.3. Access Control System

  • The user that created the flashcard/folder owns the flashcard/folder. If they own the folder, they own all the cards inside it
  • Other users can view it but not edit it
  • If they want to edit it, they can first clone it
  • Users can find flashcards made by other users on a separate search tab
  • Users can be given access to flashcard by the owner

4. Contributors

Contributors are welcome!

The project uses feature branches, which are made from the development branch. It is important to keep to this rule!

For more information, please go to CONTRIBUTNG.MD. API documentation is avaliable at docs/

5. Server setup

At the moment, a pipeline exists to:

  • Build the docker container
  • Check the container can run
  • Upload it to docker hub as a private container since it contains keys
  • SSH into a GCP VM and update the container
  • Check the VM is running

If you want to manually setup the code, follow the following steps:

  • firebase_url, firebase_config.json and credentials.json in the overall project directory, which store the url of the firebase instance and the firebase credentials (api key)
  • Get the code on the server, using git or docker(your own build of the code)
  • Navigate to the frontend/ folder, install the npm dependencies in node_requirements.txt, and building the code with npm run build
  • If using docker, a docker-compose.yml file can be made, using the following information:
  • Make sure backend/database/database_config.py stores type="production"
  • Make sure frontend/src/api/secretKeys.js stores the action part of the correct Mailchimp form as mailChimpApiKey
version: '3'

services:
  flashcard-app:
    image: jacobmacleod/flashcard-app:latest
    ports:
      - "5000:5000" 
  • docker-compose up can be used to build the code, and docker-compose up --force-recreate --build -d && docker image prune -f to update the container

More information of how the code works is in CONTRIBUTING.md

dolphin-flashcard-app's People

Contributors

jacob-macleod avatar nathan-a-macleod avatar jaymeklein avatar kenudeh avatar

Stargazers

 avatar

Watchers

 avatar  avatar

dolphin-flashcard-app's Issues

Unhandled exception on calculate_streak endpoint

While testing the calculate_streak endpoint, i faced the following exception:

  File "Flashcard-App\backend\routes\api\statistics.py", line 203, in calculate_streak
    last_streak = stats["lastStreak"]
                  ^^^^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

Testing with valid data, it returns a proper {'success': True} message, i had no problems with valid data.

But when it comes to testing with non-existent data, userID in this case, shouldn't the endpoint return something like "User not found" or {'success': False}?

Develop statistics

Develop statistics APIs so that:

  • Total and weekly XP can be updated
  • Streak is updated
  • Heatmap data is updated

Improve issues

Investigate how to improve issues to better follow agile methodology. Issues should have:

  • Story points (1 point per 4 hours (about a days work for me working part time))
  • Issue priority (minor, major, critical). Documentation should be made about this
  • Everytime 1 story point is completed (4 hours of work), and a break in time to development is made a comment should be made in the issue

CONTRIBUTING.md should be created and info on this added

Add API for quests

Add API methods to manage weekly quests
Quests are created weekly, and all users are in a quest. Quests can be based on a fixed number of characteristics such as cards learned, streak, xp, etc.
There should be a way to get all users ranked in order of how they are doing in the quest, as well as some sort of rating - ie, 3/5 sets learned

Develop API route for Total XP

Dashboard
Here, you can see the total XP (6093). The dashboard page is in development, and an API route needs to be written to read the total XP from the database and return it.

How the code works is:

  • backend/main.py runs a server
  • The code in frontend/ displays the UI, and gets data from backend/main.py using the API, which is basically a function that does some processing returns a value that can be accessed over the internet. The frontend code knows to go to http://dolphinflashcards.com.api/<whatever api function is being called> because that is stored as a variable in a file in the frontend folder

Every API request is made with json data, which provides information needed for the request

Your code will go in backend/routes/api/statistics.py. The format of each function that already exists is as follows - below you can see a simplified existing function with some comments:.

# /api/get-heatmap is the URL the user will go to to get the data. It must begin with /api/
# "POST" in methods=["POST"] means new data will be created. Your route will only read data, so
# you'll have methods=["GET"]
@statistics_routes.route("/api/get-heatmap", methods=["POST"])
def get_heatmap() : // The unique function name
    # A comment explaining the code and how to use it
    """ Get the user's heatmap data
        Requests should have json in the following format:
    {
        "userID": "my id"
    }
    """
    # Check the request json
    # A variable storing a dictionary storing the format we should expect the request to be in. You only need
    # To take the userID, so your variable will be the same
    expected_format = {
            "userID": "",
        }
    # Next few line - check the json provided with the request is correct. request.json is the 
    # json the user provides with the request
    result = check_request_json(
        expected_format,
        request.json
    )
    if result is not True:
        return jsonify(
            {"error": result + ". The request should be in the format: " + str(expected_format)}
        ), 400

    # Get the userID
    user_id = request.json.get("userID")
    # Read the heatmap data. Your total XP data is at "/users/" + user_id + "/statistics/totalXP"
    heatmap = db.get("/users/" + user_id + "/heatmapData")
    # Return the data read in json format
    return jsonify(heatmap)

Load flashcards

Write an API endpoint to get all the flashcards that a user needs to revise to day based on their due date

Develop API doc

Develop documentation in a folder for the documentation of the API. Comments explaining the API are at the start of each API function, so it should be a fairly straightforward fix

TypeError on create_flashcard endpoint (regex)

When testing the create_flashcard endpoint using example data, during the check_request_json function,
i got a TypeError: unhashable type: 'list':

In re.match(expected_value, request_values[i]): the values are:

expected_value

[
  {
    "front": "",
    "back": "",
    "reviewStatus": "^\\d+\\.\\d+$",
    "lastReview": "^(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[0-2])/\\d{4}$"
  }
]

request_values[i]

[
  {
    "front": "Front 1",
    "back": "Back 1",
    "reviewStatus": "0.0",
    "lastReview": "01/01/1969"
  },
  {
    "front": "Front 2",
    "back": "Back 2",
    "reviewStatus": "0.0",
    "lastReview": "01/01/1969"
  }
]

Dummy data

data = {
            "userID": "1",
            "flashcardName": "My new set",
            "flashcardDescription": "This is\nmy description",
            "cards": [
                {
                    "front": "Front 1",
                    "back": "Back 1",
                    "reviewStatus": "0.0",
                    "lastReview": "01/01/1969"
                },
                {
                    "front": "Front 2",
                    "back": "Back 2",
                    "reviewStatus": "0.0",
                    "lastReview": "01/01/1969"
                }
            ]
        }

The above test results in:

  File "Flashcard-App\backend\verification\api_error_checking.py", line 44, in check_request_json
    if not re.match(expected_value, request_values[i]):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python312\Lib\re\__init__.py", line 167, in match
    return _compile(pattern, flags).match(string)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python312\Lib\re\__init__.py", line 285, in _compile
    return _cache2[type(pattern), pattern, flags]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unhashable type: 'list'

KeyError on create-account endpoint (local database config)

I was testing the create-account endpoint via /api/create-account with the following parameters:

{
    "userID": "1231",
    "displayName": "Jayme Klein"
}

database_config.py is configured as type="local"

I had this exception when trying to create a new user:

Flashcard-App\backend\database\local_database.py", line 41, in _traverse_path
    current = current[key]
              ^^^^^^^^^^^^
KeyError: ''

and these were the values the method was using:
image

Event with an existing user in the file, the '' key would not be found:
image

Should an empty '' key exist in data.json file?

I'm gonna skip this endpoint for the moment.

Please let me know if you need more context or if the issue is not properly writen.

Fix pipeline error and improve code base accessibility

There are several main tasks for this DevSecOps focused issue:

  • Apparently, it's safe for the frontend to expose the API key. The following needs to be done:
    • Investigate whether the same API key is used on the backend and frontend. If so, find out whether exposing the key will alow users to do what they want to the DB. If not, make the front end sign in method use the actual API key, hardcoded in a file
  • Make all API calls in frontend reference the deployed app (http://dolphin-flashcards.com) so that the frontend can be run independently of the local backend server. So the frontend should never need the backend server running locally. The url should be in a standalone file for easy access
  • Make the db class have a dev mode, where it reads and writes to a single json file, converting a data path ("my/data/path") to a json location. Add reading and writing this way. Use ChatGPT for this
  • Make it so by default when you clone the repo, it uses the local dev files, and in production it talks to firebase. Make it so you can make it talk to firebase yourself if you want
  • Use a smaller Linux image for the docker image, so it takes less storage. The pipeline failed due to storage - this should be fixed
  • Add a CONTRIBUTING.md file. This should explain how to contribute for frontend and backend, and explain the relationship between the two separate codebases. Since local files are now read from in dev for the backend, no firebase configuration should be needed. This should be explain, and a link given to explain how to setup your own test project. The frontend will use the real production code, from the public API
  • Add a DEPLOYING.md file that explains how to deploy with your own firebase server, and how contributing works - this info is included in CONTRIBUTING.md
  • Link to the two new markdown files from README.md

This must be done before contributors can really work on code. Right now, the backend server must be running locally, connected to the live production database, to do any contributing

Make sets show limited number of cards

Sets should show limited number of cards to revise and learn to avoid overwhelming the user. This should be automatically calculated from the words in each flashcard to learn today, or set my the user from "default" to another value

Implement card operations menu for flashcard overview page

Implement the "Rename" and "Delete" buttons for each flashcard which is accessed by clicking the three dot menu on the /flashcards page. This involves developing the frontend, including mobile support and loading animations, as well as the backend methods. Follow the UI designs.

If you're interested, please reply to this comment, and I'll send more detailed information, including showing the UI designs

Add the ability to search for flashcards

Make the search box on the /flashcards page functional, by making it actually show search results. This involves writing the python backend to facilitate this, adding any animations, including loading icons, designing the search view, and making the page work on mobile. You should follow the UI designs.

If you're interested at all, please reply, and I'll send through more detailed information, including the UI designs

IMPORTANT: Add API Testing

At the moment, the API is not tested. This should be fixed by adding extensive unit tests. This is essential, and very important, to ensure the code works long term with no errors. So far, it has only been slightly tested manually, and so there is the potential for significant issues in the code. The pipeline should run unit tests which are in the the testing folder, if they are named following a pattern which pytest can detect

Add the ability to create a folder

Make the New Folder button on the /flashcards page functional, by making it actually add a folder. This involves writing the python backend to facilitate this, adding any animations, including loading icons, and making the page work on mobile. You should follow the UI designs.

If you're interested at all, please reply, and I'll send through more detailed information, including the UI designs

Convert Documentation to Mintlify

Convert the existing documentation to mintlify, which will make the docs a lot nicer to read and understand. Below are some links:
https://mintlify.com/docs/quickstart#creating-your-documentation-repository
https://github.com/mintlify/starter
https://github.com/mintlify/starter/blob/main/mint.json

The initial setup can be based on https://github.com/mintlify/starter, but make sure you change the folder structure, possibly putting all files inside docs/ to make the repo simpler.

Setup the code to upload a static site to mintlify.

Give the documentation a blue theme, to fit in with dolphin flashcards

Add API for Leaderboard page

Add the API methods required for the leaderboard page. This includes:

  • Getting a list of all user names, sorted by weeklyXP

Add API error checking

Error checking should be added to the API to check:

  • When flashcards are loaded but there are none
  • When editing or creating flashcards, if the user exists or not

Develop Algorithm for Learning Flashcards

The algorithm should be similar to Anki, and allow users to be shown only the flashcards they need to learn
The client should pass an API endpoint the card data like review date and review status, and the new review date and status should be returned.

In Anki, cards are classed as Learn, hard, medium, easy. Easy is rarely used, and I would argue "hard" is used even less. So I would say:

  • If you swipe the card one way, you don't know it
  • If you swipe the card the other way, you know it
  • If you tap the card to flip it then press the "Easy" button or equivalent, the flashcard is classed as easy

Develop initial API

Develop a REST API to handle logging in and authenticating users, as well as creating an account

Add the ability to create a flashcard

Make the "New Flashcard" button on the /flashcards page functional, by making it actually create a flashcard. This involves writing the python backend to facilitate this, adding any animations, including loading icons, and making the page work on mobile. You should follow the UI designs.

If you're interested at all, please reply, and I'll send through more detailed information, including the UI designs

get-flashcard endpoint is returning None, regardless of given data

I was starting to test the /api/get-flashcard endpoint, which is returning None regardless of given data:
Valid data json:

valid_data = {
    "userID": "1",
    "flashcardName": "My new set"
}

And this is is the current data in data.json:

{
  "users": {
    "1": {
      "userID": "1",
      "name": "Dummy",
      "statistics": {
        "streak": "0",
        "totalXP": "0",
        "weeklyXP": "0",
        "lastStreak": "03/03/2024"
      },
      "heatmapData": {},
      "flashcards": {
        "109048371178679571656833207928626960824600184952382683242495299362286693266526": {
          "flashcardID": "109048371178679571656833207928626960824600184952382683242495299362286693266526",
          "flashcardName": "My new set",
          "flashcardDescription": "This is\nmy description",
          "cards": [
            {
              "front": "Front 1",
              "back": "Back 1",
              "reviewStatus": "0.0",
              "lastReview": "01/01/1969"
            },
            {
              "front": "Front 2",
              "back": "Back 2",
              "reviewStatus": "0.0",
              "lastReview": "01/01/1969"
            }
          ]
        }
      }
    }
  }
}

This is the path argument passed in Database.get method:
/users/1/flashcards/109048371178679571656833207928626960824600184952382683242495299362286693266526

The LocalDatabase.get method returns the expected data:

{
  "flashcardID": "109048371178679571656833207928626960824600184952382683242495299362286693266526",
  "flashcardName": "My new set",
  "flashcardDescription": "This is\nmy description",
  "cards": [
    {
      "front": "Front 1",
      "back": "Back 1",
      "reviewStatus": "0.0",
      "lastReview": "01/01/1969"
    },
    {
      "front": "Front 2",
      "back": "Back 2",
      "reviewStatus": "0.0",
      "lastReview": "01/01/1969"
    }
  ]
}

But when it comes to the Database.get method, his return is always None.

I changed the line 126 from return jsonify(db.get("/users/" + user_id + "/flashcards/" + flashcard_id)) in two different lines, just for purpose of debugging:

data = db.get("/users/" + user_id + "/flashcards/" + flashcard_id)
return jsonify(data)

Does the data value from db.get shouldn't be the same as LocalDatabase.get?

After adding the return statement to the Database.get method, the endpoint properly returned the requested data.

Should i keep this change for the next commit?

Improve pipeline

Improve the github actions pipeline to add:

  • Testing of python code on pushes to branches
  • Pylint testing - fails if the score is below a level such as 6
  • MR templates
  • Automatic generation of changelogs and release notes based on the MR text
  • Automatic versioning for merges to main based on https://semver.org

Initial code

Develop initial code to return an HTML template when the right URL is entered. The code should also:

  • Setup and use an SQL database
  • Setup docker for both the database and the code
  • Setup GitHub actions to update the docker container

Design and implement switch to firestore

Design and implement a switch to using firestore as a database, rather than the realtime database. This will allow lots of users to be added, whereas before, the single collection of a realtime database would simply not allow it

Server hosting

Host the initial code on a GCP server, and setup Github actions to reload the docker container on the server when a merge is made to main

Add API for Goals

Add API to allow users to select individual goals. This could be on the same categories as the quest page. A timeframe is selected, and there is some system to tag whether a goal has been failed, possibly deleting the record after a certain time

Flashcard API

Add features to the API to allow:

  • Creating a flashcard set
    • Cards have a front, back, review status (an int which starts at 0, representing a new card), and a last review date
  • Editing a flashcard
  • Getting cards in a set

Add API for community page

Add the API for the community page. This means:

  • Everyone's sets can be searched for
  • The cards in other's sets can be returned
  • Other's sets can be added to a folder in your personal collection

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.