io7m | single-page | multi-page | epub | Cardant User Manual 1.0.0-beta0001
3. Configuration
Previous
Front Matter
Up
5. Monitoring
Next

# 4. Model

- 4.1. Overview
- 4.2. Items
  - 4.2.1. Overview
  - 4.2.2. Metadata
  - 4.2.3. Types
  - 4.2.4. Scalar Types
  - 4.2.5. Attachments
- 4.3. Stock
  - 4.3.1. Overview
  - 4.3.2. Set Instance
  - 4.3.3. Serial Instance
  - 4.3.4. Repositing
    - 4.3.4.1. Overview
    - 4.3.4.2. Set Reposit
    - 4.3.4.3. Serial Reposit
    - 4.3.4.4. Definitions And Invariants
- 4.4. Locations
  - 4.4.1. Overview
  - 4.4.2. Metadata
  - 4.4.3. Types
  - 4.4.4. Attachments
  - 4.4.5. Hierarchy
- 4.5. Type Packages
  - 4.5.1. Overview
  - 4.5.2. Names
  - 4.5.3. Imports
  - 4.5.4. Serialization
- 4.6. Security
  - 4.6.1. Overview
  - 4.6.2. Roles
  - 4.6.3. Defined Roles
- 4.7. Audit Log
- 4.8. Inventory API

## 4.1. Overview

1
The cardant package provides a server-based application to track inventory. It stores detailed information about types of items, and can store the counts of those items present in defined locations.
2
This section of the documentation describes the internal cardant model.

## 4.2. Items

## 4.2.1. Overview

1
An item is an object that is tracked by the inventory system. When the cardant package refers to items, it should more accurately be understood to be referring to classes of items. That is, the inventory system tracks sets of items of a given class within locations. An item has associated metadata, an identifier that uniquely identifies the item class, zero or more types that can constrain the metadata associated with the item, and a name.

## 4.2.2. Metadata

1
Metadata is data associated with an item that describes that item. Items can have any number of metadata values, and inventory managers can introduce strong requirements on the presence and types of metadata on items through the application of types.

## 4.2.3. Types

1
A type is a label that can be applied to an item that will constrain the metadata associated with that item. A type on an item refers to a type declaration created by the inventory manager. A type declaration is essentially a record type in the sense that it defines a set of named metadata values along with their individual scalar types.
2
Types are intended to ensure the integrity and quality of metadata associated with items, and allow for more precise searching. For example, inventory managers might define a voltage_regulator type that is applied to electronics components within the inventory that are voltage regulators. The voltage_regulator type might be declared to require that metadata includes numeric values input_voltage and output_voltage that describe the input and output voltages of the regulator. Any attempt to update an item that has the voltage_regulator type applied without providing values for the input_voltage and output_voltage metadata will be rejected with a clear error message.
3
As mentioned, types are intended to facilitate more precise searching. It is possible to, for example, search for all items in the inventory that have an output_voltage metadata value, but this does not imply that all the returned items will be voltage regulators. With a well-designed and well-managed inventory, one can simply search for all items that have the type voltage_regulator (and then perhaps narrow down the search by asking for only those items that have an output_voltage value equal to 5.0).

## 4.2.4. Scalar Types

1
A scalar type is a named type derived from one of the following base types:

### 4.2.4.2. Metadata Value Types

Name | Description
--- | ---
Integral | A type used to express integer values.
Real | A type used to express real/fractional values.
Monetary | A type used to express monetary values. All values include an associated currency unit.
Time | A type used to express timestamp values. All values include a time zone value.
Text | A type used to express plain string values.

3
Typically, a named scalar type will augment an existing scalar base type with further constraints such as a bound on the range of allowed values. For example, an inventory manager supervising a stock of computer keyboards might define a keyboard type with a keys field of a scalar type keyboard.keys. The keyboard.keys scalar type might be derived from the Integral scalar type with a bound of [68, 104], expressing that keyboard may have as few as 68 or as many as 104 keys.

## 4.2.5. Attachments

1
Items can have zero or more attachments. An attachment is simply a file associated with the item according to a given relation. For example, an electronics component might have a PDF datasheet associated with it using a datasheet relation. Relations are entirely user-defined, and it is the responsibility of the inventory manager to use sensible and consistent relations.

## 4.3. Stock

## 4.3.1. Overview

