• Stars
    star
    595
  • Rank 75,217 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 8 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🏈 A microservice to issue, register and manage boletos

superbowleto

Build Status Quality Gate Status Security Rating Reliability Rating Bugs Maintainability Rating Vulnerabilities Code Smells Lines of Code Coverage Duplicated Lines (%) Technical Debt

🏈 A microservice to issue, register and manage boletos

Table of Contents

Technology

Here's a brief overview of our technology stack:

  • Docker and Docker Compose to create our development and test environments.
  • AWS Fargate to manage and deploy our containers.
  • AWS SQS as a queue manager to process things like boletos to register and SQS Quooler as a package to make the interaction with queues more easy.
  • Postgres as to store our data and Sequelize as a Node.js ORM.
  • Ava as a test runner and Chai to do some more advanced test assertions.
  • Express as a tool to build the web server that handles our boleto endpoints.

Developing

In order to develop for this project you must have Docker and Docker Compose installed.

First Install

If you never developed in this repo before:

  1. Clone the repository:
$ git clone [email protected]:pagarme/superbowleto
  1. Build the base images:
$ docker-compose build superbowleto-web

Running the server

To run the server, you will have to start the database and run the migrations.

  1. Start database and run migrations in one command:
$ make setup-db
  1. Or start database and run migrations separately:
  • Start database (postgres):

    $ make start-db
  • Run the migrations:

    $ make migrate
  1. Then finally run the server:
$ make superbowleto-web

Running tests

Tests are separate in functional, integration and unit. You can either run them separately or run them all.

  • Run all tests:

    $ docker-compose run test
  • Run only functional tests:

    $ docker-compose run test npm run test-functional
  • Run only integration tests:

    $ docker-compose run test npm run test-integration
  • Run only unit tests:

    $ docker-compose run test npm run test-unit

For the CI purposes we have a specif command that will generate coverage report and xml test results report to be published at the CircleCI.

$ docker-compose run --entrypoint="npm run test-ci" test --abort-on-container-exit

Installing new dependencies

We install our dependencies (aka npm dependencies) inside the Docker image (see our Dockerfile to understand it better).

This gives us the advantage of caching the dependencies installation process, so when we build the image again, it's already cached by Docker and the image can be easily distributed with all its dependencies installed.

However, if you need to install any new dependency, you must rebuild the image, otherwise, your dependency will not be available inside the container.

You can install dependencies and rebuild the image by running:

$ docker-compose run test npm install --save ramda
$ docker-compose build test

Testing

Tests are found inside the test/ directory and are separate by type: functional, integration and unit. It's also common to have some helpers folders alongside the tests.

  • Unit tests are used to test the smallest units of functionality, typically a method or a function ref.

    The folder structure of the unit tests tend to mirror the folder structure of the src folder. For instance, we generally see the following folder structure:

    ├── src
    │   ├── index.js
    │   └── lib
    │       └── http.js
    └── test
        └── unit
            ├── index.js
            └── lib
                └── http.js
    
  • Integration tests build on unit tests by combining the units of code and testing that the resulting combination functions correctlyref.

    The folder structure of the integration tests tend to mirror the folder structure of the src folder. For instance, we generally see the following folder structure:

    ├── src
    │   ├── index.js
    │   └── lib
    │       └── http.js
    └── test
        └── integration
            ├── index.js
            └── lib
                └── http.js
    
  • Functional tests check a particular feature for correctness by comparing the results for a given input against the specification. Functional tests don't concern themselves with intermediate results or side-effects, just the resultref.

    The folder structure of functional tests does not need to mirror the source folder, and the files can be organized as they seem fit. One way to organize this files is by feature or user-story. For instance, take a look at the example below, where boleto/create.js and boleto/register.js are complete user stories:

    ├── test
        └── functional
            └── boleto
                └── create.js
                └── register.js
    
  • Helpers do not test anything, but instead provide tools for the tests. Inside the helpers folders one can have fixtures (also know as "mocks"), or some util functions.

    For instance, if you need credit card information to perform various tests in many different places, or if you need an util function that is called before your tests are ran, you could place them inside a helpers folder in order to not repeat yourself:

    const creditCardMock = {
      number: 4242424242424242,
      holder_name: "David Bowie",
      expiration_date: 1220,
      cvv: 123,
    };
    
    const cleanUpBeforeTests = () => {
      db.reset();
    };
    
    module.exports = {
      creditCardMock,
      cleanUpBeforeTests,
    };

    Helpers folders can be created at any level within the test folder structure. If some helper is used only for unit tests, it should reside within test/unit/helpers. If the helpers is used across all tests, it should reside within test/helpers. If there's a helper that is used only for testing the http module on integration tests, then it should reside within test/integration/http/helpers.

