Cloudpermit - Flexiana
Home / Projects / Cloudpermit
Software development

Document Interactive Search

Services we provided:

Back-end Development

Technologies used:

Clojure

About Cloudpermit
Cloudpermit is a Software-as-a-Service (SaaS) company. They provide cloud-based software solutions for local governments, focusing on community development processes such as building permitting, business licensing, planning and zoning, code enforcement, and inspections. Their platform enables agencies to manage these functions online, streamlining operations and enhancing efficiency.

>  Go to website

Application architecture

Our goal was to create a web-based application with an interactive search map that integrates with other web services. The challenge was to create an application that integrates with many mature services with ease of deployment.

The application needed to be integrated with the following services:

Document Search Engine that allows to search documents by an address
Document Storage Service to get documents (as PDF or images) 3. Authorization Service to
allow to use prepaid accounts

Payment Gateway to allow paying for documents by a payment card

A database was used to store user’s transactions and some additional data. We picked PostgreSQL for it because of its maturity and advanced data types.

User Interface is one of the most important parts of an application. The application could be super fast, scalable and easy to deploy, but everything would be useless if no one were ever to use it. Allowing a user to search building documents by an interactive map is not an easy task. There is a lot of communication with APIs, the map has to be rerendered when the user moves the map (the map needs to get documents for new viewport).

Because of these interactions within the map we decided to use a Single Page Application for the best user experience. A communication between Single Page Application and API was done via REST, because it’s well known and simple.

Environments

Every application has to deal with many environments, e.g.:

Localhost – programmer’s environment
Staging – QA and acceptance environment
Production

The best practice is to have the same environment configurations if possible. Unfortunately we had to deploy the production version into a private cloud (for legal reasons). Thus we had to design the application with ease of deployment and configuration.

One of the customer’s technical requirements was to use a JVM-based language. Thus we picked Clojure, because of our experiences. Leiningen (Clojure package manager and build tool) generates a JAR file which has a well known and standardized deployment process.

The Next issue was how to configure the application across environments. In the building process we followed the Twelve Factor recommendations (https://12factor.net/config) thus we configured the application by environment variables that allowed us to configure the application by well known and mature environment variables. For Clojure there is a library, Duct,
(https://github.com/duct-framework/duct) that helps with configuration and application architecture.

When we set up the configuration by Duct it was easy for us to deploy the application into AWS Beanstalk and into the production environment.

Technologies

As it was pointed out in the previous section we picked Clojure as the main programming language. This wasn’t our first project in Clojure, thus it wasn’t a problem for us.

And of course we used many Clojure libraries, e.g.:

Duct – an application architecture, dependency injection  (https://github.com/duct-framework/duct)
HugSQL – SQL layer (https://www.hugsql.org/)
Postal – a simple email sender (https://github.com/drewr/postal)
Ring – for processing HTTP requests (https://github.com/ring-clojure/ring)
Compojure – a routing library (https://github.com/weavejester/compojure)
Clj-http – for calling REST services (https://github.com/dakrone/clj-http)
Clj-http-fake – for mocking HTTP requests in tests (https://github.com/myfreeweb/clj-http-fake)
ROP – a library for railway oriented programming approach (https://github.com/druids/rop)
Bouncer – for request data validation (https://github.com/leonardoborges/bouncer)
Cloverage – a code coverage tool (https://github.com/cloverage/cloverage)
Kibit – a code linter (https://github.com/jonase/kibit)
Eastwood – a code linter (https://github.com/jonase/eastwood)

Just for QA there was another dependency, Python. We used Robot framework for end-to-end testing (http://robotframework.org/). It runs a browser in the background and calls test scenarios in the same way as a user uses the application

ReactJS is a great library for coding Single Page Applications, but it’s primarily used from JavaScript. Because we’re experienced Clojure programmers, using ClojureScript for the UI part was an obvious choice.

This decision allowed us to:

Reuse business logic between frontend and backend
Not switching between two languages with different paradigmas 3. Coding the UI in a functional
way (this is the best way to program a UI nowadays)

Writing a Single Page Application from scratch is a waste of time and is creating code that someone else has already written . In the ClojureScript world there are libraries that make creating a Single Page Application easier than in JavaScript.

Main libraries that we used:

Reagent – a simple ReactJS wrapper that allows us to define UI components in Clojure native way (https://reagent-project.github.io/)
Re-frame – a framework for writing SPA (https://github.com/Day8/re-frame) 
Secretary – a routing library (https://github.com/gf3/secretary) 
Cljs-ajax – a simple AJAX client (https://github.com/JulianBirch/cljs-ajax)

QA

We are keen on the quality of code on one side to UX on the other side. We strongly focus on code reviews for these reasons:

A delivery pipeline was set like this:

When a programmer creates a pull request the build server (in our case CircleCI) is triggered.
CircleCI: 

  • Builds a JAR
  • Runs tests and code linters
  • Builds and minifies final JavaScript
  • Runs end-to-end tests against fixture data


We don’t merge the pull request until there are two approvals.
When a pull request is approved it’s merged into the develop branch (we follow Git flow   http://nvie.com/posts/a-successful-git-branching-model/)
When a build on develop is successful the code is deployed on staging environment (AWS Beanstalk) via CircleCI by using aws-java-sdkelasticbeanstalk  library  (https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-elastic beanstalk)
When a tester and a product manager approve the release, we create a release branch (new Git tag) and merge it into the master branch. (https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-elastic beanstalk)
When a build on the master branch is successful, it’s deployed into the production environment 

We basically follow this deployment pipeline on all our projects (of course sometimes with few changes like a production environment on a private cloud etc.).

Let’s grab a remote coffee and discuss your ideas