1
A stock instance is an object that associates items with locations. A stock instance effectively says "this item is present in this location". A stock instance may be a set instance or a serial instance.
2
Stock instances have globally-unique UUID identifier values.

## 4.3.2. Set Instance

1
A set instance is a stock instance that describes a set of items that, by themselves, do not have any kind of unique identities.
2
For example, an inventory manager that is managing an inventory that contains rolls of passive electronics components such as resistors would use set instances to describe sets of resistors in the inventory. The resistors themselves do not have serial numbers or any kind of individual identity and therefore there is no reason to (or, in fact, any way to) track the individual resistors; only the count of resistors has any meaning.
3
A set instance always has a count ≥ 0. Attempting to remove items from a set instance such that the count would become negative is an error.

## 4.3.3. Serial Instance

1
A serial instance is a stock instance that describes a single item that may have one or more identities associated with it.
2
For example, an inventory manager that is managing an inventory that contains musical instruments would use serial instances to identify individual instruments in the inventory. Instruments of each type are distinguished from other instruments of the same type by way of serial numbers. A serial number in the cardant package is an arbitrary string. Serial numbers are unique for a given item class but are not assumed be globally unique. After all, two manufacturers of completely different products might coincidentally manage to use the same serial numbers for their products. Within a single manufacturer's product range, however, serial numbers will most assuredly be unique.
3
As mentioned, stock instances do have a guaranteed-unique identifier, so this can be used as a system-enforced unique identifier for an item if required.

## 4.3.4. Repositing

## 4.3.4.1. Overview

1
Stock is added to and removed from locations by repositing. Intuitively, a reposit operation atomically adds zero or more instances of an item to a location, and removes zero or more items from another location in a single step. A reposit operation is either a set reposit or a serial reposit.

## 4.3.4.2. Set Reposit

1
A set reposit is an operation used to move sets of items that do not, themselves, have useful individual identities.

## 4.3.4.3. Serial Reposit

1
A serial reposit is an operation used to move items that have individual identities.

## 4.3.4.4. Definitions And Invariants

1
Reposit operations are described by the following algebraic datatype:

### 4.3.4.4.2. Reposit

    type StockReposit =
      | CAStockRepositRemove CAStockInstanceID
      | CAStockRepositSerialIntroduce CAStockInstanceID CAItemID CALocationID CAItemSerial
      | CAStockRepositSerialMove CAStockInstanceID CALocationID
      | CAStockRepositSerialNumberAdd CAStockInstanceID CAItemSerial
      | CAStockRepositSerialNumberRemove CAStockInstanceID CAItemSerial
      | CAStockRepositSetAdd CAStockInstanceID Long
      | CAStockRepositSetIntroduce CAStockInstanceID CAItemID CALocationID Long
      | CAStockRepositSetMove CAStockInstanceID CAStockInstanceID CALocationID Long
      | CAStockRepositSetRemove CAStockInstanceID Long

3
A reposit (CAStockRepositSerialIntroduce i t l s) introduces a new serial stock instance i of item t, placing it in location l, and using the initial serial number s.
4
A reposit (CAStockRepositRemove i) removes the stock instance i.
5
A reposit (CAStockRepositSerialMove i l) moves an existing serial stock instance i from the location it is currently in to the new location l.
6
A reposit (CAStockRepositSerialNumberAdd i s) adds a new serial number s to an existing serial stock instance i.
7
A reposit (CAStockRepositSerialNumberRemove i s) removes a serial number s from an existing serial stock instance i.
8
A reposit (CAStockRepositSetIntroduce i t l c) introduces a new set stock instance i of item t, placing it in location l, and using the initial count c.
9
A reposit (CAStockRepositSetAdd i c) adds c items to an existing set stock instance i.
10
A reposit (CAStockRepositSetMove i0 i1 l c) moves c items from an existing set stock instance i0 to the set stock instance i1.
11
A reposit (CAStockRepositSetRemove i c) removes c items from an existing set stock instance i.

## 4.4. Locations

## 4.4.1. Overview

1
A location is an object that tracks item counts. Locations, as a concept, are kept deliberately abstract to allow for a wide range of use-cases. A location might represent a physical storage bin in a warehouse, or it might represent a deployed computer system that has been built using items taken from the inventory. By treating locations as generic containers in this manner, the system is intended to allow for supporting different use cases such as managing retail inventory, or managing the deployment of computer parts in a laboratory. Locations are hierarchical.

