Engineering at Otovo 🏗

Why we ditched our BFF and went for Next.js

At Otovo, we’ve been using the last couple of home office months to do some technical improvements: Tailwind, Django 3.0, Vercel, and Next has been on our radar for a while. In this article, I’ll let you know why the latter made us ditch our BFF.

Best friend you say? If you, like me, grew up in the 90s, the term BFF has probably only one meaning in your head: Best Friends Forever. In the last couple of years however, the microservice community has put an effort into claiming and rebranding this term as Backend For Frontend.


Using PostgreSQL 10 with PostGIS on Travis CI

Today I needed to fix our Travis CI setup to use PostgreSQL to ensure we run the same version of PostgreSQL in production as well as in our test suite.

Travis provides all PostgreSQL versions that are available in the PostgreSQL official APT repository, so we had the packages we needed.

But, the documentation is a bit lacking, as the packages and setup differs slightly from the default 9.6 database Travis CI provides you with.

So here is the step-by-step guide to running PostgreSQL 10 with PostGIS 2.4 on Travis.


Migrating connected Django models to a different type of primary key

Sometimes, old design decisions comes back to bite you. This is one of those tales.

A project I’m working on had a Django model similar to this:

class Municipality(models.Model):
    code = models.CharField(max_length=2, primary_key=True)
    name = models.CharField(max_length=100)

and it was used by other models such as:

class ZipCode(models.Model):
    code = models.CharField(max_length=4, primary_key=True)
    municipality = models.ForeignKey(Municipality)

And all was good, until we needed to expand the municipality model to support different countries, and thus a single unique field with only the code - which may collide across countries, was not enough.

For all the modern parts of the code base we use UUIDs as the primary key, so we wanted to migrate the primary key of Municipality to a UUID, while retaining all the relations.

As of September 2017, Django does not support migrating primary keys in any nice manner, so we’re on our own here.

We tried a lot of magic solutions, but we always got stuck with the migrations system not being able to detect and handle the changes nicely.

After some research and quite a bit of trial and error, we settled on the following approach. It has some drawbacks I’ll get back to, but works reasonable well.