Evolta (now called Cloudpermit) is a leading service provider for digital building permit process from Finland. We helped them develop a Document Interactive Search. It is a service that allows end users to search and buy documents about buildings. A user can search documents via an interactive map (by typing an address), put them into a cart, and purchase them via a payment gateway or by a prepaid account.
“I started as a product manager for Evolta’s Document Store in January 2019. My first assignment was to lead the development project. Flexiana worked with us to create the first version of the product, so it was natural that we asked them to work with us again.
At the very beginning it became clear that the engineer who was working with the first version wasn’t available to work with us this time. So the big challenge was that neither myself or the engineers in Flexiana knew this product. And in addition, I had no experience whatsoever with leading a development project.”
Paula Vahtola, Product Manager, Evolta Oy
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)
- 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 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 follow 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 a configuration and application architecture.
When we setup 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 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 (https://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 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
- 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 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/clj-commons/secretary)
- Cljs-ajax – a simple AJAX client (https://github.com/JulianBirch/cljs-ajax)
QA
We are keen on quality of code on one side to UX on the other side. We strongly focus on code reviews for these reasons:
- It spreads a knowledge about the application between all programmers in a team
- It helps us to keep the quality of code
- And at the end sometimes we discover an issue before going to staging
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 https://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-elasticbeanstalk)
- 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.
- When a build on the master branch is successful, it’s deployed into the production environment
We basically follow the deployment pipeline on all our projects (of course sometimes with few changes like a production environment on a private cloud etc.).
Cooperation with customer
“Since everybody on the team knew the starting conditions of this project, we communicated all the time very actively. I noticed very soon, that when you have an over all skillful and experienced engineers working in the team, there is no need for specific experience of the product in question. I’m very grateful for Flexiana’s expertise, general insight, patience and understanding. I learned a lot about project leading and development during this project.”
Paula Vahtola, Product Manager, Evolta Oy
From a time perspective we had a fixed deadline and because the main idea was known, and bare features too, we set fixed sprints (a sprint of two weeks). We started with a prototype that allowed us to find documents within the map in the first sprint.
After every sprint we looked back at what we have done (and how) to improve our delivery and quality.
Conclusion
“We started the work in the beginning of March and the new Document Store 2.0 was launched on the 3rd of June 2019. Not only myself but also my colleagues and especially our customers are very happy with the product. Now it’s working as it should’ve worked for all these years. We’re proud to show and sell our Document Store 2.0 to all of Finland.”
Paula Vahtola, Product Manager, Evolta Oy
The project was delivered in time and now is running in a production. Currently we’re discussing new features and improvements.
From a technical perspective we have evaluated chosen technologies as suitable and we would pick them for subsequent projects too.