How does my app work with my Business - woman presents an app to a man - image by undraw.co

How does my new app work with my business? Its something you need to know as a new app owner. Image credit: undraw.co

How does my App Work with my Business?

How do I know what I’m getting when I build an app? What are all the parts that I need to make sure it works and keeps working for my customers?  How can I be sure my app is an asset for my business?

If you’re asking these questions then you are in the right place. These are exactly the sort of questions that a product owner, app entrepreneur or business owner ought to be asking when they want to be sure the app they are planning will work effectively.

This is the fifth post in my series how to build an app. In this one I’ll be looking at more advanced material then in the previous four articles; which cover how apps work, what kind of apps there are, how apps get built and how you make money from apps. If you haven’t seen those, you should go back and read them unless you’re already an accomplished app builder.

Getting up in Your Business

In this post I’ll be covering how the backend of apps communicates with your business to provide value for your customers and for you. We will be looking at what happens behind that glossy user experience, to automate business processes.

We’ll be digging in to discover what it is that you get your hands on when you’re an app owner, who has an app delivered to them.

Teams change and developers leave. What access would you need to continue on? Image credit: undraw.co

What should you expect to be handed to you by your app development team? If your entire app development team disappeared tomorrow, what would you need to carry on and keep building your app with a new team?

And thirdly and finally in this post we’re going to be looking at how you can treat your app as an asset to your business. Something that when your business is valued, that like goodwill and a client list, your app functions as an important part of your businesses balance sheet.

Let’s jump right in.

Tasks are your Business Now

In the first article “How do Mobile Apps Work” we discussed how developers built features in response to user experience designs. In the fourth on “Can I make Money with my App” we discussed how task based designs are used to ensure that your customers can achieve end-to-end value chain transactions inside of your app. 

User experience can model many business flows. Sometimes you need backend architecture designs in greater detail. Image credit: undraw.co

This idea of using experience design to model tasks done by your customers is critical to getting your app to perform effectively. We will return to this through this article.

Term Time: Customers and Business

In this series of articles, I use the term business to refer to what ever it is that you’re trying to achieve, and customers to refer to the folks you want to engage to help you get there. This is true even if you’re a not-for-profit, or in some other way are making an app that doesn’t quite fit the mould implied by “customer” and “business”.

I just don’t like the term “user” when discussing the people who will be engaging with your app. Its inescapable, especially because we have “user experience” in the mix and UX being essential. But I try to use customer in preference whenever I can. In the same way, I hammer business because we want to be business-like when we are working with tech, to make sure its effective, and provides value.

Managing App Effort

So we’re building the app to allow our customers to execute tasks and we have our team writing the code to make this happen.

The code that implements all of this behaviour has to go somewhere. It has to be stored somewhere, as it rolls off the production line from our coding team.

That somewhere is a store in the cloud that we call a repo. A repo is like a large directory or folder, in which developers place all of the code that they write for your app.

That cloud directory has special access protections so that only the developers, and you as the owner of the app can access it.

When developers write their code, as I mentioned in earlier posts they work to create an app package which can be installed on the device – the iPhone or android phone. That package can also be uploaded to the App Store or Google play store.

Code Repo: Core to Automation

In reality the process is a little bit different from that. Yes, developers can write code locally, and then push it straight to the stores.

For a release however, usually the cloud store where the code is placed – that’s our repo – is configured to automatically generate the package. It can be even configured to automatically push the package into the App Store and Google Play store.

Scripts function like bots that test and build your app. Together with the repo they form a continuous integration system. Image credit: undraw.co

Actually its more accurate to say its a special cloud-based app, called a Continuous Integration system (CI system) that automatically tests the code, then generates the app from the repo. But it is the repo typically that holds all the code for the build, contains the versioning details, and nowadays even holds the scripts for the CI system.

So to keep it simple think of your repo as not just a store for you apps code, but also the core of your app building process cycle.

Like a Version?

What’s even more interesting about the repo is that it’s not just a collection of all of the code that your developers have written for you. The repo is versioned. I alluded to this already in the previous section. Its these new version numbers that play a critical role in making frequent app releases.

What this versioning means is that if something breaks in your app the repo can be cranked back to a previous version. One that we know worked okay. 

Repository Data lives in the Cloud

So there’s a lot of cloud stuff going on here. I’ll just go over these two again.

