Teamtable is a project management web application made for the web development course at HTW Berlin by Janis Schanbacher and Florian Wolf. This repository is the Ruby on Rails backend, which provides a RESTful API. The React frontend can be found here and tested at: teamtable.io.
The following functionalities are implemented in the API
- User registration, e-mail confirmation, password reset
- Token authentication (using devise, devise-jwt), authorization
- Projects, lists, cards and tags
- Memberships and assignments
- Multilanguage
Clone the repository to your local machine
$ git clone https://github.com/teamtable/teamtable-api.git
Install the needed gems from within the repository:
$ cd teamtable-api $ bundle install --without productionMigrate the database:
$ rails db:migrate
The following two steps are required in order to access credentials and other encrypted files.
Create a file config/master.key
$ touch config/master.key
Ask one of the developers for the masterkey and insert it into
config/master.key$ echo"replace with masterkey">> config/master.key
Finally, run the test suite to verify that everything is working correctly:
$ rails testIf the test suite passes, you'll be ready to run the app in a local server:
$ rails server -p 3001
To use the application locally run $ rails server -p 3001 and use the following request base URL: http://localhost:3001
Sign up
$ curl -X POST \ https://teamtable-api.herokuapp.com/signup \ -H 'Content-Type: application/json' \ -d '{ "user": { "name": "Test User", "email": "test.user@mail.com", "password": "password", "password_confirmation": "password" }, "locale" : "en" }'
Log in
$ curl -X POST \ https://teamtable-api.herokuapp.com/login \ -H 'Content-Type: application/json' \ -d '{ "user": { "email": "test.user@mail.com", "password": "password" } }'
copy authorization header from response and use for requests that require authentication
Create Project
$ curl -X POST \ https://teamtable-api.herokuapp.com/projects \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI4Iiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNTU1OTYyMDA3LCJleHAiOjE1NTYwNDg4MDcsImp0aSI6ImEzMGViZjI1LTIyNWYtNDg3NS05NTVjLTEyM2RiNjViYzE0NSJ9.Zjc5zsyNToFVS3N_QTofxdoR4oWUyIdsELum6SLMbh4' \ -H 'Content-Type: application/json' \ -d '{ "project" : { "title" : "new project", "description" : "project description" } }'
Create List
$ curl -X POST \ https://teamtable-api.herokuapp.com/lists \ -H 'Authorization: Bearer <Token>' \ -H 'Content-Type: application/json' \ -d '{ "list" : { "title" : "new list", "description" : "list description", "project_id": "1" } }'
Create Card
$ curl -X POST \ https://teamtable-api.herokuapp.com/cards \ -H 'Authorization: Bearer <Token>' \ -H 'Content-Type: application/json' \ -d '{ "card" : { "title" : "new card", "description" : "card description", "list_id": "1" } }'
Get all lists (including cards) of current project
$ curl -X GET \ https://teamtable-api.herokuapp.com/lists \ -H 'Authorization: Bearer <Token>' \ -H 'Content-Type: application/json'
$ railsroutesPrefixVerbURIPatternController#Actionnew_user_sessionGET/login(.:format) sessions#new {:format=>:json} user_session POST /login(.:format)sessions#create {:format=>:json}destroy_user_sessionDELETE/logout(.:format) sessions#destroy {:format=>:json} new_user_password GET /password/new(.:format)passwords#new {:format=>:json}edit_user_passwordGET/password/edit(.:format)passwords#edit {:format=>:json}user_passwordPATCH/password(.:format) passwords#update {:format=>:json} PUT /password(.:format)passwords#update {:format=>:json}POST/password(.:format) passwords#create {:format=>:json} cancel_user_registration GET /signup/cancel(.:format)registrations#cancel {:format=>:json}new_user_registrationGET/signup/sign_up(.:format)registrations#new {:format=>:json}edit_user_registrationGET/signup/edit(.:format)registrations#edit {:format=>:json}user_registrationPATCH/signup(.:format) registrations#update {:format=>:json} PUT /signup(.:format)registrations#update {:format=>:json}DELETE/signup(.:format) registrations#destroy {:format=>:json} POST /signup(.:format)registrations#create {:format=>:json}new_user_confirmationGET/confirmation/new(.:format)confirmations#new {:format=>:json}user_confirmationGET/confirmation(.:format) confirmations#show {:format=>:json} POST /confirmation(.:format)confirmations#create {:format=>:json}new_user_unlockGET/unlock/new(.:format)devise/unlocks#new {:format=>:json}user_unlockGET/unlock(.:format) devise/unlocks#show {:format=>:json}POST/unlock(.:format) devise/unlocks#create {:format=>:json}projectsGET/projects(.:format) projects#index POST /projects(.:format)projects#createprojectGET/projects/:id(.:format)projects#showPATCH/projects/:id(.:format)projects#updatePUT/projects/:id(.:format)projects#updateDELETE/projects/:id(.:format)projects#destroymembershipsGET/memberships(.:format) memberships#index POST /memberships(.:format)memberships#createmembershipGET/memberships/:id(.:format)memberships#showDELETE/memberships/:id(.:format)memberships#destroycurrent_projectGET/current-project(.:format) projects#current project_members GET /projects/:id/members(.:format)projects#membersproject_tagsGET/projects/:id/tags(.:format)projects#tagsproject_listsGET/projects/:id/lists(.:format)projects#listslistsGET/lists(.:format) lists#index POST /lists(.:format)lists#createlistGET/lists/:id(.:format)lists#showPATCH/lists/:id(.:format)lists#updatePUT/lists/:id(.:format)lists#updateDELETE/lists/:id(.:format)lists#destroylist_membershipsGET/list_memberships(.:format) list_memberships#index POST /list_memberships(.:format)list_memberships#createlist_membershipGET/list_memberships/:id(.:format)list_memberships#showDELETE/list_memberships/:id(.:format)list_memberships#destroylist_membersGET/lists/:id/members(.:format)lists#memberslist_tagsGET/lists/:id/tags(.:format)lists#tagslist_cardsGET/lists/:id/cards(.:format)lists#cardslist_update_positionPATCH/lists/:id/position(.:format)lists#update_positionlist_positions_update_allPATCH/list-positions(.:format) list_positions#update_all cards GET /cards(.:format)cards#indexPOST/cards(.:format) cards#create card GET /cards/:id(.:format)cards#showPATCH/cards/:id(.:format)cards#updatePUT/cards/:id(.:format)cards#updateDELETE/cards/:id(.:format)cards#destroyassignmentsPOST/assignments(.:format) assignments#create assignment PATCH /assignments/:id(.:format)assignments#updatePUT/assignments/:id(.:format)assignments#updateDELETE/assignments/:id(.:format)assignments#destroycard_assigned_usersGET/cards/:id/assigned-users(.:format)cards#assigned_userscard_doing_usersGET/cards/:id/doing-users(.:format)cards#doing_userscard_tagsGET/cards/:id/tags(.:format)cards#tagscard_positions_update_allPATCH/card-positions(.:format) card_positions#update_all tags GET /tags(.:format)tags#indexPOST/tags(.:format) tags#create tag GET /tags/:id(.:format)tags#showPATCH/tags/:id(.:format)tags#updatePUT/tags/:id(.:format)tags#updateDELETE/tags/:id(.:format)tags#destroyattachmentsPOST/attachments(.:format) attachments#create attachment DELETE /attachments/:id(.:format)attachments#destroytag_cardsGET/tags/:id/cards(.:format)tags#cardsuser_created_cardsGET/users/:id/created-cards(.:format)users#created_cardsuser_assigned_cardsGET/users/:id/assigned-cards(.:format)users#assigned_cardsuser_doing_cardsGET/users/:id/doing-cards(.:format)users#doing_cardsuser_completed_cardsGET/users/:id/completed-cards(.:format)users#completed_cardsrails_service_blobGET/rails/active_storage/blobs/:signed_id/*filename(.:format)active_storage/blobs#showrails_blob_representationGET/rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format)active_storage/representations#showrails_disk_serviceGET/rails/active_storage/disk/:encoded_key/*filename(.:format)active_storage/disk#showupdate_rails_disk_servicePUT/rails/active_storage/disk/:encoded_token(.:format)active_storage/disk#updaterails_direct_uploadsPOST/rails/active_storage/direct_uploads(.:format)active_storage/direct_uploads#create