# Data Modeling

## Core Concepts

At the heart of this data modeling system are the following fundamental concepts.

### DataNamespace

This is the top-level container, representing a logical grouping of data. Think of it as a "domain" or a "schema" in a database. It can contain:

- `DataModels`: Logical groupings of entities.
- `DataEntities`: The basic building blocks, representing individual data structures.
- `DataProperties`: Attributes of entities (e.g., name, age, address).
- `DataAssociations`: Relationships between entities (e.g., a user has an address).
- `Sub-namespaces`: Namespaces can be nested within each other, creating a hierarchical structure.
- `Foreign Namespaces`: References to external namespaces, enabling the use of entities defined elsewhere.
- `Tags`: Common tags for the entire namespace.

### DataModel

A logical grouping of `DataEntity` instances. It represents a specific data structure, like a "Product" or "User" model. A `DataModel` can contain multiple `DataEntity` instances.

### DataEntity

The fundamental building block of the data model. It represents a specific type of data, like a "User," "Product," or "Address."

- `Properties`: DataProperty instances that describe the attributes of the entity.
- `Associations`: DataAssociation instances that define relationships to other entities.
- `Parents`: An entity can inherit from other entities, creating a hierarchy.
- `Fields`: Ordered list of properties and associations.
- `Tags`: Optional tags for the UI.
- `Taxonomy`: Reserved for future use.
- `Deprecated`: Whether the entity is deprecated.
- `Schema`: The schema allowing to translate the model into a specific format (like JSON, RAML, XML, etc.)

### DataProperty

Represents an attribute of a `DataEntity`. It has a name, a data type (e.g., string, number, boolean), and optional constraints (e.g., required, multiple, min/max values).

- `Type`: The data type of the property.
- `Schema`: The general schema definition of this property.
- `Bindings`: The list of bindings for this property.
- `Tags`: Optional tags for the UI.
- `Taxonomy`: Reserved for future use.
- `Deprecated`: Whether the property is deprecated.
- `Primary`: Whether this property describes a primary key of the entity.
- `Index`: Whether this property describes an indexed property of the entity.
- `ReadOnly`: Whether the property is read only in the schema.
- `WriteOnly`: Whether the property is write only in the schema.

### DataAssociation

Defines a relationship between `DataEntity` instances. It specifies the target entities and the nature of the relationship (e.g., one-to-one, one-to-many).

- `Targets`: The list of target entities.
- `Multiple`: Whether the association allows multiple target entities.
- `Required`: Whether the association is required.
- `Schema`: The definition of the database/API schema
- `Bindings`: The list of bindings allowing to translate the model into a specific format (like JSON, RAML, XML, etc.)
- `Hidden`: Defines if this association is a part of the schema or not.

### Bindings

Defines a translation from a data model to a specific format (like JSON, RAML, XML, etc.)

## How a Data Domain is Structured

Here's how these components work together to structure a data domain:

1. **Root Namespace**: You start with a `DataNamespace`, which acts as the root of your data domain. This namespace is the top-level container for all other elements.

1. **Sub-namespaces (Optional)**: You can create sub-namespaces within the root namespace to further organize your data. This is useful for large domains with many entities and relationships.

1. **Data Models**: Within a namespace (or sub-namespace), you define `DataModel` instances. Each `DataModel` represents a specific area of your domain. For example, you might have a "User Management" `DataModel`, a "Product Catalog" `DataModel`, and an "Order Processing" `DataModel`.

1. **Data Entities**: Inside each `DataModel`, you define `DataEntity` instances. These are the core data structures. For example, in the "User Management" `DataModel`, you might have `DataEntity` instances for "User," "Role," and "Permission."

1. **Data Properties**: Each `DataEntity` has `DataProperty` instances that describe its attributes. For example, the "User" `DataEntity` might have `DataProperty` instances for "firstName" (string), "lastName" (string), "email" (string), "age" (number), etc.

1. **Data Associations**: You use `DataAssociation` instances to define relationships between `DataEntity` instances. For example:

   - A "User" has an "Address" (one-to-one).
   - A "User" has multiple "Roles" (one-to-many).
   - A "Product" belongs to a "Category" (many-to-one).
   - An "Order" contains multiple "Order Items" (one-to-many).

1. **Inheritance**: `DataEntity` instances can inherit from other `DataEntity` instances using the parents property. This allows you to create a hierarchy of entities and reuse common properties and associations.

1. **Foreign Namespaces**: You can reference entities from other namespaces using the foreign property of the root namespace. This allows you to reuse data structures defined elsewhere.

1. **Bindings**: You can define bindings for properties and associations to translate the data model into specific formats (e.g., JSON, RAML, XML, Protocol Buffers).

## Example Scenario

Let's imagine a simple e-commerce domain:

- **Root Namespace**: `ECommerce`
  - **Sub-namespace**: `Catalog`
    - **Data Model**: `ProductCatalog`
      - **Data Entity**: `Product`
        - **Data Properties**: `name` (string), `description` (string), `price` (number), `sku` (string)
        - **Data Association**: `category` (references `Category` entity)
      - **Data Entity**: `Category`
        - **Data Properties**: `name` (string), `description` (string)
  - **Sub-namespace**: `UserManagement`
    - **Data Model**: `UserManagement`
      - **Data Entity**: `User`
        - **Data Properties**: `firstName` (string), `lastName` (string), `email` (string), `password` (string)
        - **Data Association**: `address` (references `Address` entity)
      - **Data Entity**: `Address`
        - **Data Properties**: `street` (string), `city` (string), `zipCode` (string), `country` (string)
  - **Foreign Namespace**: `Taxonomy` (defined elsewhere)
    - **Data Model**: `Taxonomy`
      - **Data Entity**: `TaxonomyItem`

### Key Relationships

- **Namespace-Model**: A `DataNamespace` contains `DataModel` instances.
- **Model-Entity**: A `DataModel` contains `DataEntity` instances.
- **Entity-Property**: A `DataEntity` has `DataProperty` instances.
- **Entity-Association**: A `DataEntity` has `DataAssociation` instances.
- **Entity-Parent**: A `DataEntity` can have `DataEntity` instances as parents.
- **Namespace-Foreign**: A `DataNamespace` can have references to `DataNamespace` instances.

## Summary

This data modeling system provides a flexible and powerful way to define complex data domains. It allows you to:

- **Organize**: Group related data into namespaces and models.
- **Structure**: Define entities with properties and relationships.
- **Reuse**: Inherit from other entities and reference foreign namespaces.
- **Translate**: Define bindings to map the model to different formats.
- **Validate**: Validate the data model definition.
- **Generate**: Generate AMF shapes and examples.