First we have the code that’s been written by the developers stored in the cloud, in the repo. If you hear names like “GitHub” and “BitBucket”, that is your repo they’re talking about. You want to make sure you have the passwords or keys to access it & administer it.

Second we have the App Store & Google play store where packages are pushed to. And that’s in the cloud too. You need passwords to access those too.

Repository: Holds code, versions it, secures it, and drives releasing an app to the stores. Make sure you have passwords to it.

What you can take from this is the general idea that several cloud-based systems are all working together, like a well-oiled machine, to process the the code and other outputs from the people in your app development team.

That system culminates in the App Store and Google Play store, but it starts with your cloud based code repo.

So when you think about what you get if someone builds you an app, it’s the keys to that repo that you want. It’s the goose that lays the golden eggs. Or at least lays the new updated versions of your app that you’re going to want down the track.

What Happens with Updates?

Now, once your customers download a new version of your app, they can open it up and the app and connect to cloud services to access additional functionality. We discussed this briefly in the previous posts on How Apps Work.

Let’s have a really good think about app updates (made by your development team); and about updates to the items that appear in your app (like services or menu items, or clothes for sale).

A customer may access a product for sale inside of your app, and complete a transaction to order that product to be delivered.

Customer payment transactions need special care in your app. Could they get charged and not receive what they paid for? Image credit: undraw.co

For this to work the app will probably need to contact a store API to check that there is sufficient inventory of the product to fulfil the order, collect the customers details, and then connect the customer to a banking API provided by your e-commerce solution.

So that is in a for-instance internet store app:

  • Your online storefront (a web-app)
  • Product fulfilment (drop-shipping or inventory)
  • Banking or e-commerce (PayPal or Stripe)
  • CRM system for customers details (Zoho or Hubspot)

What if one of these four change? You release a new app version right?

But unlike the web, your apps update when a new version is released to the App Store and installed by your customers. So you need for the old and the new version to work with all of the above services.

You’ll have customers out there with the old version of the app. Maybe for quite some time. They may just choose not to update. You at least need to not crash the app, and display some useful message like “Please update”.

Cloud or In-App?

Let’s say you manage digital for a small food chain. You have maybe a dozen restaurants in the country. And let’s say you update your menu.

You as a business app product owner may access your web-app, and update your restaurant menu in response to recent changes. Then submit those changes so the new menu goes live.

So where does the menu live? Cloud, or in-app?

If its in the cloud only – say via a hybrid app web-view, then customers who don’t have internet at the time they check your app cannot see the menu.

But if its on the phone only it makes your app downloads bigger, and you need to make an app update, just to change your menu.

In reality a good design might be to have it in the cloud, with a local cache, and a default that is installed with the app. So it’s in both places.

Stock in Trade

In your business what is providing value might be physical things you’re selling as items. Or it might be posts and reviews to your pet-minding or childcare app. Whatever they are, these items are your business to care about, if your customer is to succeed and lead to your app success.

What does all this mean from the point of view of your business?

It means that you really need to think about items that are going to appear in your app. Think about those items as part of a task it’s going to be completed by your customer – like viewing a menu, or a review.

And when you think about it, decide which details of the items have to be in the code and be shipped as part of the app. That details will be shipped to every single phone that has the app installed.

Ride share companies have Standard, Luxury and People-Mover options in their menu. Its easy to fix these in the app & update price etc from the cloud. Image credit: undraw.co

Also think which other parts will need to be live in the cloud and will need to be connected to and updated when the app is actually used.

Often the best way to visualise this is with detailed User Experience flows.

Alternatively there might be best practice for the stores or back-end API’s that you are using. So you might use a dedicated review site API. Either way you’ll need to think about where the information about those items is stored.

Viewing and Updating: Two Different Customer Tasks

Think about a case of products that are ordered in an app. In this example case only the cloud that the phone app connected to knew about the details of the products. But the app needs to know how to display them once it gets from the cloud the list of products that were available.

One pattern I have implemented for an app with In-App Purchases is to have 7 items that comprise the purchasable products. These 7 items are coded into the app, along with a name, description, category, price and photo. The app knows how to display all of these things in either a detail view for the item, or in a list of all items.

Let’s imagine one item is not available.

The picture changes if the app allows updates – that is the customer could review or purchase an item. Here we need to be careful.