## 4.4.2. Metadata

1
Locations carry metadata in the same manner as items.

## 4.4.3. Types

1
Locations can have applied types in the same manner as items.

## 4.4.4. Attachments

1
Locations can have attachments in the same manner as items.

## 4.4.5. Hierarchy

1
Locations form a hierarchy (specifically, a tree) in that any location may have any number of child locations, although a location may only have at most one parent. Locations can be reparented at any time; they are not locked into having whichever parent they had when they were created.
2
The hierarchical nature of locations can be used to model different kinds of inventory arrangements. For example, a manager of computer laboratories might define Laboratory A and Laboratory B locations. Within those locations, the manager might define locations Computer A1, Computer A2, Computer A3, and so on. Within the Computer A1 location, the manager might place a single motherboard item, one or more CPU items, and so on, from the inventory. This allows the manager to know what computer parts they have, and the computers in which those parts are being used in the laboratories under their supervision. Additionally, should one assembled computer be moved from one laboratory to another, the manager can simply reparent the computer location to the new laboratory.
3
Conversely, a manager of a retail business might define a Storage Room A location, and then within that location, define Shelf A01, Shelf A02, Shelf A03, etc. The manager can then place items onto those storage shelf locations. This allows the manager to track what stock they have, and exactly where they're keeping each kind of item.

## 4.5. Type Packages

## 4.5.1. Overview

1
Types are introduced into a running cardant server using type packages. A type package is simply a named, versioned container of types that can be uploaded and installed into the server's database atomically.

## 4.5.2. Names

1
Type packages are identified by their name and version. It is not permitted to have two packages with the same name but different versions installed at the same time. A type package name is a Lanark dotted name (such as com.io7m.example) and the types declared within the package have their names derived by concatenating their unqualified names onto the end of the package name. So, for example, a package com.io7m.example that contains a scalar type named t will cause the scalar type com.io7m.example:t to be created on the server when the package is installed.

## 4.5.3. Imports

1
A type package may import other type packages. An import consists of a package name and a version range. When a user tries to install a type package p, each import i declared by p is examined, and the server inspects its own set of installed packages and verifies that a package is installed with both a name that matches i and a version that falls within the range declared by i. If no such package exists, the type package installation is rejected and the system is left untouched.
2
For the sake of simplicity, and because the number of installed type packages is expected to be small and not change particularly often, imports are merely an install-time check. It is possible (but heavily discouraged) for type packages to refer to types in packages that they have not imported.

## 4.5.4. Serialization

1
Type packages are serialized using the given XML schema.

## 4.6. Security

## 4.6.1. Overview

1
The cardant package uses role-based access control for all operations.

## 4.6.2. Roles

1
Each user has a set of roles associated with it. When the user attempts to perform an operation on the server, the account's roles are checked to see if it has permission to perform the action.
2
A role R may be granted to a user A by user B if B has role R. Accordingly, a role R may be revoked from a user A by user B if B has role R.
3
A user holding the inventory.admin role effectively always has all available roles. If new roles are added in future versions of the cardant package, users holding the inventory.admin role will be automatically granted the new roles. It is recommended to limit this role to a single user, and to avoid using that user account for day-to-day operations.

## 4.6.3. Defined Roles

1
The following roles are available:

### 4.6.3.2. Roles

Name | Description
--- | ---
inventory.files.writer | A writer of inventory files.
inventory.files.reader | A reader of inventory files.
inventory.items.writer | A writer of inventory items.
inventory.items.reader | A reader of inventory items.
inventory.locations.writer | A writer of inventory locations.
inventory.locations.reader | A reader of inventory locations.
audit.reader | A reader of the audit log.
inventory.admin | An all-powerful administrator of inventories.

## 4.7. Audit Log

1
The server maintains an append-only audit log consisting of a series of audit events. An audit event has an integer id, an owner (represented by an account UUID), a timestamp, a type, and a message consisting of a set of key/value pairs.
2
Each operation that changes the underlying database typically results in an event being logged to the audit log.

## 4.8. Inventory API

1
The inventory API is the interface exposed to user clients. It exposes a Cedarbridge-based API over HTTP, using the included schema.
2
The inventory API is the primary means by which clients perform operations on the server.
3. Configuration
Previous
Front Matter
Up
5. Monitoring
Next
io7m | single-page | multi-page | epub | Cardant User Manual 1.0.0-beta0001