Coder Social home page Coder Social logo

tattdaddy-be's Introduction

TattDaddy

Table of Contents

Getting Started

Versions

  • Ruby: 3.2.2
  • Rails: 7.1.3

Project Description

Tatt Daddy is an app designed to connect users with tattoo artists in order to get pre-designed, flash tattoos in a quick and easy fashion. Users will scroll through different available designs that licensed tattoo artists will upload to the application, select tattoos they would like to get, and get connected with the artist to schedule an appointment, chat about small details of the work, and finalize payment. The goal is to allow tattoo collectors to easily add to their collection and provide artists an opportunity to fill more of their schedule with quick and efficient appointments.

This app was built with a team of 5 developers as the consultancy project for MOD 3 2311, from Turing School of Software and Design.

Learning Goals for Project - To learn how to build something custom from an idea, going from conceptualization to a final product. - Better time estimates and reasonable goals for project tasks. - Experience to build a collaborative Full stack app. - Creating a unique app and managing tasks as a team. - Get experience to create and build a project from scratch.
Setup 1. Fork and/or Clone this Repo from GitHub. 2. In your terminal use `$ git clone `. 3. Change into the cloned directory using `$ cd example`. 4. Install the gem packages using `$ bundle install`. 5. Database Migrations can be set up by running: ``` bash $ rails rake db:{drop,create,migrate,seed} ```
Testing

Test using the terminal utilizing RSpec:

$ bundle exec rspec spec/<follow directory path to test specific files>

or test the whole suite with $ bundle exec rspec

Database Schema

ActiveRecord::Schema[7.1].define(version: 2024_04_18_194439) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

create_table "active_storage_attachments", force: :cascade do |t|
  t.string "name", null: false
  t.string "record_type", null: false
  t.bigint "record_id", null: false
  t.bigint "blob_id", null: false
  t.datetime "created_at", null: false
  t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
  t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
end

create_table "active_storage_blobs", force: :cascade do |t|
  t.string "key", null: false
  t.string "filename", null: false
  t.string "content_type"
  t.text "metadata"
  t.string "service_name", null: false
  t.bigint "byte_size", null: false
  t.string "checksum"
  t.datetime "created_at", null: false
  t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
end

create_table "active_storage_variant_records", force: :cascade do |t|
  t.bigint "blob_id", null: false
  t.string "variation_digest", null: false
  t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
end

create_table "artist_identities", force: :cascade do |t|
  t.bigint "artist_id", null: false
  t.bigint "identity_id", null: false
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["artist_id"], name: "index_artist_identities_on_artist_id"
  t.index ["identity_id"], name: "index_artist_identities_on_identity_id"
end

create_table "artists", force: :cascade do |t|
  t.string "name"
  t.string "email"
  t.string "password_digest"
  t.string "location"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.string "scheduling_link"
end

create_table "identities", force: :cascade do |t|
  t.string "identity_label"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "tattoos", force: :cascade do |t|
  t.string "image_url"
  t.integer "price"
  t.integer "time_estimate"
  t.bigint "artist_id", null: false
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["artist_id"], name: "index_tattoos_on_artist_id"
end

create_table "user_identities", force: :cascade do |t|
  t.bigint "identity_id", null: false
  t.bigint "user_id", null: false
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["identity_id"], name: "index_user_identities_on_identity_id"
  t.index ["user_id"], name: "index_user_identities_on_user_id"
end

create_table "user_tattoos", force: :cascade do |t|
  t.bigint "user_id", null: false
  t.bigint "tattoo_id", null: false
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "status"
  t.index ["tattoo_id"], name: "index_user_tattoos_on_tattoo_id"
  t.index ["user_id"], name: "index_user_tattoos_on_user_id"
end

create_table "users", force: :cascade do |t|
  t.string "name"
  t.string "email"
  t.string "password_digest"
  t.string "location"
  t.integer "search_radius"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.string "uid"
  t.string "token"
end

add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "artist_identities", "artists"
add_foreign_key "artist_identities", "identities"
add_foreign_key "tattoos", "artists"
add_foreign_key "user_identities", "identities"
add_foreign_key "user_identities", "users"
add_foreign_key "user_tattoos", "tattoos"
add_foreign_key "user_tattoos", "users"
end

