Johannes Puirava is one of the managers of the family-run Finnish health education business ProEdu. They provide training, mostly online, for healthcare practitioners, e.g. nurses. For a nurse to be able to inject a patient with certain medicines, they need to be accredited, which often involves them completing one of the courses offered by ProEdu, as well as on-the-job performances under supervision. Once a nurse has passed all the requirements, everything needs to be signed by a doctor, after which the nurse is legally allowed to perform the said procedure for a certain amount of years (usually 1-3).
ProEdu noticed that many of their customer organizations didn’t have good oversight of who had specific credentials and for how long they were valid, as the organizations kept contacting them asking when and if a particular employee of theirs had passed some course. Closer inspection revealed that many just kept the documents on paper, in folders in someone’s office. There was an obvious problem to solve here, one that their customers would be willing to pay for.
COO ProEdu Oy
“Makers' Den created our web application to digitize the process of license management in the health sector. They delivered UX/design and development and are still maintaining it after launch. They've been with us throughout the whole process and are still improving it as we sign new customers and receive more feedback”
The Technical setup
To facilitate fast delivery, we opted to use,
ReactJS. We’re a ReactJS shop, and all our projects are built on top of it.
Typescript - Many of us are a decade into using it, and there’s no looking back. All out frontends and backends are always done in strictly typed Typescript.
BlitzJS, which is a framework that extends upon NextJS. You can think of it as a “Ruby-on-Rails” for Typescript/React/NodeJS. It features:
Zero-API layer. For even faster turn-a-round times, BlitzJS allows us to share code between the backend and frontend and do API calls by calling "mutations" and “query” functions from the frontend code without any boiler-plate, facilitated by a code generation step in the build. It’s just like using React-query (Tanstack query) but without having to code unnecessary Rest APIs (or GraphQL resolvers).
Solid authentication and authorization setups that have been well tested
Initial scaffolds include basic user models, sign-up, registration, and forgot password functionalities.
A vibrant community, solid documentation, and a plugin ecosystem to quickly add cross-cutting features in minimal amounts of time.
Prisma, which is the best Database/ORM layer for NodeJS. It generates Typescript types for your database schema, strictly typed database queries, and production-ready database migrations. A tremendous boost for producing end-to-end functionality fast.
PostgreSQL - our relation DB of choice when it's a fit, and it’s almost always a fit.
ChakraUI - we used this very configurable, complete, and easily themeable component library as the basis for the design system to speed things up.
Render.com - a Heroku-like platform with much more lenient pricing and a much faster pace of development**.** With this, we can achieve production quality deployment setups with fully automated Continuous Deployment and fully Git-managed Infrastructure-as-code style setup in less than half a day.
We like to leverage tools that take us to production fast because time spent on re-inventing the wheel does not produce business value, for example, building custom CI/CD pipelines, deployment environments, custom component libraries, and figuring out immature tools and libraries.
How we worked together
In cases where we’re independently delivering without integrating into the client’s team, we usually set up a weekly meeting and a shared Slack channel for ad-hoc questions - as we did in this case.
For the start of the project, we first had a 2.5-hour remote kickoff over Google meets, where the team and all stakeholders were present. In the meeting, the client presented the initial wireframes with user flows from beginning to end, and we asked plenty of questions concerning unclear portions. Some of which would have to be cleared up later.
During the kickoff, we set up the weekly meeting schedule, and after the meeting, we broke up the requirements into “stories” and tasks we put into an Asana board, which was the project management tool in use.
After this initial phase, we met weekly on Mondays, where we demonstrated our progress. The progress could also be reviewed by looking at the Asana board and an always-deployed staging version of the application at any time. After the weekly demo, we prioritized and specified the tasks for the next iteration.
This project didn’t have a rigorous specification from the get-go, so there was a lot of daily back-and-forth communication on our common Slack channel and many ad-hoc meetings. The weekly meetings often evolved into future feature discussions for which we scheduled separate design sessions. During these sessions, we heavily leveraged Figma to communicate how new business requirements may be solved.
Internally, our team meets every morning to discuss what was done the previous day and what each team member sets out to achieve on the current day, as well as raise any issues.
We can do without separate designers if a project is for an internal tool or a b2b app where they’re also solving a problem for themselves. High-fidelity designs and the involvement of designers usually have poor ROI in such cases. We can prototype their ideas into reality with fast feedback loops. Using pre-defined design systems like ChakraUI, which we theme to the client’s colors, and doing simple wireframes for initial views with Figma is usually all that’s needed. UX is still important, but we pride ourselves on being product-oriented developers with empathy for the users. It’s the outcome of having developed dozens of frontends.
In January 2023, they have close to 80 client organizations using their platform to manage licenses. It has been a successful new business in parallel with their education business, one that might eclipse it in the future.