How I built APPoint as the single dev

Cosmin Stefaniga find me on twitter at @CosminStefaniga 2020-10-24 21:11:27 UTC

This is an overview of how the project was put together and what technologies it uses

In early 2020, me and my-cofounder, Alex, launched our bootstrapped project, APPoint, after about 14 months of development during nights and weekends mostly. A lot of nights and weekends. The pandemic and the lockdowns were an unpleasant surprise, to say the least. We used these months to find more professionals to test and we ironed out a few more bugs and did some more polishing. We’re looking now at getting more professionals signed up on the platform.

I was the single dev and while I built it, I learned a few things, so I’m sharing here those things and how we put the project together.

But first, what is APPoint?

APPoint is a web and mobile app for professionals to manage their customers and appointments, that also provides insights into the business via a series of reports and views. It also sends out SMS reminders to customers to boost shows and revenues. The mobile app is available on iOS and Android.

The stack is all javascript, from the feathersjs API to the emberjs front-end to the React Native mobile apps, though we started with only a Ruby on Rails app and the emberjs front-end. We had no plans for a mobile app at first. Mostly because the app was intended to be used by receptionists and they were using laptops and desktops. Neither of us had any experience with mobile development, nor did we have any money to pay for a dev. Since our app could be used on a mobile browse if someone wished it so, it was good enough to launch something.

After I had an MVP with enough functionality, that was fully responsive, we ran a test on a series of mobile phones and I was very pleased with how it performed. So we decided that using an app with a web view might not be a bad idea. Hardware is now much better and so are the webviews.

This also opened up the market since we could now target individual professionals like hairdressers, make-up artists and other solo-professionals that only have a mobile phone and that are still doing business with pen and paper, some with the built-in calendar.

The API

I knew I wanted to move fast and iterate quickly. I also wanted to use what I already know and not spend time learning a new programming language. I work as an emberjs/ruby on rails dev, so that’s what I chose.

I started with Ruby on Rails for the API and was moving quite fast, but I found myself writing the same boilerplate over and over again. I wanted something that already allows me to do selects, filtering, sorting, crud operations without having to write the same controllers over and over. I was looking at graphql, but had no time to learn how to use it.

That is when I came across featherjs, a javascript framework that does exactly what I wanted. It exposes services that can handle my needs, already built-in. I was hooked. It also provides these interfaces on the client via several transport layers. I spent a lot of time considering if I should switch to it and break the rule above. After a couple of weeks I decided to switch and I don’t regret it.

Feathersjs allowed me to move very fastt. If you are wondering how fast, I can give you an example. My co-founder called to discuss the screen with the customers list. He was about to go on a drive for 1.5h. By the time he got out of the car we had a screen with customers, pagination, search, CRUD, recent clients already styled and usable. It is ridiculously productive.

The web app

The web is an emberjs application, that is also packaged as a mobile app.

The central part is the calendar, so this is where we spent a lot of nights brainstorming and prototyping. I wrote a separate blog post about it.

I want to mention a few projects for which I’m very grateful. So a big thank you to their authors and contributors. It would have taken me at least twice as much without them.

ember-bootstrap simple-auth power-calender power-select ember-file-upload ember-concurrency

The mobile app

For the mobile app I was conflicted. Do it in React Native and have better UX, but slower development time as I would have to basically redo the web interface all over. I was also going to move a fair bit slower as I started learning React Native fairly recently. I decided to combine the two technologies. I would reuse the emberjs app, that is responsive and package it in a React Nstive app. I would use the APIs from React Native to get access to the phone camera, file system, contacts and push notifications.

This proved a very sane solution. Nobody actually could tell they were using a web app, except for one person that noticed the transitions are different. And these were technical people. The professionals using the app didn’t care at all. They were happy they had a good tool in their hand.

I initially used Expo in managed mode and really liked the process and ease of use and deploying with a single command. I had to eject because we decided to implement subscriptions.

Deploying the app with Expo is extremely easy, just a single command:

expo publish

That is it. It will ask for a password and it will take care of everything. You will have to login, add the app information, screenshots.

I would recommend not to eject, unless you have to. The process of manually setting up the deployment to the store is something that I really hate. I spent weeks until I found out everything I needed to do and until everything was set up.

The deployment process is now handled by fastlane, which is an awesome project. Setting up fastlane requires a separate article.

What I like about fastlane is that you can also upload texts and screenshots along with the build.

The infrastructure

For most of the development and testing phase I used Dokku. I LOVE this project. Having a project running is as simple as git push.

Dokku allows you to run apps in containers the same as Heroku. Plugins are available for Rails, nodejs, PHP, MySQL, Postgres, Redis, Letsencrypt, storage.

dokku apps:create appname dokku postgres:create appdb dokku postgres:link appdb appname

This will create a DATABASE_URL environment variable on the app container and you can now deploy with git push dokku master.

You can easily launch with Dokku as I’m running production projects with it and I had no problems. You can scale later.

Since the day job for Alex is doing server work of all kinds, he decided to create a setup for launch using Terraform in the Hetzner cloud, since they are so cheap and they have wonderful docs, APIs and service. Hetzner is highly recommended.

We run 3 app instances with a Redis instance for the queue and a MySQL database with 2 slave nodes. The whole server setup is done with Terraform like I mentioned above and it allows us to easily scale this in the future. We’re considering switching to containers in the future, but at the moment there is no need.

Deployment happens via Gitlab workers. When we merge into master the deployment pipeline is started and it takes around 5 minutes to have everything updated. During the deployment process migrations are also run if any are pending (with sequelize).