As per the assignment, requirements were limited to Create a production-ready web endpoint that accepts a JSON payload as a POST request and sends an alert to a Slack channel if the payload matches desired criteria. Requirements were straight forward. I took the liberty to build a product which provides following functional and non-fucntion features around the core requirement. But keeping estimated time in mind, I'll be providing seed file to populate database with relevant data so that we can leave implementation of additional APIs for later stage and only focus on core requirement for this submission.
- Authentication - Currently uses Basic auth to secure endpoint so that no one can misuse endpoint in sending spam/explicit messages to slack channels. It can be change to more secured signature based authentication with minimal additions.
- Retry mechanism with exponential backoff using wait and jitter options in active job's retry_on callback
- Throttling using rack-attack
- Using application-level encryption supported by Active record to securely store slack api tokens and basic auth secret tokens
- Extendable database design which can accomodate multiple clients and each client can have multiple projects and client can setup project specific slack alert for N number of alery types. See this
- Additional communication channels such as Email, SMS, can be added with minimal modification in current database design
- Code is divided across services such as SpamDetection so that new services can be added quicker and code is easier to understand. See this
- Docker
- Test coverage
- JWT based user authentication
- Uses UUIDs in-place of IDs to reference records so that record ids are not prone to guessing.
- Ruby - "3.0.4"
- Rails - "~> 7.0.4"
- Postgresql
- Docker
- Postman
- Slack-api-client
- Some important gems/tools : Rodauth, Erd, Rspec, Webmock, Rack-attack
Note - 1 - You don't need to install rails, ruby, postgresql in your local system if you want to setup project only using docker. After installing docker, See this section to setup project using docker.
Note - 2 - As I wasn't provided with any email address with which I can share the private github repo that is why project repo is public. And for the same reason, I had to commit master.key file which is important for active record encryption. Otherwise I would've shared such credentials separately in email.
-
Please install Ruby if you don't already have one installed. You can follow steps from following link for the installation.
-
Install Rails
https://guides.rubyonrails.org/v5.1/getting_started.html#installing-rails
-
Install Postgresql db
-
Install Docker
-
Install Postman
-
Obtain Slack API token
To receive slack alert. You've to create a slack bot and integrate it into your slack workspace. Please follow below steps:
a. Create new slack app
b. Click on
Oauth & Permissions
item from left side menuc. Go to
Scopes
section and add Oauth scopes. You must addchat:write
scope in order to send messages to slack channelsd. Go to
OAuth Tokens for Your Workspace
section on same screen and note down your Slack API tokene. Add bot into your slack channel where you want to receive alers.
d. Note down channel's name with
#
There are three ways to setup this project.
Let me explain each method.
-
Clone this repo in your local system using
git clone https://github.com/bittu-choudhary/alert-badger.git
-
Make sure your local postgresql server is up and running.
-
Run
bundle install
-
Change following database configuration as per your system in
config/database.yml
host: localhost username: <your-postgresql-username> password: <your-postgresql-password>
-
Create database
bin/rails db:create
-
Migrate database
rails db:migrate
-
Add Slack API token, Slack channel Name and basic auth secret token in
seed.rb
file -
Seed database
rails db:seed
-
Run rails server and use APIs. For API usage, check below .
rails s
-
Your app is up and running on
http://127.0.0.1:3000
- Clone this repo in your local system using
git clone https://github.com/bittu-choudhary/alert-badger.git
- change directory to code folder and run following command.
docker compose -f docker-compose.yml -f docker-compose-dev.yml up --build
- Above command should run following three containers
ad_postgres pgadmin4 alert_badger
- Run migrations
docker-compose run alert_badger rake db:migrate
- Add Slack API token, Slack channel Name and basic auth secret token in
seed.rb
file - Seed database
docker-compose run alert_badger rake db:seed
- Your app is up and running on
http://127.0.0.1:3000
- Docker is setup to run pgadmin client. Read this section to know more.
-
You can access pgadmin web client using following credentials.
host: http://localhost:12345/ email: bittu@test.com password: password
-
Click on
Add new server
and use following configurations in respective tab andsave
- TabName Configuration - General Name - <choose-any-server-name> - Connection Host - postgres Username - alert_badger_app Password - password
-
You should see new server added to left side pan. Expand it and you can access databases.
Project includes Postman API client's collection and environment.
You can use following API to send alert.
- Alert
- Create :
POST /api/v1/alerts
- Create :
Accessing rails console
-
For source and localhost setup run :-
rails c
-
For source and docker setup, run :-
docker compose run alert_badger rails c
Application uses Rspec. To run test suits, run below command.
rspec
For more details regarding options and documentation, read here
Idea was to design a schema which can be use as a standalone product for alerting clients based on their preferences. Here is brief summary of each table and their association with each other
- User - Keep record of all users. keeps a boolean to differentiate admins
- Client - Client belongs to User. It contains client specific details
- Project - Project belongs to client. Client can have many projects. Store project specific information and secret token unique to each project. Project name and secret token is being used as credentials for basic authentication
- Slack Integration - Stores slack workspace details such as workspace name and slack api token. Belongs to client. Client can have many slack integrations
- Slack Notification Receiver - Stores slack channel details and their relationship with projects and notification types. Client can customize slack alert preferences based on combination of projects, types and channels. Belongs to Notification type, Belongs to projects, Belongs to Slack Integration
- Notification Type - Stores type of notifications
- Alert Details - Stores details of all incoming alerts including their payload. Belongs to Project.
- Notification Detail - Store details of all outgoing notifications including slack alerts. Belongs to Projects, Alert Details, Notification Type, Slack Notification Receivers.
This project uses three services to keep code clean and modular.
- Alert Handler - It takes care of all operations related to alert object. It inspects alert object and do needful based on result of inspection
- Spam Detection - It takes care of rules and policies which determines if an alert is spam or not
- Slack Notifier - It takes care of extracting alert receivers and schedules slack alert to all those receivers