External APIs/Services

AWS S3 API

  • In our application, we leverage AWS S3 to manage user-uploaded image files. By storing these files in an S3 bucket, we effectively reduce the size of our database, containing only essential data. This approach is particularly beneficial given the potentially large sizes of image files. Storing them in an external database like S3 enables us to store secure URLs in our database queries, rather than cumbersome image data. This optimization enhances the efficiency of our database operations while ensuring the security and accessibility of our image assets.

  • AWS S3 documentation

GitHub OAuth

  • We integrated GitHub OAuth into our application to streamline the user authentication process and enhance security. By utilizing GitHub OAuth, we leverage the robust authentication infrastructure provided by GitHub, a trusted platform widely used by developers. This approach not only simplifies the login experience for our users by allowing them to use their GitHub credentials but also ensures a higher level of security by delegating the authentication process to GitHub's servers. Additionally, GitHub OAuth provides us with access to user profile information, enabling us to personalize the user experience and tailor our application's functionality based on their GitHub identity and permissions. Overall, integrating GitHub OAuth enhances both the usability and security of our application, contributing to a more seamless and trustworthy user experience.

  • GitHub Documentation

Google Matrix Distance API

  • We integrated the Google Distance Matrix API into our application to enhance the user experience by providing accurate and real-time distance and travel time information between users' locations and tattoo artists' studios. By leveraging this API, Tatt Daddy can offer users valuable insights into the proximity of available tattoo artists, enabling them to make informed decisions when selecting artists for their tattoo appointments.

  • The Google Distance Matrix API allows us to calculate the distance and travel time between multiple origins and destinations, considering various transportation modes such as driving, walking, or public transit. This functionality empowers users to efficiently plan their tattoo appointments based on factors such as travel distance and estimated time of arrival, ensuring a seamless and convenient booking experience.

  • Additionally, by integrating the Google Distance Matrix API, we can optimize the routing and scheduling of appointments, minimizing travel time for both users and tattoo artists. This optimization not only enhances the overall efficiency of the booking process but also contributes to a more satisfying and streamlined user experience.

  • Distance Matrix Documentation

Contributors

Jack Sweeney

Laura R Vega V

Joey Reyes

Jessica Kohl

Faisal Nazari

Endpoints

User

Get One User

Request:

GET /api/v0/users/:id
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": {
    "id": "25",
    "type": "user",
    "attributes": {
      "name": "Ruby Gem",
      "location": "9705 Fishers District Dr, Fishers, IN 46037",
      "email": "[email protected]",
      "search_radius": 25,
      "password": null
    }
  }
}
Create User

Request:

POST /api/v0/users
Content-Type: application/json
Accept: application/json

Body:

{
  "user": {
	"name":"Jack Sweeney",
	"location":"3405 Legend Dr., Los Angeles, CA 90034",
	"email":"[email protected]",
	"search_radius":25,
	"password":"unreadable_hash"
  }
}

Response: status: 200

{
  "data": {
    "id":"4",
    "type":"user",
    "attributes": {
      "name":"Jack Sweeney",
      "location":"3405 Legend Dr., Los Angeles, CA 90034",
      "email":"[email protected]",
      "search_radius":25,
      "password": null
    }
  }
}
Update User Request:
PATCH /api/v0/users/:id
Content-Type: application/json
Accept: application/json

Body:

{
  "user": {
	"name":"New Name",
	"location":"223 S Amazon Dr., Indianapolis, IN, 46259",
	"email":"[email protected]",
	"search_radius":20,
	"password": null
  }
}

Response: status: 200

{
  "data": {
    "id":"4",
    "type":"user",
    "attributes": {
      "name":"Jack Sweeney",
      "location":"3405 Legend Dr., Los Angeles, CA 90034",
      "email":"[email protected]",
      "search_radius":25,
      "password": null
    }
  }
}
Delete User Request:
DELETE /api/v0/users/:id
Content-Type: application/json
Accept: application/json

Response: status: 204