For stores where items are a selection from a slow changing range, model them in the app and update availability online. Image credit: undraw.co

To check that we’re OK to display an item, our app can connect to the fulfilment centre and update the inventory amount, find that the item is out of stock, or off the menu, and update the view, so only 6 items appear in the store view.

This way you have a double-entry approach to the items in the app. The app knows about base items, and how to display them.

But that model is updated from the cloud, when the customer interacts with the app.

Out of Sync or Out of Stock

In the case of the menu for the restaurant, it might be possible to store the menus inside of the app when the code is being written. If you have items that are for sale, that are ordered up, like say a cake shop, it might be that you stop doing a particular item.

You could ship the app to the App Store with the menu inside of it. Customers could download your app and quickly see your menu of cakes without having to even connect to the Internet.

But do you see the problem here?

If you are not able to make say the carrot cake because carrots are in short supply, then you make it unavailable on the web-app; you need to make sure that the customer cannot place an order for it in the app. If a customers card was to get charged, and no cake was supplied that is a very bad result.

You need to think about what would happen if connectivity to the web-app was out – say due to your site being down for maintenance. Could the app still connect to Stripe?

Update transactions, especially ones involving customers money, need to be very carefully planned out. Handle error and no-network as well as success cases.

So here you need a “fail-closed” or “fail-safe” design for the user-experience flow. If the app does not get updated with a non-zero amount of cakes available, then it will show “out of stock” even if the app could not connect to the site.

Some very simple apps just function like a flyer or a brochure, and display information that changes infrequently. This can be okay if that’s all you need. But be very careful with update transactions.

Take Advantage of Dynamic Data

We talked in the previous post about stickiness being really important. We discussed ways to get customers to revisit your app. One way is to be updating the app with new content – if the app gets updated often customers will open the updated app because it appears on the home screen showing new updates are ready to be viewed, so sometimes it can be good to update the app.

However it can be a pain if you have important information that you need to change and customers have not updated the app, and thus seeing old information.

Tabbed apps with a profile have a chance to personalise things for the customer. Make them feel special and empowered. Image credit: undraw.co

This is why it’s important to break down the tasks that your customers are going to be completing inside of your app, step-by-step and think clearly about which parts of those tasks need to interact with data that is going to be stored on the cloud, versus data that can be stored inside the app itself.

Your app should know about the customer. It has stored information, so use that to display up-to-date dynamic information from your business.

We covered this in the previous section with a “be careful” message. Now we’re going to flip that, and think of the other risk of not having enough changing information.

Access and Roles

Let’s think some more about examples. Take the task of a craftsperson who updates the items for sale on a crafts-for-sale app. The app itself has owners who make the software for the app. But there’s a privileged role for the craftspeople who sell their wares on there. And of course the customers who buy the crafts are a third role.

The first thing that has to happen is there needs to be a way to confirm that whoever it is that’s connecting to the cloud service where the item information is stored actually has permission to change that data. Imagine if the craftsperson had a competitor who wanted to cause trouble – if there was no security anyone could connect and completely wreck their sales. 

So the app has to connect to a cloud service to check credentials of the craftsperson, and once it’s been confirmed that they have access the app can then go ahead and apply the changes.

You could get away with a hard-coded access for the owners of the app – they probably know the passwords they need. But you need something to handle that special privileged user: that something is a role.

Platform-as-a-Service. None Shall PaaS!

In reality it’s common to use what we call a platform-as-a-service or PaaS to provide a lot of the cloud functionality needed for things like login. PaaS is a special case of Software-as-a-Service or SaaS. These days it’s much more convenient to let someone else host that software, hence we can think of PaaS and SaaS as pretty much being the same thing.

If you’ve ever seen login with Google in an app, that’s using Google’s platform as a service.

This platform as a service for all kinds of cloud operations, in addition to login and authentication, including managing data, storing files and playing video. 

So now you understand that there are lots of different cloud components at the backend of any successful app.

UX Needs to be Mapped out for All Roles

There’s the cloud that gets new app versions out. They include the repo from when new versions of the app are pushed to the stores, and the continuous integration systems.

Then there’s your own business cloud, the store data of items that customers want to interact with, your business web-app, and platform-as-a-service providers. We’ll talk more about that last one later.

