Avarts (name change pending) is an open-source, self-hostable, and private fitness app with some of the basic features from Strava.
Docker is the quickest way of getting a local development server up and running.
git clone https://github.com/ethanfann/avarts.git && cd avarts
Copy .env.example
to .env
cp .env.example .env
Open .env
and update the following:
MAPBOX_TOKEN
ADMIN_EMAIL
ADMIN_PASSWORD
ADMIN_FIRST_NAME
ADMIN_LAST_NAME
Admin .env
variables will be used during database seed to create the default admin account.
Copy frontend/.env.example
to frontend/.env
. This contains an env variable, REACT_APP_SERVER_URL
that points to the server.
cp frontend/.env.example frontend/.env
Build the Docker image
docker compose build
Run Docker compose
docker compose up
Start the frontend in a separate terminal window, which will open a webpage at localhost:3001
once done.
cd frontend && npm install && npm run start
Login with ADMIN_EMAIL
and ADMIN_PASSWORD
from .env
Download a GraphQL client like GraphiQL and point it to http://127.0.0.1:3000/graphql
in order to execute queries and mutations against the server.
All GraphQL responses are statically typed. Create a new file in app/graphql/types
in order to add a new type.
Ex.
activity_comment_type.rb
module Types
class ActivityCommentType < BaseModel
field :comment, String, null: false
field :user, UserType, null: false
end
end
The general process for creating a new query is as follows:
- Create a resolver in
app/graphql/resolvers/
- Append the resolver to
app/graphql/types/query_type.rb
Ex.
app/graphql/resolvers/ping.rb
class Resolvers::Ping < GraphQL::Schema::Resolver
type String, null: false
description 'Ping Pong'
def resolve
'Pong'
end
end
module Types
class QueryType < BaseObject
# ...
field :ping, resolver: Resolvers::Ping
# ...
end
end=
The general process for creating a new mutation is as follows:
- Create a resolver in
app/graphql/mutations/
- Append the resolver to
app/graphql/types/mutation_type
Ex.
app/graphql/mutations.add_activity_comment.rb
module Mutations
class AddActivityComment < GraphQL::Schema::Mutation
argument :comment, String, required: true
argument :activity_id, ID, required: true
argument :user_id, ID, required: true
type Types::ActivityCommentType
def resolve(comment: nil, activity_id: nil, user_id: nil)
ActivityComment.create!(
comment: comment,
activity_id: activity_id,
user_id: user_id,
)
end
end
end
GraphQL Code Generator is used to provide typed components and hooks for use in the frontend React SPA.
To generate a schema from Rails.
- Export the GraphQL Schema from Rails
rake graphql:schema:dump
- Run Codegen
cd frontend && npm run codegen
Note: This step is required after making any modifications to the Rails models or graphql types.
- Add the mutation/query in
frontend/src/graphql/[mutations/query]
frontend/src/graphql/mutations/addActivityComment.mutation.ts
import gql from "graphql-tag";
export default gql`
mutation AddActivityComment(
$comment: String!
$userId: ID!
$activityId: ID!
) {
addActivityComment(
comment: $comment
userId: $userId
activityId: $activityId
) {
id
}
}
`;
- Import a Query/Mutation
frontend/src/components/UploadForm.tsx
import { useAddActivityCommentMutation } from "../../generated/graphql";
const ActivityCommentBox = (props: Props) => {
// ...
const [addActivityCommentMutation] = useAddActivityCommentMutation()
// ...
const addComment = async (e: React.FormEvent, currentUser: UserType) => {
e.preventDefault()
if (currentUser && currentUser.id && activityId) {
await addActivityCommentMutation({
variables: {
comment: comment,
userId: currentUser.id,
activityId: activityId,
},
refetchQueries: ['myActivites'],
})
}
// ...
}
return (
// ...
)
}
Terraform is used to manage the creation of AWS resources for running in production. Currently this includes:
- S3: Stores user avatar and Mapbox static activity ride images.
- Cloudfront: Serves S3 assets over a CDN.
- Install Terraform
- Verify an AWS profile has been created in
~/.aws
. - Run the Terraform commands below
terraform init
terraform plan
terraform apply
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
for more information.
Ethan Fann - github@ethanfann.com
Project Link: https://github.com/ethanfann/avarts