Get User's (Liked) Tattoos Request:
GET /api/v0/users/:user_id/tattoos
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": [
    {
      "id": "11",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/379ece3d-6f4e-40d6-b7c4-47920d62ddfa",
        "price": 315,
        "time_estimate": 85,
        "artist_id": 0,
        "artist": {
            "id": 5,
            "name": "Ivy Running",
            "email": "[email protected]",
            "password_digest": null,
            "location": "45 Marathon Rd, Los Angeles, CA 90032",
            "created_at": "2024-04-19T00:23:41.504Z",
            "updated_at": "2024-04-19T00:23:41.504Z",
            "scheduling_link": "www.google.com"
        }
      }
    },
    {
      "id": "12",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/66a957cb-a6ef-4967-b049-dc6694022cf2",
        "price": 350,
        "time_estimate": 60,
        "artist_id": 5,
        "artist": {
            "id": 5,
            "name": "Ivy Running",
            "email": "[email protected]",
            "password_digest": null,
            "location": "45 Marathon Rd, Los Angeles, CA 90032",
            "created_at": "2024-04-19T00:23:41.504Z",
            "updated_at": "2024-04-19T00:23:41.504Z",
            "scheduling_link": "www.google.com"
        }
      }
    },
    {
      "id": "13",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/ad31388d-2480-49c3-b270-f4adcf6b7f9d",
        "price": 280,
        "time_estimate": 12,
        "artist_id": 8,
        "artist": {
            "id": 5,
            "name": "Ivy Running",
            "email": "[email protected]",
            "password_digest": null,
            "location": "45 Marathon Rd, Los Angeles, CA 90032",
            "created_at": "2024-04-19T00:23:41.504Z",
            "updated_at": "2024-04-19T00:23:41.504Z",
            "scheduling_link": "www.google.com"
        }
      }
    },
    {
      "id": "14",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/176b3ee5-22d9-4561-818b-e80c0fd36307",
        "price": 335,
        "time_estimate": 80,
        "artist_id": 8,
        "artist": {
            "id": 5,
            "name": "Ivy Running",
            "email": "[email protected]",
            "password_digest": null,
            "location": "45 Marathon Rd, Los Angeles, CA 90032",
            "created_at": "2024-04-19T00:23:41.504Z",
            "updated_at": "2024-04-19T00:23:41.504Z",
            "scheduling_link": "www.google.com"
        }
      }
    },
    {
      "id": "15",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/51cbb0a7-7d92-4835-b180-5ed250d2e815",
        "price": 245,
        "time_estimate": 75,
        "artist_id": 8,
        "artist": {
            "id": 5,
            "name": "Ivy Running",
            "email": "[email protected]",
            "password_digest": null,
            "location": "45 Marathon Rd, Los Angeles, CA 90032",
            "created_at": "2024-04-19T00:23:41.504Z",
            "updated_at": "2024-04-19T00:23:41.504Z",
            "scheduling_link": "www.google.com"
        }
      }
    }
  ]
}
User Dislike a Tattoo Request:
DELETE /api/v0/user_tattoos
Content-Type: application/json
Accept: application/json
{
  "message": "Successfully deleted a Tattoo"
  }
Create User Tattoo Request:
POST /api/v0/user_tattoos
Content-Type: application/json
Accept: application/json

Body:

{
  "user_tattoo": {
    "user_id":7,
    "tattoo_id":1,
     "type": "like"
  }
}
(where 7 and 1 are valid user and tattoo IDs)
(change type to "dislike" to create UserTattoo with a "disliked" status)

Response: status: 200

{
"message": "Tattoo successfully added to User"
}
Delete User Tattoo Request:
DELETE /api/v0/user_tattoos
Content-Type: application/json
Accept: application/json

Body:

{
  "user_tattoo": {
    "user_id":7,
    "tattoo_id":1
  }
}
(where 7 and 1 are valid user and tattoo IDs)

Response: status: 204

Get User's Identities Request:
GET /api/v0/users/:user_id/identities
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": [
    {
      "id": "5",
      "type": "identity",
      "attributes": {
        "identity_label": "Female"
      }
    },
    {
      "id": "6",
      "type": "identity",
      "attributes": {
        "identity_label": "Asian"
      }
    }
  ]
}
Create User Identity Request:
POST /api/v0/user_identities
Content-Type: application/json
Accept: application/json