Even though these backend transactions can be complex, it’s not important to understand all of the technologies involved. Your developers will be across all the issues like encryption, and cloud storage.

A store owner role in a “crafts for sale” app would have different UX, than customers. Image credit: undraw.co
  • UX for Crafts for Sale app
    • Vendor
      • Photo, Description, Price – Modify
      • Reviews – View
    • Craft buyers
      • Review – Modify
      • Photo, Description, Price – View

The most important thing is to carefully break down the tasks that your customer figures will go through an item by item detail where data needs to flow as your customer completes that transaction with your website.

Big Backends

And do that for each type of customer. That is to say each role. Going back to our craftspeople – they are your customers too, if you own that crafts-for-sale app.

If the transaction involves you or an employee authenticating and operating on an administrator basis with your data it’s even more important to think carefully and clearly about every single step of that transaction.

Sometimes your backend, in-house operation scales up and just giving out the admin password to everyone is not good enough. Then you need to manage that as a role as well.

Roles, Items and UX. Oh my!

Ok, so we have covered quite a bit of confusing business stuff. But you can start to see how the complexity blows out really quickly once you have a matrix of roles, items that need managing and both views and online stores of those items.

It doesn’t matter how it’s implemented, your job as product owner is just to confirm that those steps work once the functionality is claimed to have been implemented by the developers.

The best way to deal with this is to put all your matrix of customer use-cases and roles, and item updates into a Great Big Chart. The cells that are not working yet are red, or yellow, and they get marked green once they work.

Product owners can map out complex roles & task interactions with a big chart. These are useful in acceptance testing. Image credit: undraw.co

Spreadsheets can work quite well for this, as long as you use ones that are accessible to everyone that needs to work on it.

In teams that are using a release-often, continuous integration model, the Product Owner can consult their chart to check during sprint review that working software is fulfilling use cases.

Front-load the High Risk

Note that it’s extremely normal for the most complex parts of an app to be implemented upfront early in the activate meant process so that you can check that these cloud transactions are successfully implemented by your development team, before getting into the longtail of completion.

But what happens in the app if we can’t connect to the cloud? What happens if someone connects to the cloud long enough to download the app, but then after that the cloud is not available because the network has dropped out or the customer has turned off their data?

One common problem with badly engineered apps is that they’re not robust against network dropouts, crashes, and use of behaviour such as backgrounding the app or closing the app.

Plan to test for network or other outages during your app acceptance, or automated tests. Image credit: undraw.co

When you think about a task that your customer is going to be completing in the app such as ordering, they will often switch to another app such as a text messaging app to consult with a friend about the purchase.

Poorly engineered apps may not handle being backgrounded in this way.

Now you have more rows and cells for your Great Big Chart. As well as cases for the different roles, you have “no-network” and “app backgrounded” rows as well.

Acceptance Testing and Releases

For this reason when doing acceptance testing on your app prior to release your product owner will work with the development team to test app packages that are release-candidates, ensuring that the app still works even if the network is turned off at times.

This testing is done on actual devices. End-to-end tests that include connecting to any cloud services should also be done at this time.  Note that some developers rely on test systems like browser stack which emulates phone devices, and does not actually use a real phone the way a customer would.

A cloud based error showing up in a native app due to mobile connectivity drop-outs. Screenshot taken by (c) Smithsoft 2020, Screen design (c) Uorda. Used by fair use.

Handle this by looking at your Great Big Chart and pick the items that would be Show-Stoppers for the release. These are the combinations of roles, items and use-cases for tasks which absolutely have to work. Write up these items as tests for your Quality Assurance team to try out when checking a release-candidate.

How do you handle this QA stuff?

“Wait, did you say QA? You haven’t even covered QA!” I hear you say.

It’s OK, how you handle this will depend on your team dynamics and the relationship you have to your developers.

Analytics and your Business

When we discussed the cloud and how apps work with it we discovered that there is kind of two clouds.

Firstly, there’s the cloud that is used to get your apps out to your customers. This is your Apple App Store, and Google Play Store; and also the repository of code along with your continuous integration systems that automate the process of getting new builds out so that your developers don’t have to do this manually.

Secondly we have the cloud that is used as the back-end of your app. There’s your own website or web-app, and various PaaS offerings and so on that can be integrated, payment providers and so on.

Well now we have a new cloud complication, that I had previously been ignoring so as make explanations easier.

