//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
Apache Unomi gathers information about users actions, information that is processed and stored by Unomi services. The collected information can then be used to personalize content, derive insights on user behavior, categorize the user profiles into segments along user-definable dimensions or acted upon by algorithms.

=== Items and types

Unomi structures the information it collects using the concept of `Item` which provides the base information (an identifier and a type) the context server needs to process and store the data. Items are persisted according to their type (structure) and identifier (identity). This base structure can be extended, if needed, using properties in the form of key-value pairs.

These properties are further defined by the `Item`’s type definition which explicits the `Item`’s structure and semantics. By defining new types, users specify which properties (including the type of values they accept) are available to items of that specific type.

Unomi defines default value types: `date`, `email`, `integer` and `string`, all pretty self-explanatory. While you can think of these value types as "primitive" types, it is possible to extend Unomi by providing additional value types.

Additionally, most items are also associated to a scope, which is a concept that Unomi uses to group together related items. A given scope is represented in Unomi by a simple string identifier and usually represents an application or set of applications from which Unomi gathers data, depending on the desired analysis granularity. In the context of web sites, a scope could, for example, represent a site or family of related sites being analyzed. Scopes allow clients accessing the context server to filter data to only see relevant data.

_Base `Item` structure:_

[source,json]
----
{
  "itemType": <type of the item>,
  "scope": <scope>,
  "itemId": <item identifier>,
  "properties": <optional properties>
}
----

Some types can be dynamically defined at runtime by calling to the REST API while other extensions are done via Unomi plugins. Part of extending Unomi, therefore, is a matter of defining new types and specifying which kind of Unomi entity (e.g. profiles) they can be affected to. For example, the following JSON document can be passed to Unomi to declare a new property type identified (and named) `tweetNb`, tagged with the `social` tag, targeting profiles and using the `integer` value type.

_Example JSON type definition:_

[source,json]
----
{
    "itemId": "tweetNb",
    "itemType": "propertyType",
    "metadata": {
        "id": "tweetNb",
        "name": "tweetNb",
        "systemTags": ["social"]
    },
    "target": "profiles",
    "type": "integer"
}
----

____

Unomi defines a built-in scope (called `systemscope`) that clients can use to share data across scopes.
____

=== Events

Users' actions are conveyed from clients to the context server using events. Of course, the required information depends on what is collected and users' interactions with the observed systems but events minimally provide a type, a scope and source and target items. Additionally, events are timestamped. Conceptually, an event can be seen as a sentence, the event's type being the verb, the source the subject and the target the object.

_Event structure:_

[source,json]
----
{
    "eventType": <type of the event>,
    "scope": <scope of the event>,
    "source": <Item>,
    "target": <Item>,
    "properties": <optional properties>
}
----

Source and target can be any Unomi item but are not limited to them. In particular, as long as they can be described using properties and Unomi’s type mechanism and can be processed either natively or via extension plugins, source and target can represent just about anything. Events can also be triggered as part of Unomi’s internal processes for example when a rule is triggered.

Events are sent to Unomi from client applications using the JSON format and a typical page view event from a web site could look something like the following:

_Example page view event:_

[source,json]
----
{
    "eventType": "view",
    "scope": "ACMESPACE",
    "source": {
        "itemType": "site",
        "scope": "ACMESPACE",
        "itemId": "c4761bbf-d85d-432b-8a94-37e866410375"
    },
    "target": {
        "itemType": "page",
        "scope": "ACMESPACE",
        "itemId": "b6acc7b3-6b9d-4a9f-af98-54800ec13a71",
        "properties": {
            "pageInfo": {
            "pageID": "b6acc7b3-6b9d-4a9f-af98-54800ec13a71",
            "pageName": "Home",
            "pagePath": "/sites/ACMESPACE/home",
            "destinationURL": "http://localhost:8080/sites/ACMESPACE/home.html",
            "referringURL": "http://localhost:8080/",
            "language": "en"
        },
        "category": {},
        "attributes": {}
      }
    }
}
----

=== Profiles

By processing events, Unomi progressively builds a picture of who the user is and how they behave. This knowledge is embedded in `Profile` object. A profile is an `Item` with any number of properties and optional segments and scores. Unomi provides default properties to cover common data (name, last name, age, email, etc.) as well as default segments to categorize users. Unomi users are, however, free and even encouraged to create additional properties and segments to better suit their needs.

Contrary to other Unomi items, profiles are not part of a scope since we want to be able to track the associated user across applications. For this reason, data collected for a given profile in a specific scope is still available to any scoped item that accesses the profile information.

It is interesting to note that there is not necessarily a one to one mapping between users and profiles as users can be captured across applications and different observation contexts. As identifying information might not be available in all contexts in which data is collected, resolving profiles to a single physical user can become complex because physical users are not observed directly. Rather, their portrait is progressively patched together and made clearer as Unomi captures more and more traces of their actions. Unomi will merge related profiles as soon as collected data permits positive association between distinct profiles, usually as a result of the user performing some identifying action in a context where the user hadn’t already been positively identified.

=== Sessions

A session represents a time-bounded interaction between a user (via their associated profile) and a Unomi-enabled application. A session represents the sequence of actions the user performed during its duration. For this reason, events are associated with the session during which they occurred. In the context of web applications, sessions are usually linked to HTTP sessions.