Coder Social home page Coder Social logo

cubecrit's Introduction

CubeCrit

A website for reviewing speedcubes.

Local Development

Requirements

Commands

# install dependencies
poetry install

# run formatters/apply fixes
poetry run poe format

# run linters/apply checks
poetry run poe lint

# run tests
poetry run pytest

Running Locally

# start the local postgres db server on localhost:5432
docker compose up db

# set environment variables
export DB_ADDRESS="postgresql://cubecrit:password@localhost:5432/cubecrit"

# set environment variables for powershell
$Env:DB_ADDRESS="postgresql://cubecrit:password@localhost:5432/cubecrit"

# start the debug server on localhost:3000
poetry run poe flask-debug

Database Schema

DB Diagram

cubecrit's People

Contributors

bobertoyin avatar epproper54 avatar

Watchers

 avatar

cubecrit's Issues

Address Docstring Lints and Unit Test Code Coverage

There are still quite a few outstanding lint errors related to docstrings, and our unit test coverage isn't very comprehensive. We should work on this before completing Issue #8 to prevent having future PRs get blocked.

Spruce Up UI

In its current state, the UI components are a bit barren and jarring in spacing and color. Hopefully it'll improve as we add more features and fill out each page, but for now we should sit down to figure out how to make it look a little cleaner.

Setup Dockerfile

At some point, we'd probably like to have a Dockerfile to simplify deployments

Create Search Page

To enable users to search through our site's content, we need a search page to show users what cubes are available for review.

The search URL should look something like /search?q=<query string>&puzzle_type=<puzzle_type external id>&manufacturers=<multiple manufacturer external ids>&sort_by=<sorting method>&page=<page number>.

q represents the search query that the user has entered, and will be used to filter out puzzles by their display name. This parameter can be optional/empty.

puzzle_type represents the puzzle type that users want to filter by. This parameter can be optional/empty.

manufacturers represents the manufacturers that users want to filter by. This parameter can be optional/empty.

sort_by represents the sorting method for the results. This could be something like "A-Z", "Rating: High to Low", etc.

page represents the page number for the results. We want to paginate our results to prevent large database loads and slow response times. Each page should show the same number of results (this number will be determined by our back-end, and is not user-configurable). If this parameter is missing/empty then we assume that we are showing the first page of results.

Additionally, the search bar on the home page should route the user to this page with the appropriate parameters.

Allow Users to Create Reviews

Once Issue #5 is complete, we can allow users to write a review for a cube.

This should be a page with a short summary of the cube information for users to see while they're writing their review, along with the form that will actually submit their review to the backend to store.

There should be some basic validation to prevent invalid/bad data from being stored into the database, and a simple feedback loop to indicate that something went wrong (this feedback loop will be rudimentary for now, but can be improved in future versions). When complete, we should redirect them to the page for their submitted review.

Add Github Actions

To improve the overall development process, we should enforce some of the linting/formatting/testing requirements that currently exist in the repo.

This might take a little longer than expected, since the unit tests currently require a live database connection to run. Ideally we figure out a way to mock the connection so that each test can just set its own data.

Additionally, code coverage should be added to the pytest step with a reasonable coverage requirement.

Improve layout/design of the All Puzzles page

Right now the layout of the All Puzzles page is pretty awkward (no spacing between elements/poor use of page space, elements are too large on mobile screens):
Screenshot 2024-05-18 at 11 16 13 AM
Screenshot 2024-05-18 at 11 16 21 AM

We should make the image size for each cube closer to a thumbnail image, along with centering the pagination buttons along the bottom of the screen and using some kind of flexbox container to handle displaying all of the puzzles.

Create validation module

Pretty soon we'll be adding all kinds of validation functions to validate and/or sanitize user input, so we might as well create a new Python module (file) to hold all of these functions.

Currently we only have one function to move:

def validate_page_number(page_number: str | None) -> int:
if page_number is None:
return 1
try:
check_num = int(page_number)
return check_num
except ValueError:
return 1

We should also maybe consider adding this part of the code into the function:

if page > num_pages or page < 1:
raise abort(404)

Along with raising an abort(404) if it fails being parsed into an int.

Add Review Data to Puzzle Model

To make our search page and puzzle pages more useful, we need to extract and display puzzle rating information to display on the webpage. More specifically, we need to calculate the average rating and total number of reviews for each cube.

This information should be displayed on each puzzle page and on the search page.

Implement Sign In and Sign Out Workflows

We want users to be able to sign in/out in order to properly attribute reviews, along with allowing personalization in the future.

This development is two-fold: we need to integrate with the WCA to authorize users, then use server-side sessions to keep users logged in, allow them to log out, and allow our back-end to determine the current user.

You'll want to read up on WCA's v0 API documentation to understand what routes you'll need to add, along with Flask Session's documentation to implement server-side sessions. Lastly, we'll use Flask Sessions' SQLAlchemy interface to avoid bringing in any more dependencies.

Move schema.sql to a migration system

Once we deploy this app, we need a way to maintain schema changes in the future. Something like Alembic or even Flask-Migrate, which is built using Alembic, should do the trick. It'll also improve our development process by automating some of the schema/seed application process on a developer's local database.

Setup Integration Tests

Once issue #10 is complete, we can create integration tests that use an in-memory sqlite database for more comprehensive testing.

Navbar Brand Link Not Working

Clicking the "CubeCrit" text on the left side of the navbar should redirect the user to the home page, but instead it keeps them on the current page.

Create Custom Error Pages

To improve the user experience of our web server, we should use custom HTML pages when 404 and 5xx errors are returned to the user.

See here for documentation on how to implement these pages.

Additionally, any controllers that use abort should no longer say return abort(xxx) and instead just say abort(xxx):

if manufacturer is None:
return abort(404)

This is because calling abort implicitly raises an exception for flask to handle, so there's no real need to return the value of the function call.

Create navbar links to common pages

Right now, the All Puzzles page is only accessible via manually entering the URL; we should start adding links somewhere in the navbar, with the first one being for the All Puzzles page.

Create Puzzles Page

Although a search page is nice, it'd also be good to just have a simple page/set of pages with all of the puzzles on the website listen in alphabetical order.

These pages should be paginated, so that we aren't actually loading all of the puzzles on the page at once.

Create Manufacturer Page

We should provide a nice little summary page for manufacturer info, along with some of their popular cubes.

Storage For Production Data

We need a way to store data that will be in the production database when deploying. We want to avoid storing in this repository because we'd need to create a pull request for every change to production data (e.g., creating a PR to change the name of manufacturer). Instead, we should store most of the data somewhere else (like a google sheet or another repository), and then create a scheduled script that pulls the data and inserts it into the database.

Note: for things like external id changes, we either need to carefully consider how the script will cascade the changes or still create migration scripts to apply to the production database.

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.