And that extra complication is analytics.

What is it?

Analytics: the Necessary Complication to your Cloud or PaaS picture

Before I answer that I just want to say that analytics are pretty much the most important thing to include in your app. Get developers to include it the moment the app actually compiles on a device.

Typically its easy to do: just include the analytics vendors Software Development Kit (or SDK) in the build of your apps. Sometimes its as simple as adding a line in a dependency management system.

Once the SDK is in; developers have a new set of API’s that they can code to, allowing the documentation of customers doing tasks such as opening the apps cart, posting a new article or setting their profile picture. We know now how critical tasks are: analytics are what shows you your task completion, for the app out there in TV land. Its a view into the world of your customers.

Analytics are pretty much the most important thing to include in your app.

If you ever find yourself asking questions about what is happening with your app, the answer is usually “use analytics”.

In the past we used to refer to “Business Intelligence” for what we learn about our customers. And we know already about consoles for seeing what is happening with – for example – the uptake of new releases. Our database systems and the load on them is captured over time on consoles.

All of these come under the heading of analytics. And its yet more work for our already swamped Product Owner, and Project Manager/Team Lead. If some of the developer team are dedicated to reliability or operations, you might have some of them looking after analytics too.

Basically analytics are data that you get back from live systems. They are the most valuable data you have about your customers, about your apps and about how the whole system is working.

Back-end and Front-end Analytics? Hrrm, lets just say Analytics

Like the rest of the cloud picture you have back-end and front-end analytics. In my opinion there is no clean line between the two and its good to have some cross-over in who is looking at these to make sure actionable insights have more than one set of eyes on them.

The front end analytics can be Firebase Analytics (not to be confused with Google Analytics) which is free but part of the google megaplex; or MixPanel which is a paid-solution but independent & powerful, or one of the other myriad offerings in this complex space.

Flurry analytics, now owned by Yahoo. Free, still used, and the original mobile solution. (c) Smithsoft, screen (c) Flurry Inc.

These answer questions like what version of my app are users on? Who is entering my funnel for a particular task? Are there parts of the app that are dead – that is not being used? Are crashes or errors impacting my users?

There’s advertising and campaign related analytics too. These answer questions like which ads were most successful in getting my customers to install and actually open, then generate revenue in my app? These SDK’s will depend on which ads providers you’re using – often Facebook, Google or others.

The Software Development Kit proliferation

For these front end systems to work you need to include the vendors SDK into your mobile app, and then log events. This is essential to do.

The back end analytics will be your Google Play and App Store consoles, (which can include app crashes as well, as version information). This is not a replacement for proper mobile analytics however.

There’s your Continuous Integration system consoles that show what builds are progressing as they push to the stores automatically.

For the behaviour of your http traffic, that is your business web-site or web-app, there’s Splunk or New Relic, and many others that leverage log analysis to produce insights as to what’s going right or wrong.

Note that these SDK’s can expose your app to issues with the App Stores especially if out-of-date, so only use where necessary, update them aggressively, and purge them if not used.

An Alternative to Quality?

With great analytics across the board, developers can build quickly and with confidence knowing that any problems can be quickly detected and then fixed; sometimes even before many customers are affected.

Does this mean you don’t have to worry about all that pesky Quality Assurance. Well, almost. You can take that approach. Facebook has famously worked with “go fast and break things” type methodology.

Analytics can tell you what your customers are experiencing on the other side of the world, in other time zones before problems or bad reviews arise. But are they a replacement for quality? Image (c) Sarah Smith.

It all depends on your appetite for quality versus velocity of features. The needle on that barometer is a business decision that needs to be made at that level of your thinking.

In the early stages of a project, when fewer customers are involved, it can be a great idea to adopt a more aggressive feature velocity, use feature toggles to manage features that are not ready for mass adoption and watch the whole thing with analytics.

At least if your analytics picture is solid you have these options.

Sidebar: Developer Relations

As a business owner then, you should expect that your developer will give you access to the code that they have written for you. Your developer should give you a login to the repo where they’re placing the code that you are paying for. This is especially important if you’re playing things more arms length with your app development, rather than getting involved with daily work on the app.

I have worked with start-ups and customers in the past who have pressured and soured the relationship with their developers not realising that at any moment the cost of the developers walking away from the relationship was that they would lose everything. This happened because they did not have access to the code repository.