Body:

{
  "user_identity": {
    "user_id":25,
    "identity_id":2
  }
}
(where 25 and 2 are valid user and identity IDs)

Response: status: 200

{
"message": "Identity successfully added to User"
}
Delete User Identity Request:
DELETE /api/v0/user_identities
? /api/v0/artists/:artist_id/identities/:id -> no body
Content-Type: application/json
Accept: application/json

Body:

{
  "user_identity": {
    "user_id":25,
    "identity_id":2
  }
}
(where 25 and 2 are valid user and identity IDs)

Response: status: 204

Artists

Get All Request:
GET /api/v0/artists
Content-Type: application/json
Accept: application/json

Response: status: 200

{"data": [
  {
    "id":"5",
    "type":"artist",
    "attributes": {
      "name":"Ronnie Medhurst",
      "email":"[email protected]",
      "password":null,
      "location":"Suite 431 840 Marnie Estates, North Stephnie, WA 82782-8921"
    }
  },
  {
    "id":"6",
    "type":"artist",
    "attributes": {
      "name":"Malissa Schaefer",
      "email":"[email protected]",
      "password":null,
      "location":"511 Collier Summit, Mairaport, DE 39107"
    }
  },
  {
    "id":"7",
    "type":"artist",
    "attributes": {
      "name":"Jake Quitzon",
      "email":"[email protected]",
      "password":null,
      "location":"521 Merrill Union, Treutelview, UT 72253"
    }
  },
  {
    "id":"8",
    "type":"artist",
    "attributes": {
      "name":"Abdul Moen III",
      "email":"[email protected]",
      "password":null,
      "location":"9173 Lashawn Court, East Haywoodshire, NC 51851"
    }
  },
  {
    "id":"9",
    "type":"artist",
    "attributes": {
      "name":"Mrs. Maynard West",
      "email":"[email protected]",
      "password":null,
      "location":"Apt. 264 13947 Kiehn Plain, Trevorbury, OH 95278"
      }
    }
  ]
}
Get One Artist Request:
GET /api/v0/artists/:id
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": {
    "id": "5",
    "type": "artist",
    "attributes": {
      "name": "Tattoo artists",
      "email": "[email protected]",
      "password": null,
      "location": "1400 U Street NW, Washington, DC 20009"
    }
  }
}
Create Artist Request:
POST /api/v0/artists
Content-Type: application/json
Accept: application/json

Body:

{
  "artist": {
    "name":"Ted Lasso",
    "location":"Pacific Ocean",
    "email":"[email protected]",
    "password":"TotalFutbol"
  }
}

Response: status: 200

{
  "data": {
    "id":"15",
    "type":"artist",
    "attributes": {
      "name":"Ted Lasso",
      "email":"[email protected]",
      "password": null,
      "location":"Pacific Ocean"
    }
  }
}
Update Artist Request:
PATCH /api/v0/artists/:id
Content-Type: application/json
Accept: application/json

Body:

{
  "artist": {
    "name":"Ted Lasso",
    "location":"Pacific Ocean",
    "email":"[email protected]",
    "password":"TotalFutbol"
  }
}

Response: status: 200

{
  "data": {
    "id":"15",
    "type":"artist",
    "attributes": {
      "name":"Ted Lasso",
      "email":"[email protected]",
      "password": null,
      "location":"Pacific Ocean"
    }
  }
}
Delete Artist Request:
DELETE /api/v0/artists/:id
Content-Type: application/json
Accept: application/json

Response: status: 204

Get Artist Identities Request:
GET /api/v0/artists/:artist_id/identities
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": [
    {
      "id": "5",
      "type": "identity",
      "attributes": {
        "identity_label": "Female"
      }
    },
    {
      "id": "6",
      "type": "identity",
      "attributes": {
        "identity_label": "Asian"
      }
    }
  ]
}
Create Artist Identity Request:
POST /api/v0/artist_identities
Content-Type: application/json
Accept: application/json

Body:

{
  "artist_identity": {
    "artist_id":2,
    "identity_id":8
  }
}
(where 2 and 8 are valid artist and identity IDs)

Response: status: 200