Data Flow

This project has two programs, the worker and the server.

Server

This section documents what every endpoint of the server does.

1. POST /boletos

Create a new boleto.

After creating the boleto (on our database), we will try to register the boleto withing the provider. Here, there's two possible outcomes: a) the provider could be reached, could process the boleto and gave us a status (either registered or refused); or b) the provider could not be reached or could not process the boleto (giving us an unknown/undefined/try_later status).

a) Provider could process the boleto

The following steps illustrate the case where the provider could be reached and it could process the boleto.

  1. The Client makes an HTTP request to create a boleto.
  2. We create the boleto in the Database with status issued.
  3. We try to register the boleto within the Provider.
  4. The provider returns an answer (either registered or refused).
  5. We update the boleto status in the Database.
  6. We return the response to the Client (HTTP response).

1a-post-boletos-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

b) Provider could not process the boleto

The following steps illustrate the case where the provider could be reached and it could process the boleto.

  1. The Client makes an HTTP request to create a boleto.
  2. We create the boleto in the Database with status issued.
  3. We try to register the boleto within the Provider.
  4. The provider could not be reached or could not process the boleto.
  5. We update the boleto status in the Database to pending_registration.
  6. We send the boleto (boleto_id and issuer) to an SQS queue called boletos-to-register. This queue will be processed by the worker later.
  7. We return the response to the Client (HTTP response) with the status = pending_registration.

1b-post-boletos-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

Example:

POST /boletos

Content-Type: application/json

{
  "queue_url": "http://yopa/queue/test",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}

201 Created

Content-Type: application/json

{
  "queue_url": "http://yopa/queue/test",
  "status": "issued | registered | refused",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "issuer_id": null,
  "title_id": "null",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}

2. GET /boletos

Retrieve all boletos.

2-get-boletos-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

Example:

GET /boletos

Content-Type: application/json

{
  "count": "10",
  "page": "1"
}

200 Ok

Content-Type: application/json

[{
  "id": "bol_cj1o33xuu000001qkfmlc6m5c",
  "status": "issued",
  "queue_url": "http://yopa/queue/test",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "issuer_id": null,
  "title_id": "null",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}]

3. GET /boletos/:id

Find one boleto by id.

3-get-boletos-id-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

Example:

GET /boletos/:id

Content-Type: application/json

{
  "id": "bol_cj1o33xuu000001qkfmlc6m5c"
}

200 Ok

Content-Type: application/json

{
  "id": "bol_cj1o33xuu000001qkfmlc6m5c",
  "status": "issued",
  "queue_url": "http://yopa/queue/test",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "issuer_id": null,
  "title_id": "null",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}

Worker

This section documents what the worker processes.

1. Process boletos-to-register queue

This is a worker which consumes the queue which has boletos to register and effectively register them.

When a boleto can't be registered within the provider at the moment of its creation, it will be posted to a SQS Queue called boletos-to-register. This worker is responsible for processing this queue. Here are the steps:

  1. This worker consumer function is triggered when an item is on the queue
  2. Using sqs-quooler we then start to poll items from SQS (sqs.receiveMessage)
  3. Each message received has a boleto ({ id, issuer}) and a message (the raw SQS message from boletos-to-register queue).
  4. We use the boleto id to find the boleto on Database.
  5. We check if the boleto can be registered, i.e. if the status of the boleto is either issued or pending_registration.
  6. If the boleto can be registered, we try to register it within the provider.
  7. If the provider could not process the boleto, we stop executing here. The SQS Message will then go back to boletos-to-register queue and will be later processed.
  8. We update the boleto status with either registered or refused.
  9. IMPORTANT: After the boleto is updated, we notify the boleto owner by sendin an SQS message to the queue the owner specified on the boleto creation (aka: boleto.queue_url). The owner will then handle the processing of these SQS Messages. That's the only way we can notify the boleto owner that a boleto that went to boletos-to-register queue was updated. That's why it's mandatory to pass a queue at the moment of the boleto creation. 1-process-boletos-to-register-queue-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/worker

More Repositories

1

cafe-com-testes