Communication is key to working with your whole development team. That communication includes access to code, UX designs and working software versions as apps are developed. Avoid souring your relationship as you need your team onside. Image credit: undraw.co

App owners who retain developers, often watch their apps grow with excitement, as release after release new features arrive. But if they don’t have access to the repo they may find they have nothing if that developer closes down business.

PaaS access is also Business Critical

But even access to the code is not enough, if there are back end services that you also need to make the app work. It’s common for example to store managed data in the cloud – the PaaS I mentioned above. These services are the ones that the app requires once it’s logged in to present dynamic data.

So to this end as an app development customer you need to work with your product owner or project manager to make sure that you have a shared list of login details for all the platform-as-a-service backends, the code repo and any other cloud facilities that are required to make the app work.

So lets assume you have the repository access, and the backend keys as well. You can log in to Firebase or whatever other PaaS is being used, and you’re all set up.

Quality Assurance and Getting New Apps Versions Out

The last thing is how to handle releases. As I mentioned above I don’t really cover QA in these articles.

The ideal situation is you have a low rate of problems with your app, you work tightly with your development team and they demonstrate features to you as product owner during the apps progress.

Ideally you have a soft-launch process where you curate early-access customers who get to experience the warts-and-all versions of the app. As the app stabilises feature-wise you get more bugs fixed as well.

But you can shoot for a high quality release as a different option. That’s a more old-school approach. Doing that involves more work than accepting a “release often” and “fix often” approach.

We discussed above the the idea of Continuous Integration. Developers show their work to the product owner on a daily basis, and present it as working software in the Sprint Review. In this model the developers write automated tests to make sure functionality keeps working.

But it is true that sometimes marketing departments and investors want a Big Bang release. Then you have to take a bit more rigour to your tests.

Pizza and Spreadsheets

When you work for a release that you want to expose to customers in a big way, you can consult your Great Big Chart, and come up with a suite of acceptance tests – again Excel or Google Sheets is fine for this.

The developers will supply a release candidate, say version RC1, which is on a seperate part of the code base called a branch. This part of the code base only gets fixes. No new features go into that branch.

Repository branches can provide a release candidate with separation from other code, in a high-process release model. Image credit: undraw.co

If your acceptance testing exposes problems then you go back to the team, who code a fix, put it in the branch and make a new version called RC2.

Finally you get a golden release candidate that goes out for your launch. You have a very high confidence in the quality. But it comes at a cost.

Either you have to shout everyone in your team lots of pizza and drinks as you sit around a table trying out all the cases in your Acceptance Tests spreadsheet. It can stretch for days if the process doesn’t go to plan.

You can outsource QA as well. This is quite common. But again its costly and also very variable results are had as the temptation to just throw it over the wall to an external QA house without an acceptance test suite is great.

Unless you have your tests worked out, the external QA house can find a bunch of pointless flaws that are not show stoppers, leaving the things you care about untested.

Continuous Integration

This is developer Nirvana. The golden standard for software is to have low errors, great automated tests that your continuous integration system runs for you, and just keep rolling out new releases every week or two.

Doing this is much preferred to having managed QA and high-process releases.

And it can be achieved but doing it requires a lot of discipline and some very talented engineering managers.

In Closing

In closing out this article let’s summarise what we have learnt.

  • Understand the role code plays in building your app.
    • It’s more complex than just developers pushing packages
    • Apps can be updated automatically from the repo
    • the repo is critical to the Continuous Integration of your app.
  • Secondly we covered how task-based-design can be used
    • to double check that even the most complex interactions
    • check roles to create a Great Big Chart of use-cases
  • As part of that design you should be sure about
    • which items are hardcoded into the app, and
    • which are dynamically fetched from cloud Apis.
  • Manage your relationship with your developer and team
    • Backend services that your app uses in production,
    • PaaS (platform as a service) like Google for login or
    • any other cloud database used for the app
    • You need admin access as part of the developer giving over control of the app to you as the app owner (but don’t abuse that access)
  • Quality assurance can be part of a big-bang release process but generally continuous releases and soft-launches are better if possible.
    • QA is costly unless you in-house it and
    • out-sourcing effectiveness depends on how good your acceptance testing documentation is.

Images (where noted) are the work of Katerina Limpitsouni. Check Katerina’s stuff on undraw.co.