Delete Artist Identity Request:
DELETE /api/v0/artist_identities
? /api/v0/artists/:artist_id/identities/:id -> no body
Content-Type: application/json
Accept: application/json

Body:

{
  "artist_identity": {
    "artist_id":2,
    "identity_id":8
  }
}
(where 2 and 8 are valid artist and identity IDs)

Response: status: 204

Get Artist's Tattoos Request:
GET /api/v0/artists/:artist_id/tattoos
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": [
    {
      "id": "210",
      "type": "tattoos",
      "attributes": {
        "image_url": "/random/url/path",
        "price": 306,
        "time_estimate": 160,
        "artist_id": 288,
        "artist": {
          "id": 288,
          "name": "Margrett Dare I",
          "email": "[email protected]",
          "password_digest": null,
          "location": "90797 Hammes Lodge, Port Junefort, VT 43513",
          "created_at": "2024-04-18T21:38:06.092Z",
          "updated_at": "2024-04-18T21:38:06.092Z",
          "scheduling_link": "http://conn.example/sherilyn.witting"
        }
      }
    },
    {
      "id": "211",
      "type": "tattoos",
      "attributes": {
        "image_url": "/random/url/path",
        "price": 303,
        "time_estimate": 72,
        "artist_id": 288,
        "artist": {
          "id": 288,
          "name": "Margrett Dare I",
          "email": "[email protected]",
          "password_digest": null,
          "location": "90797 Hammes Lodge, Port Junefort, VT 43513",
          "created_at": "2024-04-18T21:38:06.092Z",
          "updated_at": "2024-04-18T21:38:06.092Z",
          "scheduling_link": "http://conn.example/sherilyn.witting"
        }
      }
    },
    {
      "id": "212",
      "type": "tattoos",
      "attributes": {
        "image_url": "/random/url/path",
        "price": 172,
        "time_estimate": 86,
        "artist_id": 288,
        "artist": {
          "id": 288,
          "name": "Margrett Dare I",
          "email": "[email protected]",
          "password_digest": null,
          "location": "90797 Hammes Lodge, Port Junefort, VT 43513",
          "created_at": "2024-04-18T21:38:06.092Z",
          "updated_at": "2024-04-18T21:38:06.092Z",
          "scheduling_link": "http://conn.example/sherilyn.witting"
        }
      }
    }
  ]
}

Tattoos

Get One Request:
GET /api/v0/tattoos/:id
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": {
    "id": "4",
    "type": "tattoos",
    "attributes": {
      "image_url": "image/path", 
      "price": 250, 
      "time_estimate": 90, 
      "artist_id": 19
    }
  }
}
Create Tattoo Request:
POST /api/v0/tattoos
Content-Type: application/json
Accept: application/json

Body:

{
  "price": 90, 
  "time_estimate": 120, 
  "artist_id": 18, 
  "image_url": "test/url/path"
}

Response: status: 200

{
  "data": {
    "id": "3", 
    "type": "tattoos", 
    "attributes": {
      "image_url": "test/url/path", 
      "price": 90, 
      "time_estimate": 120, 
      "artist_id": 18
    }
  }
}
Update Tattoo Request:
PATCH /api/v0/tattoos/:id
Content-Type: application/json
Accept: application/json

Body:

{
  "tattoo": {
    "price": 90, 
    "time_estimate": 120, 
    "artist_id": 18, 
    "image_url": "test/url/path"
  }
}

Response: status: 200

{
  "data": {
    "id": "4",
    "type": "tattoos",
    "attributes": {
      "image_url": "image/path", 
      "price": 250, 
      "time_estimate": 90, 
      "artist_id": 19
    }
  }
}
Delete Tattoo Request:
DELETE /api/v0/tattoos/:id
Content-Type: application/json
Accept: application/json

Response: status: 204

Get All Matching User's Pref Request:
GET /api/v0/tattoos?user=(:user_id)
Content-Type: application/json
Accept: application/json

Response: status: 200

