Developer guide for JustMatch Api.
The code follows most Rails conventions. If you've worked with Rails before the project should be easy to navigate.
-
Technology
- Ruby 2.5
- Ruby on Rails 5.2
- PostgreSQL 9.5
- Redis 3
-
PostgreSQL extensions
unaccent
-
Environment variables
- Used to configure app
- List of variables
-
Uses
sidekiq
for background jobs (including emails) -
All role based access is contained in
app/policies
- One for each controller
- Uses the
pundit
gem
-
JSON serialization
- Uses the
active_model_serializers
gem- Uses the JSON API adapter
- Uses the
jsonapi_helpers
gem - Follows the JSON API standard
- Uses the
-
Notifications and emails
- An
ActionMailer
like implementation for SMS has been implemented, seeJobTexter
- Every single notification/email has their on class in
app/notifiers
- Notifiers invokes the appropriate mailers and texters
- Sends SMS messages using Twilio and the
twilio-ruby
gem
- An
-
Invoices
- Integrates with Frilans Finans, using the gem
frilans_finans_api
- Almost all API communication with Frilans Finans is done from scheduled jobs
- Integrates with Frilans Finans, using the gem
-
Geocoding
- Uses
geocoder
- All models that need geocoding abilities include the
Geocodable
module - Uses Google Maps under-the-hood
- Uses
-
File upload
- Uses the
paperclip
gem, together withaws-sdk
to save files to AWS S3 - All files are uploaded separately, the API then returns a token, that then can be used when creating a new resource
- Uses the
-
Internal gems
- Some logic have been extracted to gems located in
lib/
, i.eJsonApiHelpers
"A set of helpers for generating JSON API compliant responses."FrilansFinansApi
"Interact with Frilans Finans API."
- They aren't published separately because they aren't quite complete or ready for external use
- Some logic have been extracted to gems located in
-
Errors & Monitoring
- Uses the Airbrake and the
airbrake
gem for error notifications
- Uses the Airbrake and the
-
API versions
- All routes namespaced under
api/v1/
- All controllers namespaced
Api::V1
- All routes namespaced under
-
Admin tools
- Uses
activeadmin
gem - Admin interface under
admin
subdomain - Admin insights interface under path
/insights
- Uses the
blazer
gem
- Uses the
- Uses
-
SQL queries/finders
- Located in
app/models/queries
namespaced underQueries
- Located in
-
Documentation
- Generate docs with
script/docs
- Uses the
apipie-rails
gem - API documentation is annotated just above each controller method
- The
Doxxer
class inapp/support
is for writing and reading API response examples
- Generate docs with
-
Tests
- Uses
rspec
- Uses
factory_bot
- Runners in
spec/spec_support/runners
are used to run extra checks when running tests- Runs only when running the entire test suite or if explicitly set
- Some of them can halt the execution and return a non-zero exit status.
- Test helpers are located in
spec/spec_support
- Uses
webmock
- Geocode mocks in
spec/spec_support/geocoder_support.rb
- Uses
-
Model translation
- Each model that need translated columns
- has a corresponding model, i.e
JobTranslation
- includes
Translatable
module
- has a corresponding model, i.e
- Translation model
- includes
TranslationModel
module
- includes
- Defines the translated columns with the
translates
macro- That macro defines an instance method
set_translation
on the model
- That macro defines an instance method
- There are a few helper services, and corresponding
ActiveJob
classes to process translationsProcessTranslationService
takes a translation and creates translations for to all eligible localesCreateTranslationService
takes a translation and a language for it to be translated to- Both
ProcessTranslationService
andCreateTranslationService
have corresponding background jobsProcessTranslationJob
andCreateTranslationJob
- Uses Google Translate under the hood
- Translations will only be created if the detected source language is over a certain threshold
- Each model that need translated columns
-
Static Translations
- Uses
rails-i18n
- Stored in
config/locales/
- Supports fallbacks
- Uses Transifex to translate.
- Configuration in
.tx/config
- Push/pull translations with Transifex CLI
- Configuration in
- Uses
-
Receiving SMS
- Configure a HTTP POST Hook in the Twilio Console
- Add the route:
POST https://api.justarrived.se/api/v1/sms/receive?ja_KEY=$JA_KEY
, replace$JA_KEY
with something secret.
- Add the route:
- The SMS from number will be looked up and if there is a match a message will be added to the chat between that user and our "support user" or admin.
- Configure a HTTP POST Hook in the Twilio Console
-
Receiving Email
- The env variable
DEFAULT_SUPPORT_EMAIL
should match the email of the "support user" - See Sendgrids docs https://sendgrid.com/docs/API_Reference/Webhooks/parse.html
- Basically you need to
- Setup some CNAME records pointing to Sendgrids
- Setup and MX record for a subdomain that Sendgrid will "handle", i.e if you setup
email.example.com
, Sendgrid will handle all emails sent to that subdomain - Configure their "Parse" HTTP POST Hook
- Add the route:
POST https://api.justarrived.se/api/v1/email/receive?ja_KEY=$JA_KEY
, replace$JA_KEY
with something secret.
- The email from address will be looked up and if there is a match a message will be added to the chat between that user and our "support user" or admin.
- The env variable
Setup dev database from Heroku app
$ bin/rails dev:db:heroku_import[heroku-app-name]
if you're using zsh
you have to escape [
and ]
, more info.
$ bin/rails dev:db:heroku_import\[heroku-app-name\]
Restore database command
$ pg_restore --no-owner -d <db_name> <path_to_db_data_dump>
Setup database from Heroku for development use
Download database dump from Heroku
$ heroku pg:backups:download --app=<heroku_application_name>
Import database to development database
# Reset the database to make sure the database dump is imported cleanly
$ rails db:drop db:create
$ pg_restore --no-owner -d just_match_development latest.dump
Anonymize database
$ rails dev:anonymize_database
The database is now safe for development use and you can login as admin with username [email protected]
and password 12345678
.