O Café com Testes é uma iniciativa interna da Pagar.me para compartilhar conhecimento sobre testes e boas práticas de desenvolvimento. Essa iniciativa foi inspirada no Testing on the Toilet do Google
479
star
2

pagarme-php

💙 Pagar.me's PHP API
PHP
343
star
3

lambda

🔮 Estudos obscuros de programação funcional
JavaScript
317
star
4

vagas

🤝 Venha fazer parte do nosso time
316
star
5

node-boleto

Boleto generator in Node.js
JavaScript
298
star
6

react-event-components

🛰 A set of React components designed to handle global events (interval, keyboard, touch, mouse, etc)
JavaScript
274
star
7

teleport

🍆 Trigger-based Postgres replicator in Go that works without superuser permissions
Go
233
star
8

react-style-guide

Our React Style Guide
JavaScript
156
star
9

git-style-guide

Git styleguide followed by us here at Pagar.me
136
star
10

tldr

📜 A microservice to store and display sales receipts
JavaScript
133
star
11

react-scripts-former-kit-dashboard

📊 A custom react-scripts for building highly-customizable dashboards using former-kit components
JavaScript
130
star
12

react-payment-card-component

💳 A modern credit card component for React
JavaScript
99
star
13

the-office

Escritório virtual da Pagar.me
Svelte
94
star
14

pagarme-ruby

Pagar.me's Ruby API
Ruby
80
star
15

pagarme-python

🐍 Pagar.me's Python library
Python
76
star
16

former-kit

✈️ Primitive and unstyled React components ready for receiving your own visual identity.
JavaScript
71
star
17

javascript-style-guide

🎨 Javascript styleguide followed by us here at Pagar.me
JavaScript
50
star
18

deployer

📟 A tool for fetching, building, pushing and deploying applications.
Go
47
star
19

pagarme-magento

🛒 Pagar.me's Magento plugin
PHP
46
star
20

pagarme-java

Pagar.me's Java API
Java
44
star
21

pagarme-net

Pagar.me .NET library
C#
41
star
22

artis

💳 Projeto de Checkout desenvolvido em parceria entre MundiPagg e Pagar.me.
JavaScript
40
star
23

escriba

📜 Logging on steroids
JavaScript
38
star
24

talks

🎬 Recursos e material de estudo para criar boas talks
38
star
25

business-calendar

Holiday and financial operation calendar database
CSS
31
star
26

former-kit-skin-pagarme

✈️ A skin for former-kit based on Pagar.me's brand.
CSS
25
star
27

pagarme-core-api-php

PHP
23
star
28

pagarme-opencart

Modulo Pagar.me para OpenCart
PHP
22
star
29

robrowser

🤖 Automated frontend tests in different browser stacks
JavaScript
22
star
30

edipsy

Decent EDI file parsing in Node.js
JavaScript
22
star
31

sqs-quooler

A complete queue consumer for SQS
JavaScript
21
star
32

pagarme-nodejs-sdk

TypeScript
20
star
33

mr-krabs

🦀 💰 A package to clear Fargate cluster tasks https://www.npmjs.com/package/mr-krabs
JavaScript
20
star
34

satan-pm

node cluster process manager, upstart friendly
JavaScript
18
star
35

biblioteca-virtual

Repositório com links para artigos, vídeos, cursos levantados pelos times
18
star
36

caesar-challenge

17
star
37

magento2

Magento2 Module for Pagar.me 2.0
PHP
16
star
38

pagarme-ng-checkout

Angular service to provide checkout functionality to your Angularjs application.
JavaScript
16
star
39

pagarme-php-sdk

PHP
16
star
40

woocommerce

Woocommerce module for Pagar.me
PHP
16
star
41

pagarme-pocs

Um repositório para armazenarmos todas as pocs e exemplos de códigos que fazemos.
JavaScript
15
star
42

opensource

This is a guide for sharing best practices in furtherance of our open source projects
15
star
43

pagarme-ios

Pagar.me's iOS API
Objective-C
15
star
44

cryptokit

Golang crypto wrapper with pluggable providers
Go
15
star
45

node-rsa-keygen

Native RSA keypair generator for Node
C++
14
star
46

emblematic-icons

Pagar.me's iconography
JavaScript
14
star
47

hermes

Angular.js $http wrapper for RESTful applications
JavaScript
14
star
48

bifrost

🌈 Bifrost: Pagarme's bridge between browser and MPOS
C#
13
star
49

business-moment