{ 
  "data": [
    {
      "id": "1",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/fee274f7-0fa9-4606-855b-9c286fcb1661",
        "price": 300,
        "time_estimate": 90,
        "artist_id": 5
      }
    },
    {
      "id": "2",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/e94a0c62-8f4d-4e00-8de5-9c77cafc10c0",
        "price": 300,
        "time_estimate": 90,
        "artist_id": 5
      }
    },
    {
      "id": "3",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/c0fc1e3c-2af3-4bba-9f1b-739e3ee02c8a",
        "price": 250,
        "time_estimate": 80,
        "artist_id": 5
      }
    },
    {
      "id": "4",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/faa4aa31-75bf-4f8e-b7a8-77ad75856549",
        "price": 275,
        "time_estimate": 80,
        "artist_id": 7
      }
    },
    {
      "id": "5",
      "type": "tattoos",
      "attributes": {
        "image_url": "https://gist.github.com/assets/149989113/331f0aef-ab8e-4360-b9b7-fc991b12976f",
        "price": 325,
        "time_estimate": 85,
        "artist_id": 8
      }
    }
  ]
}

Identities

Get All

Request:

GET /api/v0/identities
Content-Type: application/json
Accept: application/json

Response: status: 200

{
  "data": [
    {
      "id": "1",
      "type": "identity",
      "attributes": {
        "identity_label": "LGBTQ+"
      }
    },
    {
      "id": "2",
      "type": "identity",
      "attributes": {
        "identity_label": "Black"
      }
    },
    {
      "id": "3",
      "type": "identity",
      "attributes": {
        "identity_label": "Native American"
      }
    },
    {
      "id": "4",
      "type": "identity",
      "attributes": {
        "identity_label": "Latino"
      }
    },
    {
      "id": "5",
      "type": "identity",
      "attributes": {
        "identity_label": "Female"
      }
    },
    {
      "id": "6",
      "type": "identity",
      "attributes": {
        "identity_label": "Asian"
      }
    },
    {
      "id": "7",
      "type": "identity",
      "attributes": {
        "identity_label": "None"
      }
    }
  ]
}
Sign In Request:
POST /api/v0/sign_in
Content-Type: application/json
Accept: application/json

Body:

{
  "sign_in": {
    "email": "[email protected]",
    "password": "123Password",
    "type": "Sign In as User"
  }
}

(where user email & password are correct)
Note: To sign in as an Artist, alter type to "Sign In as Artist"

Response: status: 200

{
  "data": {
    "id": 20, 
    "type": "artist"
  }
}
Sign Out

tattdaddy-be's People

Contributors

jackcsweeney avatar jriv-10 avatar kohljd avatar laurarvegav avatar mfaisalnazari avatar

Stargazers

 avatar  avatar

Watchers

 avatar

tattdaddy-be's Issues

distance matrix api

Distance Matrix API should send a response that responds with distance from user to all artists.

Response should like

{ "data": [
           {
               "artist_id": "1234"
                "distance": "25 miles"
               }
           },
           {
             "artist_id": "525"
                "distance": "25 miles"
               }
           },
           ...,
           ...,
       ]
   }

Idea for Disliked UserTattoos

Could potentially add enum to UserTattoos table that tracks the like/dislike action for the user. Then could easily sort on the tattoos that are shown to the user to not show already liked or disliked tattoos without having to create an additional table for the disliked ones.

GET One User

GET api/v0/users/:id
RETURNS all user data

{ "data": {
               "id": "322458",
               "attributes": {
                   "name": "user",
                   "location": "1400 U Street NW, Los Angeles, CA 90034 ",
                   "email": "[[email protected]](mailto:[email protected])",
                   “search_radius”: “25”,
                   "password_digest": "unreadable hash"
               }
           }
}

EDIT One User

PATCH api/v0/users/:id
RETURNS updated user data

{ "data": {
               "id": "322458",
               "attributes": {
                   "name": "user",
                   "location": "1400 U Street NW ",
                   "email": "[[email protected]](mailto:[email protected])",
                   “search_radius”: “25”
               }
           }
}

SAD PATH: CREATE New User

POST api/v0/users - where body is missing attributes for user

RETURN

 {
     "errors": [
         {
             "detail": "Validation Failed: <attribute_name> can't be blank"
         }
     ]
 }

verify sign in credentials

Request & Body

POST "/api/v0/sign_in" sent with params[:sign_in]

