This is bite 2 of the 3-bite Story of Meewee. Read Story of Meewee Bite 1 here.
Meewee evolved at an insane pace the first 1-2 years. But then things slowed down. We had a stable product, and we had fine growth in terms of number of users and organizations signing up.
Problem was, we were soon out of money, and had to focus our time on something that could give us butter on our bread quickly.
This also meant, that Meewee became a one-man project. And this one-man became increasingly busy with the butter-giving activities.
It’s a good thing, that Meewee is super stable, and only requires minimal maintenance, while steadily becoming adopted by more.
Our first paying customer signed up in March 2013. Others followed soon after, including our first international customers from The Netherlands and Belgium. MeeWee had broad international appeal.
In the beginning of 2013, our focus was on small to medium sized companies, which in Denmark means 50 to 100s of employees.
Many companies we presented MeeWee to really liked it. Their payroll department would save a lot of money not needing to calculate every employee’s accounts for paid and unpaid leave. They could also save time when doing mandatory statistical registrations of employee sickness and vacation. Or if the organization was entitled to government refund during parental leave, sickness and more.
Hello Time Registration
Some of our customers told us, that these full time employees was only part of their workforce, and lots of other employees was either only paid by the hour, or otherwise contractually obligated to perform time registration on the projects they worked on. These projects could be internal or external. And often the external projects was invoiced to a paying customer. A nice Time Registration system would be a huge benefit for their finance deparment.
Extend by Flexibility
But MeeWee 1.0 didn’t have time management or time registration. What we had was a truly flexible rule engine. So we could fairly easily add another root registration type, next to the existing ones; Leave and Sickness.
When building a standard product, and presented with ideas and requirements from customers, you really need to think carefully about the following:
- Is it a feature that many customers want?
- Do these potential customers want to pay enough to mandate the build cost?
- Can you ask the initial customer to pay for the feature (fully or partially)?
We had used our own time registration system, ServerTalk, from the day we started our company. And of course it’ll make sense for us to use MeeWee for this instead. So at least we’d have two customers.
When thinking about it, Leave and Sickness is non-Project Time. So if we implemented Time Registration in MeeWee, we’d have both Time and non-Time. One the opposite of the other. Existence of one thus implicitly implies the non-existence of the other. This can be used for several nifty functionality, in example: Don’t remind employees to register their time, if they’re on leave.
It seems that two explicit features adds up to even more implicit features. 1+1>2!
We spoke with other customers, and to them it also made a lot of sense to have Time Registration as an integral function of MeeWee.
We decided to implement it. The 19th of April 2013, we had the first Time Registration in the MeeWee database.
Time Registration took our MeeWee Rule Engine to the next level. The 1st of May 2013 we enabled our users to add maximum hours for a project per Employee, per Team or for the whole Organization. This could be calculated per day, for a period or “forever”. Similarly we added minimum hours, which shows up as an informational notice, when users have registered less than required per day, week, month etc.
The Time Registration module became publicly available in October 2013.
To boost sales, we hired Orlando Brandi. His task was to take care of social media and telemarketing.
One of his creations was this promotional video, which he also did the voice-over for.
We went out of money, and had to start focusing on getting other sources of revenue. As a side project we did consulting (mostly me).
We now funded MeeWee via personal loans.
2013 was our most productive year so far, going from
1360 git commits in 2012 to
2819 new commit in 2013!
Being a small company of 2 developers and a 1 sales person, plus offices and hosting, requires a bit of money. So in 2014 we kept funding MeeWee with personal loans.
We also kept producing lots of new enhancements and features, to make the usability even better, fix bugs and inconveniences, meet customer demands and more.
Partnerships via Integration
In 2014 we spent a lot of time integrating MeeWee with other systems such as:
- payroll providers
- book keeping / financial systems
- EIS/ERP systems
We made an informal agreement with one of Scandinavias biggest providers of payroll, namely Bluegarden. To let us focus on making a stable integration framework, and work on an efficient add-on component for Bluegarden, we hired a third developer; Kevin Jørgensen.
I met Kevin at the Copenhagen Clojure Google Group (this was before we started using Meetup.com). In one of those meetups, I presented our work on MeeWee, explained the architecture, how we use Datomic and more.
Kevin started working with us the 1st of February 2014.
The integration project was a huge task, and required a lot of time and finances from us. Especially since the API of Bluegarden was developed by a single consultant working for them, and it was less than unstable, hard to debug, and changed every now and then, effectively setting us back every time. We gave them lots of qualified feedback, and hoped our time spent was what we had to pay for the official future partnership with them.
The partnership via integration was our primary effort for future revenue. At least 50% of our time in 2014 was spent working on it. It was a go/no-go situation – either we succeeded with the Bluegarden and possibly other partnerships, and started earning significant revenue through that channel, or we ran out of money.
To focus everything on this partnership, we had to let Orlando go in May 2014.
To further focus our time, we started a very effective quarterly ritual coined the MeeWee CodeCamp. As the name suggests, the idea is to go somewhere for a few days, and just code. Make food together, eat, code, drink a few beers, code more, sleep a bit and repeat.
One of our investors owns a small cabin a bit away from Copenhagen, and he allowed us to use it. We spent 3-4 days in each CodeCamp, and the idea was to work on, and finish, a new feature during the camp.
The first CodeCamp was in November 2013. But most of them was in 2014.
The least effective of them was the one we held in December 2014 in our own office. The takeaway is – get away!
CodeCamps is a concept I’d really like to revive sooner than later.
Søren wanted to leave. He wanted to move with his family, to allow them to get back to their roots. Søren used to be an elite athlete, as part of the team that won one of the Olympic medals for Denmark in 2000. And he wanted to spend time in that world again, this time as a trainer.
With Søren off our team, we really missed a developer for the webapp. He did an amazing job with the MeeWee webapp. Looking back it’s difficult to see who else would’ve had the skills and patience to build something that complex, on a very new technology, while also learning a new programming language. The result was really good – how many webapps still work great in production nearly untouched after 10 years?
But Kevin and I couldn’t maintain the webapp, while also working on the backend and integration. So we had to find another way.
Since we started MeeWee a lot of new projects and libraries was built using Clojure and ClojureScript. And Clojure One (on which the MeeWee webapp was based) wasn’t maintained anymore. ReactJS was what everyone was talking about. And for ClojureScript Reagent was built. A highly intuitive library for building React.js webapps with ClojureScript.
Kevin and I decided to build all new frontend features with Reagent, and over the coming years slowly replace parts of the webapp with Reagent, plus communicating between our apps and the server using Websockets.
This was Project Frank.
Two-factor authentication and Websockets
We wanted to increase the security of MeeWee, with a new setting in the user profile, offering Two-factor authentication to anyone.
This new functionality was based on Project Frank – the combination of Reagent and Websockets.
It worked out pretty good, and we had a framework to build our user interface with going forward.
Clock-in/out & Time Accounts
One of our customer had a lot of employees working in shifts. They basically had these different shift types:
- Day shift
- Evening shift
- Night shift
- Special shifts for weekends/holidays
Each employee was put in a specific shift for a specific number of weeks. The shifts had flex, fix and overtime – which we decided to call Time Accounts.
The customer asked if we could build a feature, that allowed their employees to clock-in when they met, clock-out for lunch and other breaks, clock-in again after breaks, and then automatically add or subtract minutes to the different Time Accounts based on the clock-in/out events and current shift type.
Remember we said that
1+1>2? This is another good example hereof, since time accrued on the Overtime Account can later be used as Paid Leave.
We developed a working prototype for this. Again using our new Project Frank.
It’s still available in MeeWee, and is a highly undersold feature.
- We added Time Registration Reminders
- We enhanced security in several ways, including implementing CORS
- We added Intercom as our primary support channel
2014 was almost as productive as 2013, with 2430 git commits.
Kevin ended 2014 by resigning. I couldn’t really match his salary expectations anymore. He found a job that paid him almost twice as what I could offer. 31st of January 2015 was his last day at the MeeWee office.
Now I was alone, a team of 1, taking care of backend, frontend, database, infrastructure and devops, integration, sales and support.
I terminated the rental of our office space.
From now on, MeeWee was a thing I did at home or in a coffee shop, when I wasn’t doing consulting for a(nother) customer.
New SmartPhone App
In the beginning I felt fine. I felt super productive, since I didn’t have to coordinate with anyone. I wrote down code, as the ideas arrived.
This lead to a new SmartPhone App. In 2015 Windows Phone seemed to becoming increasingly popular, partly due to it’s innovative UI consisting mostly of squares with texts. I liked the simplicity of it, and decided to develop a new app, using ClojureScript with Reagent and websockets – based on my experience from Project Frank. This I’d wrap with Cordova to make building and deploying easy for both Android and iOS.
I built and open sourced the basic starting point of the mobile app, and called it CorDeviCLJS (for CORdova, DEVice for native device functionality, and CLJS for ClojureScript).
The app still works pretty good, and has been available ever since without any major changes.
After not really collaborating with us for some time, Bluegarden suddenly launched an app, which could do some of what we wanted to do with them. This had to mean there was an API ready. I contacted them, and they confirmed, but the API only contained enough to get their own app running. I was super disappointed.
The year after I was contacted by a new guy responsible for partnerships, but it never really lifted off by then.
- Flexible rule engine got even more rules built-in
- The logo was revamped into the rounded white logo on either black or red
- Clock-in/out got it’s first major update with a new shift editor
344 commits during 2015.
In 2016 I spent most of my time on a project I started working on during 2015.
Technically it was great fun. I’m an Electronics Engineer, and my task was to create a prototype for a system consisting of:
- development and design of an IoT device
- firmware for the electronics
- a smartphone app enabling communication with other people and the device
- the backend/service
- admin dashboard, and
- the database/infrastructure
I was a single man army, with the task of creating a MVP. In the first half of 2016 it was working.
Unfortunately the person responsible for the finances, didn’t find enough money for us to get a monthly salary. During 2016 and 2017 I ended up spending all my savings, while working way too many hours every week, adding new features and enhancing the solution.
We didn’t agree on how things should be run, so I quit the project before the end of 2017.
I still found little time to support MeeWee customers. To make this simpler, I enhanced the onboarding templates for new customers. This made it much easier for new customers to add their Employees, Teams and Employee Groups, and my life as an onboarding supporter was also simplified.
I also got lots of translations made for MeeWee. I found a cheap translation service online, and found a way to convert the text resources from MeeWee into a standard used by online translation services. I uploaded them, and got translations for around 10 extra languages.
Unfortunately I didn’t get time, or money, to have the translations verified. So they were never introduced in production.
This may be a thing to do later though!
2016 got 157 commits.
2017 was a very inactive year for MeeWee. Apart from a tiny bit of support, only minor changes to make onboarding and customer support easier was made, alongside necessary maintenance and security upgrades.
2017 only saw 37 commits.
In 2018 I started working with Dewise – Marilag and Erik. Good company, and nice to actually get good money for good work again! I quickly became partner and co-owner.
This also meant a lot of new projects, new people to get to know. And not really much more time to work on MeeWee.
In the beginning we were just 9 people in Dewise. 3 in Denmark, and 6 in Manila. But Dewise grew steadily, and the need for stricter Time and Leave Management was evident.
So I introduced MeeWee to Dewise, and we started using it for both Time and Leave.
Since Clojure is (primarily) a JVM language, and native applications start much faster than Java applications while using less resources, I experimented with this for the MeeWee backend.
Initial results showed almost immediate startup using just a few megabytes of memory, which was quite promising!
My end goal of the experiments, was to use a GraalVM build for the Docker image of the backend, to enable much faster automatic scaling in production, while using less resources. At the time there was still code that used Java Reflection, to allow for on-demand build of dynamic Employment Functions and Filters used by the MeeWee Rule Engine. And a GraalVM build doesn’t allow the use of Reflection. So the project was put on hold.
In May 2018 the GDPR legislation took effect in the European Union, and MeeWee was modified to explicitly adhere to it.
Since all support and infrastructure cost was personally financed by myself at this time, I disabled the use of Intercom. The monthly bill from them was almost half of the monthly total cost of running MeeWee (yes, MeeWee is very lean!).
Better database migrations
The upgrading of the database schema was enhanced, so it was done automatically when the updated service starts up, instead of me having to trigger it manually before upgrading.
Adding a new integration
2018 also saw the integration for another payroll system.
126 commits was needed in 2018.
I was still very busy working with Dewise projects. And in 2019 I was working full time at a big project for the Danish tax agency (SKAT).
In Denmark we got new legislation for paid vacation in 2019. Because of that, I had to update the logic of the functions calculating the accrual and spending of paid vacation accordingly.
This was a bit complex, and took a while during evenings and weekends. The update was deployed to production just in time.
Aside from the implementation of the “Ny Ferielov”, the changes to MeeWee was few in 2019:
- Added a flag in the Organization profile, to hide personal details in notifications
- Added Zambia and Zimbabwe to the list of supported countries, because we got our first signup from there!
72 new commits found their way to our git repository in 2019.
This was the most inactive year of MeeWee, perhaps ever!
Of course it’s important to remember, that MeeWee is a super stable product, that “just works” 😉 Therefore only security fixes are necessary.
There was only tweaks and minor changes to the implementation of the new Danish legislation for paid vacation.
Just 32 commits!
From January to October 2021, the most inactive months in the life of MeeWee took place. Only 4 commits were made in these 10 months!
It’s worth noting, that since MeeWee was born until Q4 2021, Users and Organizations from 74 countries around the world, had found and signed up with MeeWee.
Most of those without any specific sales or SEO effort from our side.
Dawn of an Agreement
After the summer break, I approached my partners in Dewise – Marilag and Erik – with a proposal: I offered all my stakes in MeeWee to Dewise, if Dewise would finance a team to make a 10 year anniversary revamp.
The focus of the revamp should be:
- Renewed focus on making life easier for Consultants/Freelancers, and the companies hiring them
- Making it easier to integrate with MeeWee
- More user friendly Time Registration
We agreed on the general terms, and presented our shared idea to the other stakeholders: Allan, Diego and Marianne.
The agreement was finalized, and my stakes was sold to Dewise the 15th. MeeWee development was now waking up from hibernation.
It was agreed that the new team should start the 1st of January 2022. But before that, a lot of preparation had to be done.
Preparing for the next Meewee
First of all, everything had to be upgraded.
- Backend libraries and components
- Frontend (ClojureScript) libraries
- Upgrade infrastructure for added resiliance and scalability
In general the upgrade was super easy. Clojure and ClojureScript is a super stable language, and most libraries tend to adopt this stability. So in most cases the upgrade was a bliss.
ClojureScript was what took the most time. Because of our legacy, our webapp used a few old libraries, that hadn’t been maintained for many years. Some of them wasn’t even supported by the newest ClojureScript compiler. The most prominent example of this is Domina, which I chose to fork and update, to make it compatible with the newest ClojureScript.
I prioritized this since we needed to onboard a new Clojure developer from January 2022. I wanted the current code base to be as good an example as possible, while also enhancing readability.
New Public API
MeeWee never really had a public API. We wanted this in the next version of MeeWee, because it should be easy to integrate with, and build solutions on top of, MeeWee. One of our goals with the 10 year anniversary version of MeeWee, is to integrate it with other products we’re working on.
The technologies and languages used in these other products are different from MeeWee. So a standardized, documented and Open, Public API is a main new feature to be developed.
From November until the end of 2021, I focused my time on finalizing the foundations of this new, self documenting, data driven, public Open API, with a custom developed and domain aware web based test client.
Ready for the Next!
81 commits was made during the hectic months leading up to 2022.
The refactored MeeWee backend, with a new Public
/login API endpoint, testable from the test client, was deployed the 29th of December.
This meant we were ready for new adventures with a brand new team in 2022!
This concludes Bite 2. In Bite 3 I’ll tell you what happened from the 1st of January 2022, until our 10 year anniversary launch of Meewee Nxt in October 2022!