April 26, 2024

Inuko Cloud Overview

Inuko Cloud is the software that hosts apps for customers (or tenants).
New customers can easily sign-up, for one or more apps.
Additionally each app can be customized individually per customer.
How does it work? Where does it work? Let's explore.


Inuko Cloud has 3 major functional components, the Databases the Server and the ClientApp.
Let's look at each in turn.


Customer data is stored in Azure SQL (Germany data center), specifically an Azure SQL pool with an Azure SQL Database for each customer.
(While that sounds complicated it is just a managed MSSQL server).

Databases are encrypted, as demanded by privacy protection laws and inline with best practices.
Customer data is also protected by regular backups:

  • Hourly (Point in Time) for last 7 days
  • Weekly for last 4 weeks
  • Monthly for 1 year

Server (backend)

The server (or backend) is the central communication point where everything comes together.
It is running in Microsoft Azure (Germany data center).

In a a nutshell, it connects authorized users to the Database.
To do so, it provides services to the ClientApp.


In order to identify a customer, the server uses the concept of an Organization.
Individual users (like you and me) belong to an organization.

Each organization receives a unique url like https://dog-super-store.inuko.net.


Data service

This service, allows the ClientApp to fetch or modify data in an organization's Database.
Before doing anything else, it will check whether the user belongs to the organization and she is authorized to access or modify data.

As an optimization, large data is transparently redirected and stored as Azure Blobs.

Metadata service

Organizations start with the same Database schema, but additional database tables or columns can be added. To describe and change the organization database schema, the ClientApp will use the server's metadata service.

At the core, the metadata service is a description of the database.

  1. List of database tables (sometimes called objects or entities)
  2. For each table
    • Name (all lowercase, only a-z and _ allowed)
    • Type (normal, many-to-many)
    • List of fields (columns)
  3. For each field
    • Name
    • Type, one of: text, whole number, money, date, lookup
    • Options, values that are allowed (or suggested)

Each db table (or object or entity) has a few mandatory fields:

  • id - the unique identificator of the record (long text like: 13535433-B024-4CA1-AC42-3A25989563F7)
  • name - the human readable identificator (for example if we have a table of car-makers, it can be "Toyota", "VW", "Ford" etc.).
  • creation date, modification date, etc.

The lookup type is used to define a relationship between tables. It stores the ID of a record.
This is also called a Foreign Key.
For example, let's say we have an sales-order table and a customer table.
We want to know who is the customer for each sales-order. To achieve that, we would create a customerid lookup field on the sales_order table.

The many-to-many table has always only 2 lookup fields. It is used to describe

Writing to the metadata api will update the description and update the sql schema to match.


This means making sure the user is who she says she is.
Each organization has (its own) database table of users.
Thus to authenticate a user the server receives the follwing info for the ClientApp:

  • the name of the organization (it is in the url).
  • the user's email
  • the user's password or Google, Microsoft or Apple confirmation that the email belongs to the user.

An organization can allow new user's to sign up (disabled by default).
Or more commonly an organization administrator will add users.

login login

There is no limit to how many organizations a particular user can belong to.
Keep in mind that while a single person (email in fact) can be part of multiple organizations, from the point of view of the Server these are distinct, independent users.
That means, if you sign in to one organization, it grants you no access to other orgs.


What a user can do is controlled with the authorization module.
We will need to define a few terms for this to make sense.
It might sounds a bit complicated at first.
But the befefit is that is easy to defined what each user can do can in great detail.

First of all each user can have multiple roles. (Example: sales-person, or manager.) A user role is a named collection of permissions. (Example: sales-person can see and edit their own customer records. Managers can edit all customer records and can also delete them.)
Each user can also be member of one or more teams. (Example: a sales person can belong the US or Europe team.)

A database record has an ownerid and teamid field. (Example: a customer record is owned by John and team US.)

Finally a permission defines what a role can do to records of a particular db table (object).
Each permission is combination of Database Table, Operation, Level. The operation is one of create, read, update or delete.
The level specifies on which records a user with this role can do the operation on. It is one of these:

  1. None - the user cannot do the operation on any record.
  2. Owner - if a user is the owner of the record (the record ownerid is equal to the user's id.) the operation is allowed.
  3. Team - if a user is a member of the record's team (the record teamid is equals to the id of one of the user's teams) the operatior is allowed.
  4. All - the operation is always allowed.



This is the component that the users actually see.
Most commonly it is running in user’s browser like Chrome or Edge or Safari.
There is also a separate ClientApp that can be installed on Windows or OSX. And there are ClientApps for iPhone and Android.


The ClientApp will collect user info and call on the Server to authenticate the user.
Then it will use the Server data & metadata service to get the information the user requires.

At his point the Client app could show the user all the records she has access to.
And allow her to modify them. While it would work, it is far from usable.

Instead we want to present the user with a more logical and user-friendly view of her data.
A view that allows for efficient navigation. That displays only pertinent information.
And provides access to more complex operation, not just the basic create, update & delete.

A view that is task, and not data oriented.

We call such an view App.

Apps - User Interface and Logic

The anatomy of an app is quite straightforward, an app is build from components.
There are different types of component, but they are all stored in the database inu_view table.
Thus each organization can have a completely different set of apps with unique UX.


Navigation menu is displayed on the left hand side. In contains a list of shortcuts, optionally divided into sections.
There are List and custom shortcuts (any http link or a custom component).


This component is a highly configurable list of records from a table.
Let's see what we can configure:

  1. Table - which table is the primary source of data.
  2. Name - name of the List
  3. Hidden (not visible by default, admin must enable)
  4. Fields - list of fields to show. From the primary table and all related tables (via lookups). Order and size can be adjusted.
  5. Filter - defines which records to show. For example, we could setup a filter to only list the records where the current user is the record owner.
  6. Sort - how is the list of records sorted. For example by name, or date, ascending or descending
  7. Display - List, Table, Map, Calendar, Chart - how to render the records.
  8. Command - list of built-in or custom operations.
  9. Quick filters - optional filters a user can apply at will.

When to show a particular List depends on the Navigation and Form configuration.


The role of this component is to drill down into details of a single database record.
Again, is is highly configurable:

  1. Table - which table is the primary source of data.
  2. Name - name of the form
  3. Collection of sub-components:
    • Splitter: splits the available space into a left and right hand side of configurable width.
    • Tabs: groups sub-components as Tabs
    • Flex: a horizontal or vertical list of sub-components
    • Fields: a list of database table fields. Separated into sections and configurable size and design.
    • SubList: this component displays a List of records related to the primary record. (Example: Customer's sales-orders).
    • Custom: custom sub-component (See further down in the Logic section)
  4. Command - list of built-in or custom operations.


For adding behavior or logic, javascript code is used. This code is executed in the browser.

Table-level logic This code can handle predefined events for each db table:

  1. change of fields on a record
  2. before a record is saved to the database
  3. after a record is saved to the database

Custom commands These are javascript functions invoked by List or Form custom commands.
The code can read or write db records, show custom UI or communicate with thirdparty services.

Custom component Furthermore javascript code can implement React components.
It is possible to create

  1. custom List element component
  2. custom Form field component
  3. custom Form sub-component
  4. custom Navigation component


This is a but an overview of the Inuko Cloud.
In future post will analyze each section in more detail.

As always, if there is a topic that you'd like to know more about, please get in touch.

Happy hacking!