Note: "type" can be 'Sign In as Artist' or 'Sign In as User'

# just the params[:sign_in]

 "sign_in" => {
        "email" => "[email protected]", 
        "password" => "123", 
        "type" => "Sign In as Artist"
    }
# entire params

{
    "sign_in" => {
        "email" => "[email protected]", 
        "password" => "123", 
        "type" => "Sign In as Artist"
    }, 
    "controller" => "sessions", 
    "action" => "create"
}

Response

Happy:

status: 200
{
  data: {
     id: number
     type: artist or user
     }
}

Sad: status: 422 and potential error message

Create List of Identities for Identities Table

Create a list of all identities we would like to include as options for artists to select that they identify with and users to select as a preference for to see tattoos from.

Things like LGBTQ+ Friendly, Black, Woman, etc.

GET All Identities Endpoint

GET "/api/v0/identities"

RETURNS:

{ "data": [
   { "id": 1,
     "type": "identity",
     "attributes": {
         "identity_label": "LGBTQ+"
       },
   { "id": 2,
     "type": "identity",
     "attributes": {
         "identity_label": "Woman"
        },....
   ]
}

GET All Artists Tattoos

GET api/v0/artists/:id/tattoos
RETURNS all tattoos from specific artist

{ "data": [
           {
               "id": "322458",
               "attributes": {
                   "price": "300",
                   "time_estimate": "90",
                   "artist_id": "35446",
                   “image_url”: “image_url/link”
               }
           },
           {
               "id": "322474",
               "attributes": {
                   "price": "300",
                   "time_estimate": "90",
                   "artist_id": "35446",
                   “image_url”: “image_url/link”
               }
           },
           ...,
           ...,
       ]
   }

CREATE Tattoo

POST "/api/v0/tattoos"
BODY: {artist_id: 123123, image_url: "amazon/s3/url", price: 2354, time_estimate: 90}

RETURNS:

{ "data": 
           {
               "id": "322458",
               "attributes": {
                   "price": "300",
                   "time_estimate": "90",
                   "artist_id": "35446",
                   “image_url”: “image_url/link”
               }
           }
   }

SAD PATH: GET All Tattoos That Fit User Criteria

GET api/v0/tattoos?artists_identity={user_identity_preference}&radius={user_search_radius}&user_location={user_location} where user location is blank

RETURNS

 {
     "errors": [
         {
             "detail": "Must have location to find tattoos"
         }
     ]
 }

response sent to frontend

When frontend app uses endpoint "get /api/v0/tattoos?user=user_id" the json response is sent with the data we have filtered the our queries from the distance matrix API
response:

{ “data”: [ {
               "id": "322458",
               "attributes": {
                   "price": "300",
                   "time_estimate": "90",
                   "artist_id": "35446",
                   “image_url”: “image_url/link”
               }
           },
           "id": "322458",
                      "attributes": {
                             "price": "300",
                              "time_estimate": "90",
                              "artist_id": "35446",
                              “image_url”: “image_url/link”
                          }
                        },
    .....
    ....
] }

CREATE New User

POST api/v0/users
RETURNS newly created user data

{ "data": {
               "id": "322458",
               "attributes": {
                   "name": "user",
                   "location": "1400 U Street NW ",
                   "email": "[[email protected]](mailto:[email protected])",
                   “search_radius”: “25”,
                   "password_digest": "unreadable hash"
               }
           }
}

returned data from distance matrix api

Make SQL or Active Record Query that sends back a parsed JSON response with all artists that fit users set radius

result of this story should have an array of artist objects.

GET One Tattoo

GET api/v0/artists/:artist_id/tattoos/:id
RETURNS returns data for one specific Tattoo

{ “data”: {
               "id": "322458",
               "attributes": {
                   "price": "300",
                   "time_estimate": "90",
                   "artist_id": "35446",
                   “image_url”: “image_url/link”
               }
           }
}

returned data from query

Query response should be all artists within users set range then filter by checking identity matches with at least 1 of the preferred user identities.

CREATE UserTattoo

POST "/api/v0/user_tattoos" - status in the body is the liked or disliked enum. 0 for liked 1 for disliked
BODY:

{
     "user_id": 322474,
     "tattoo_id": 54861,
     "status": 0
 }

RETURNS { "message" : "Tattoo successfully added to User"}

GET User Tattoos

GET "/api/v0/users/:id/tattoos"
RETURNS All tattoos that have been liked by user

EDIT One Artist

PATCH api/v0/artists/:id
RETURNS Artist with new updated info

{ "data": {
               "id": "322458",
               "attributes": {
                   "name": "Tattoo artists",
                   "location": "1400 U Street NW ",
                   "email": "[[email protected]](mailto:[email protected])",
	       “Identity”: “LGBTQ+ Friendly”,
                   "password_digest": "unreadable hash"
               }
           }
}

SAD PATH: GET One Artist

GET api/v0/artists/:id - where artist id does not exist

RETURN

 {
     "errors": [
         {
             "detail": "Couldn't find Artist with 'id'=123123123123"
         }
     ]
 }

SAD PATH: DELETE One User

DELETE api/v0/users/:id where ID does not exist

RETURNS Error status 404

 {
     "errors": [
         {
             "detail": "Couldn't find User with 'id'=123123123123"
         }
     ]
 }

GET All Tattoos That Fit User Criteria

GET api/v0/tattoos?user={user_id}
RETURNS all tattoos from artists that fit preference and radius criteria

{ "data": [
           {
               "id": "322458",
               "attributes": {
                   "price": "300",
                   "time_estimate": "90",
                   "artist_id": "35446",
                   “image_url”: “image_url/link”
               }
           },
           {
               "id": "322474",
               "attributes": {
                   "price": "300",
                   "time_estimate": "90",
                   "artist_id": "35446",
                   “image_url”: “image_url/link”
               }
           },
           ...,
           ...,
       ]
   }

DELETE One Artist

DELETE api/v0/artists/:id
RETURNS successful status of 204
{ “status”: 204 }

Pagination in views/API

Acceptance Criteria: Team should be able to demonstrate pagination as implemented. Ideally, be able to show the value this feature adds to the application.

GET One Artist

GET api/v0/artists/:id
RETURNS Artist that matches sent ID with all attributes associated with that artist

{ "data": {
               "id": "322458",
               "attributes": {
                   "name": "Tattoo artists",
                   "location": "1400 U Street NW ",
                   "email": "[[email protected]](mailto:[email protected])",
	       “Identity”: “LGBTQ+ Friendly”,
                   "password_digest": "unreadable hash"
               }
           }
}

SAD PATH: EDIT One Artist

PATCH api/v0/artists/:id - where attributes being edited are left blank

RETURN

 {
     "errors": [
         {
             "detail": "<attribute_name> must not be blank"
         }
     ]
 }

SAD PATH: GET One User

GET api/v0/users/:id - where user id does not exist

RETURN

 {
     "errors": [
         {
             "detail": "Couldn't find User with 'id'=123123123123"
         }
     ]
 }

SAD PATH: EDIT One User

EDIT api/v0/users/:id - where edited attribute is left blank

RETURNS

 {
     "errors": [
         {
             "detail": "Validation error: <attribute_name> cannot be blank"
         }
     ]
 }

CREATE New Artist

POST api/v0/artists
BODY:

{ "attributes": {
                   "name": "Tattoo artists",
                   "location": "1400 U Street NW ",
                   "email": "[[email protected]](mailto:[email protected])",
	           “Identity”: “LGBTQ+ Friendly”,
                   "password_digest": "unreadable hash"
                       }
}

RETURNS newly created artist

{ "data": {
               "id": "322458",
               "attributes": {
                   "name": "Tattoo artists",
                   "location": "1400 U Street NW ",
                   "email": "[[email protected]](mailto:[email protected])",
	           “Identity”: “LGBTQ+ Friendly”,
                   "password_digest": "unreadable hash"
               }
           }
}

setup artist scheduling link

Add scheduling_link attribute to artist with a presence: true validation.
Update tattoo serializer to create JSON response that includes artist's scheduling link attribute value.

sign out user or artist

Request
DELETE "/api/v0/sign_out"

BODY: { "user_id": "1" } or {"artist_id": "1"}

Response
Happy: 204 status

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.