Helpers for dealing with business days. Uses business-calendar as source.
JavaScript
13
star
50

pagarme-ng-dropdown

Pagar.me directive to provide a simple and quick dropdown from a provided array of options
JavaScript
13
star
51

cards-style-sheet

💳 A sheet of cards in CSS
CSS
13
star
52

p4g4rm3

Validador de senha de nossos serviços! ⛔
JavaScript
13
star
53

mpos-net-sdk

Pagar.me's mPOS SDK
C#
13
star
54

papeis

Os papéis que temos no Pagar.me
11
star
55

pagarme-core-api-nodejs

JavaScript
10
star
56

dojo

Repositório para as práticas de Dojo do time de Tecnologia da Pagar.me
JavaScript
10
star
57

pagarme-ng-range

Pagar.me directive to provide a custom range element
JavaScript
9
star
58

pagarme-express-exemplo

Esse projeto é um guia do fluxo de uso das funções mais utilizadas da API do Pagar.me
JavaScript
9
star
59

pagarme-python-sdk

Python
8
star
60

pagarme-sass-styleguide

The awesome angular.js styleguide that we follow at Pagar.me
8
star
61

warp-pipe

Golang tools to handle postgres logical replication slots
Go
8
star
62

pagarme-core-api-python

Python
8
star
63

dust

⚙️ 🏜️ Grupo de estudos da linguagem Rust 🏜️ ⚙️
Rust
8
star
64

pagarme-core-api-java

Java
8
star
65

pagarme-ng-tooltip

Pagar.me directive to provide simple a tooltip
JavaScript
8
star
66

pagarme-angular-styleguide

The awesome angular.js styleguide that we follow at Pagar.me
8
star
67

deplorator

extreme secure deploy manager
JavaScript
7
star
68

brand

Pagar.me logos in optimized SVG
7
star
69

terraform-ecs-application

ECS + CODEDEPLOY integrated with canary capabilities
HCL
6
star
70

pagarme-core-api-dotnet-framework

C#
6
star
71

pagarme-developers

Pagar.me's Developer Blog
CSS
6
star
72

pinpadRNExample

Example para integração com Pinpad em React Native
JavaScript
6
star
73

livepatch

Patch JSON streams on the fly
JavaScript
6
star
74

css

✨ Estudos sobre toda a magia do CSS
5
star
75

monkeyflash

Awesome library for animation and web page automation
JavaScript
5
star
76

react-material-design-icon-components

React components for all material design icons.
JavaScript
5
star
77

bundler

Node.js private package manager
JavaScript
5
star
78

pagarme-net-standard-sdk

C#
5
star
79

pagarme-core-api-go

Go
5
star
80

pagarme-golang-sdk

Go
4
star
81

ecommerce-module-core

PHP Module Core for our modules
PHP
4
star
82

cluster-requiem

Enhacements for the cluster module in order to handle graceful shutdowns with jobs that aren't associated with a socket.
JavaScript
4
star
83

bluebird-ff

Bluebird functional/flow extensions
JavaScript
4
star
84

scripts-to-rule-them-all

Pagar.me's scripts to rule them all, Docker version
Shell
4
star
85

tabajara-replicator

MySQL to PostgreSQL replicator
Ruby
4
star
86

cadu-js

💚 CADU Javascript API
JavaScript
4
star
87

pagarme-java-sdk

Java
4
star
88

arcaneshield

Python
4
star
89

ecs-task-def-replacements

JavaScript
4
star
90

mpos-android

Exemplo de aplicação do SDK Android MPOS Pagar.me
Java
4
star
91

pagarme-prestashop

Pagar.me - Prestashop Module
Smarty
4
star
92

aws-challenges

Desafios para candidados a vagas do time infraestrutura AWS
4
star
93

barcode-backup

Please, do not use this repository for production it is for reference only! Thank you!
JavaScript
3
star
94

gulp-ngspec

Hard file management for gulp projects
JavaScript
3
star
95

elasticrecord

ElasticSearch trait for ORMs, batteries included.
JavaScript
3
star
96

post-mortem-reports

Outage post mortem reports
3
star
97

lambda-simple-deploy

💿 Package and update your existent AWS Lambda functions
JavaScript
3
star
98

pagarme-core-api-dotnet-standard

C#
3
star
99

moment

Moment proxy usando a TZ de America/Sao_Paulo
JavaScript
3
star
100

mpos-bridge-js

JavaScript
2
star