Cardant User Manual 1.0.0-SNAPSHOT

Book Metadata

DATE | 2023-12-16T17:05:50+00:00
DESCRIPTION | User manual for the cardant server.
IDENTIFIER | 9e6e25d5-7759-49a9-97b4-d0c645799e42
LANGUAGE | en
SOURCE | https://www.io7m.com/software/cardant/
TITLE | Cardant User Manual 1.0.0-SNAPSHOT

License

Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com

This book is placed into the public domain for free use by anyone for any purpose. It may be freely used, modified, and distributed.

In jurisdictions that do not recognise the public domain this book may be freely used, modified, and distributed without restriction.

This book comes with absolutely no warranty.

Table Of Contents

Cover

Colophon

Table Of Contents

1. Introduction

2. Installation

2.1. Overview

2.2. PostgreSQL

2.3. Idstore

2.4. Maven Central

2.5. OCI Images

2.5.1. Quay.io

2.5.2. Health Checks

2.6. Running The Server

2.6.1. Initialization

2.6.2. Running

2.7. Running The Shell

2.8. Database

2.8.1. Overview

2.8.2. Roles

2.8.2.1. Overview

2.8.2.2. Owner

2.8.2.3. Worker

2.8.2.4. Reader

3. Configuration

3.1. Overview

3.2. Smallest Working Configuration

3.3. InventoryService

3.3.1. Description

3.3.2. Example

3.4. Idstore

3.4.1. Overview

3.4.2. Description

3.4.3. Example

3.5. Maintenance

3.5.1. Overview

3.5.2. TLSReloadInterval

3.5.3. Example

3.6. Limits

3.6.1. Overview

3.6.2. MaximumFileUploadSizeOctets

3.6.3. MaximumCommandSizeOctets

3.6.4. Example

3.7. Database

3.7.1. Overview

3.7.2. Example

3.8. OpenTelemetry

3.8.1. Overview

3.8.2. Traces

3.8.3. Metrics

3.8.4. Logs

3.8.5. Example

3.9. Schema

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

5. Monitoring

5.1. Overview

5.2. Metrics

5.2.1. Names

6. Command-Line Interface

6.1. Overview

6.2. initialize

6.2.1. Name

6.2.2. Description

6.2.3. Parameters

6.2.4. Examples

6.3. package get

6.3.1. Name

6.3.2. Description

6.3.3. Parameters

6.3.4. Examples

6.4. package list

6.4.1. Name

6.4.2. Description

6.4.3. Parameters

6.4.4. Examples

6.5. server

6.5.1. Name

6.5.2. Description

6.5.3. Parameters

6.5.4. Examples

6.6. shell

6.6.1. Name

6.6.2. Description

6.6.3. Parameters

6.6.4. Examples

6.7. version

6.7.1. Name

6.7.2. Description

6.7.3. Parameters

6.7.4. Examples

7. Shell

7.1. Usage

7.1.1. Overview

7.1.2. Tab Completion

7.1.3. History

7.1.4. Quoting

7.1.5. Newlines

7.1.6. Formatter

7.1.7. Bookmarks

7.1.8. Searching

7.1.8.1. Description

7.1.8.2. Name Matching

7.1.8.3. Type Matching

7.1.8.4. Description Matching

7.1.8.5. Media Type Matching

7.1.8.6. Serial Matching

7.1.8.7. Package Matching

7.1.8.8. Field Matching

7.2. Shell Command Reference

7.2.1. audit-search-begin

7.2.1.1. Name

7.2.1.2. Description

7.2.1.3. Parameters

7.2.1.4. Examples

7.2.2. audit-search-next

7.2.2.1. Name

7.2.2.2. Description

7.2.3. audit-search-previous

7.2.3.1. Name

7.2.3.2. Description

7.2.4. bookmark-list

7.2.4.1. Name

7.2.4.2. Description

7.2.5. bookmark-login

7.2.5.1. Name

7.2.5.2. Description

7.2.5.3. Parameters

7.2.6. bookmark-put

7.2.6.1. Name

7.2.6.2. Description

7.2.6.3. Parameters

7.2.7. bookmark-remove

7.2.7.1. Name

7.2.7.2. Description

7.2.7.3. Parameters

7.2.8. file-get

7.2.8.1. Name

7.2.8.2. Description

7.2.8.3. Parameters

7.2.9. file-put

7.2.9.1. Name

7.2.9.2. Description

7.2.9.3. Parameters

7.2.10. file-search-begin

7.2.10.1. Name

7.2.10.2. Description

7.2.10.3. Parameters

7.2.11. file-search-next

7.2.11.1. Name

7.2.11.2. Description

7.2.12. file-search-previous

7.2.12.1. Name

7.2.12.2. Description

7.2.13. files-recent

7.2.13.1. Name

7.2.13.2. Description

7.2.14. help

7.2.14.1. Name

7.2.14.2. Description

7.2.14.3. Examples

7.2.15. item-attachment-add

7.2.15.1. Name

7.2.15.2. Description

7.2.15.3. Parameters

7.2.16. item-attachment-remove

7.2.16.1. Name

7.2.16.2. Description

7.2.16.3. Parameters

7.2.17. item-create

7.2.17.1. Name

7.2.17.2. Description

7.2.17.3. Parameters

7.2.18. item-get

7.2.18.1. Name

7.2.18.2. Description

7.2.18.3. Parameters

7.2.19. item-metadata-put

7.2.19.1. Name

7.2.19.2. Description

7.2.19.3. Parameters

7.2.20. item-metadata-remove

7.2.20.1. Name

7.2.20.2. Description

7.2.20.3. Parameters

7.2.21. item-search-begin

7.2.21.1. Name

7.2.21.2. Description

7.2.21.3. Parameters

7.2.22. item-search-next

7.2.22.1. Name

7.2.22.2. Description

7.2.23. item-search-previous

7.2.23.1. Name

7.2.23.2. Description

7.2.24. item-types-assign

7.2.24.1. Name

7.2.24.2. Description

7.2.24.3. Parameters

7.2.25. item-types-revoke

7.2.25.1. Name

7.2.25.2. Description

7.2.25.3. Parameters

7.2.26. location-attachment-add

7.2.26.1. Name

7.2.26.2. Description

7.2.26.3. Parameters

7.2.27. location-attachment-remove

7.2.27.1. Name

7.2.27.2. Description

7.2.27.3. Parameters

7.2.28. location-get

7.2.28.1. Name

7.2.28.2. Description

7.2.28.3. Parameters

7.2.29. location-list

7.2.29.1. Name

7.2.29.2. Description

7.2.30. location-put

7.2.30.1. Name

7.2.30.2. Description

7.2.30.3. Parameters

7.2.31. login

7.2.31.1. Name

7.2.31.2. Description

7.2.32. logout

7.2.32.1. Name

7.2.32.2. Description

7.2.33. roles-assign

7.2.33.1. Name

7.2.33.2. Description

7.2.33.3. Parameters

7.2.34. roles-get

7.2.34.1. Name

7.2.34.2. Description

7.2.34.3. Parameters

7.2.35. roles-revoke

7.2.35.1. Name

7.2.35.2. Description

7.2.35.3. Parameters

7.2.36. self

7.2.36.1. Name

7.2.36.2. Description

7.2.36.3. Examples

7.2.37. set

7.2.37.1. Name

7.2.37.2. Description

7.2.37.3. Parameters

7.2.38. stock-reposit-remove

7.2.38.1. Name

7.2.38.2. Description

7.2.38.3. Parameters

7.2.38.4. Examples

7.2.39. stock-reposit-serial-introduce

7.2.39.1. Name

7.2.39.2. Description

7.2.39.3. Parameters

7.2.39.4. Examples

7.2.40. stock-reposit-serial-move

7.2.40.1. Name

7.2.40.2. Description

7.2.40.3. Parameters

7.2.40.4. Examples

7.2.41. stock-reposit-serial-number-add

7.2.41.1. Name

7.2.41.2. Description

7.2.41.3. Parameters

7.2.41.4. Examples

7.2.42. stock-reposit-serial-number-remove

7.2.42.1. Name

7.2.42.2. Description

7.2.42.3. Parameters

7.2.42.4. Examples

7.2.43. stock-reposit-set-add

7.2.43.1. Name

7.2.43.2. Description

7.2.43.3. Parameters

7.2.43.4. Examples

7.2.44. stock-reposit-set-introduce

7.2.44.1. Name

7.2.44.2. Description

7.2.44.3. Parameters

7.2.44.4. Examples

7.2.45. stock-reposit-set-move

7.2.45.1. Name

7.2.45.2. Description

7.2.45.3. Parameters

7.2.45.4. Examples

7.2.46. stock-reposit-set-remove

7.2.46.1. Name

7.2.46.2. Description

7.2.46.3. Parameters

7.2.46.4. Examples

7.2.47. stock-search-begin

7.2.47.1. Name

7.2.47.2. Description

7.2.47.3. Parameters

7.2.47.4. Examples

7.2.48. stock-search-next

7.2.48.1. Name

7.2.48.2. Description

7.2.48.3. Examples

7.2.49. stock-search-previous

7.2.49.1. Name

7.2.49.2. Description

7.2.49.3. Examples

7.2.50. syntax-list

7.2.50.1. Name

7.2.50.2. Description

7.2.50.3. Examples

7.2.50.4. Parameters

7.2.51. syntax-show

7.2.51.1. Name

7.2.51.2. Description

7.2.51.3. Examples

7.2.51.4. Parameters

7.2.52. type-package-get-text

7.2.52.1. Name

7.2.52.2. Description

7.2.52.3. Parameters

7.2.52.4. Examples

7.2.53. type-package-install

7.2.53.1. Name

7.2.53.2. Description

7.2.53.3. Parameters

7.2.54. type-package-schema

7.2.54.1. Name

7.2.54.2. Description

7.2.54.3. Parameters

7.2.54.4. Examples

7.2.55. type-package-search-begin

7.2.55.1. Name

7.2.55.2. Description

7.2.55.3. Parameters

7.2.56. type-package-search-next

7.2.56.1. Name

7.2.56.2. Description

7.2.57. type-package-search-previous

7.2.57.1. Name

7.2.57.2. Description

7.2.58. type-package-uninstall

7.2.58.1. Name

7.2.58.2. Description

7.2.58.3. Parameters

7.2.59. type-package-upgrade

7.2.59.1. Name

7.2.59.2. Description

7.2.59.3. Parameters

7.2.60. version

7.2.60.1. Name

7.2.60.2. Description

7.2.60.3. Examples

8. API Access

8.1. Inventory Protocol

8.1.1. Versioning

8.1.2. Health

8.1.3. Version 1.0

8.1.3.1. Encoding

8.1.3.2. Login

8.1.3.3. Commands

8.1.3.4. Transactions

8.1.3.5. Schema

9. Security

9.1. Overview

9.2. Security

9.2.1. Overview

9.2.2. Security Policy Violations

10. Appendix: Schema: Type Package 1.0

1. Introduction

The cardant package provides a server for managing inventories.

1.2. Features

Tracks user-defined items within user-defined hierarchical storage locations.

Strongly-typed metadata with user-defined types.

Rich search functionality; perform complex searches over item metadata with automatic pagination and sorting.

Full API access for all operations.

Full Java API for performing operations.

Fine-grained capability based security model for operations; Safely write external services that can perform operations while maintaining the principle of least privilege.

Command-line shell.

Complete audit log; every operation that changes the state of the system is logged in an append-only log.

Fully instrumented with OpenTelemetry.

A small, easily auditable codebase with a heavy use of modularity for correctness.

An extensive automated test suite with high coverage.

Platform independence. No platform-dependent code is included in any form, and installations can largely be carried between platforms without changes.

OSGi-ready

JPMS-ready

Support for Canonmill keystores.

ISC license.

2. Installation

2.1. Overview

2.2. PostgreSQL

2.3. Idstore

2.4. Maven Central

2.5. OCI Images

2.5.1. Quay.io

2.5.2. Health Checks

2.6. Running The Server

2.6.1. Initialization

2.6.2. Running

2.7. Running The Shell

2.8. Database

2.8.1. Overview

2.8.2. Roles

2.8.2.1. Overview

2.8.2.2. Owner

2.8.2.3. Worker

2.8.2.4. Reader

2.1. Overview

The cardant server package is available from the following sources:

2.1.2. Sources

Maven Central

Quay.io

Regardless of the distribution method, the cardant package will contain a command named cardant that acts as the main entrypoint to all of the server and client functionality.

2.2. PostgreSQL

The cardant server requires a PostgreSQL server. The cardant server will create the required tables and database objects on first startup, given the name of a running PostgreSQL database, and a PostgreSQL role and password.

2.3. Idstore

The cardant server delegates all user and password management to idstore and therefore requires a running idstore server in order to work.

2.4. Maven Central

A distribution package can be found at Maven Central.

The cardant command requires that a Java 21+ compatible JVM be accessible via /usr/bin/env java.

Verify the integrity of the distribution zip file:

2.4.4. Verify

$ gpg --verify com.io7m.cardant.main-1.0.0-SNAPSHOT-distribution.zip.asc
gpg: assuming signed data in 'com.io7m.cardant.main-1.0.0-SNAPSHOT-distribution.zip.asc'
gpg: Signature made Tue 28 Jun 2022 15:01:56 GMT
gpg:                using RSA key 3CCE59428B30462D10459909C5607DA146E128B8
gpg:                issuer "contact@io7m.com"
gpg: using pgp trust model
gpg: Good signature from "io7m.com (2022 maven-rsa-key) <contact@io7m.com>" [unknown]

Unzip the zip file, and set up the environment appropriately. The cardant command expects an environment variable named CARDANT_HOME to be defined that points to the installation directory.

2.4.6. Extract

$ unzip com.io7m.cardant.main-1.0.0-SNAPSHOT-distribution.zip
$ export CARDANT_HOME=$(realpath cardant)
$ ./cardant/bin/cardant
cardant: usage: cardant [command] [arguments ...]
...

2.5. OCI Images

2.5.1. Quay.io

OCI images are available from Quay.io for use with podman or docker.

2.5.1.2. Podman/Docker

$ podman pull quay.io/io7mcom/cardant:1.0.0-SNAPSHOT
$ podman run quay.io/io7mcom/cardant:1.0.0-SNAPSHOT
cardant: usage: cardant [command] [arguments ...]
...

2.5.2. Health Checks

The OCI image includes a cardant-healthcheck command that makes a request to a health endpoint on the Inventory API server. The command expects the server to be accessible on localhost inside the container, and requires that the CARDANT_HEALTHCHECK_PORT environment variable be set to the port used by the Admin API. By default, the container sets CARDANT_HEALTHCHECK_PORT to 30000 and therefore there is no need to set this variable manually if the server is configured with the default settings.

This feature may only be available when running the image under docker due to limitations in the OCI image specification. The functionality of the health check service can be used directly via the Inventory API.

2.5.2.3. Health Example

$ curl http://localhost:30000/health
OK

2.6. Running The Server

2.6.1. Initialization

Given an appropriate configuration file in server.conf, it's necessary to tell cardant to configure the database and create an initial administrator. It's necessary to specify the idstore user ID of a user that will be considered to be the administrator of the cardant server:

2.6.1.2. Initialize

$ cardant initialize \
  --admin-id '92f83bce-3973-4db8-8aaf-d401443a9772' \
  --admin-name 'someone' \
  --configuration server.conf

It is not critical that the username given match the user ID on the idstore server; the name will be updated automatically from that server when a user logs in.

2.6.2. Running

The server can now be run with cardant server:

2.6.2.2. Run

$ cardant server --configuration server.conf
info: [localhost/<unresolved>:30000] Inventory API server started

The server does not fork into the background and is designed to be run under process supervision.

2.7. Running The Shell

Run cardant shell [1] to start the shell:

2.7.2. Shell

$ cardant shell
[cardant]# version
com.io7m.cardant 0.0.1-SNAPSHOT 20af71248a7784b0e5247eab4b1ebd28de284739

2.8. Database

2.8.1. Overview

The cardant package uses PostgreSQL for all persistent data.

2.8.2. Roles

2.8.2.1. Overview

The cardant package sets up multiple roles during database initialization. The configured roles have different degrees of privileges in order to allow, for example, external systems such as database metrics collectors read-only access to the database. All the defined rules are declared with the built-in PostgreSQL restrictions such as nocreatedb, nocreaterole, etc.

During the startup of the cardant server, the server will connect to the database using the owner role and do any database table initialization and/or schema upgrades necessary. The server will then disconnect from the database, and then connect to the database again using the worker role. The worker role is then used for normal operation of the server; if this role is somehow compromised, the role only has a limited ability to do any damage to the database, and cannot affect the audit log at all.

2.8.2.2. Owner

The owner role is the role that owns the database and is permitted to create tables, create new roles, etc. This role is used by the cardant package when creating the database during the first run of the server, and for upgrading database schemas later. Administrators are free to pick the name of the role, although it is recommended that the role be named cardant_install to make it clear as to the purpose of the role.

If the PostgreSQL OCI image is used, it is common to have the image create this role automatically using the POSTGRES_USER and POSTGRES_PASSWORD variables:

2.8.2.2.3. Example

$ podman run \
  --name some-postgres \
  -e POSTGRES_USER=cardant_install \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -d postgres

2.8.2.3. Worker

The worker role is the role that is used for normal database operation. It is a role that has read/write access to all tables (except for the audit log which is restricted to being append-only), although it is not granted the ability to create new tables, drop tables, or do other schema manipulation. The role is always named cardant, and adminstrators are required to set a password for this role.

2.8.2.4. Reader

The reader role is a role that is permitted read-only access to some of the database. It is effectively an optional role that can be used by various database metrics systems if required. If a password is not specified for the role in the server's configuration file, then logging in is not permitted at all.

Footnotes

1 | If running under podman or docker, remember to use the -i and -t options. References to this footnote: 1

3. Configuration

3.1. Overview

3.2. Smallest Working Configuration

3.3. InventoryService

3.3.1. Description

3.3.2. Example

3.4. Idstore

3.4.1. Overview

3.4.2. Description

3.4.3. Example

3.5. Maintenance

3.5.1. Overview

3.5.2. TLSReloadInterval

3.5.3. Example

3.6. Limits

3.6.1. Overview

3.6.2. MaximumFileUploadSizeOctets

3.6.3. MaximumCommandSizeOctets

3.6.4. Example

3.7. Database

3.7.1. Overview

3.7.2. Example

3.8. OpenTelemetry

3.8.1. Overview

3.8.2. Traces

3.8.3. Metrics

3.8.4. Logs

3.8.5. Example

3.9. Schema

3.1. Overview

The cardant server is configured using a single XML-formatted configuration file. The format has a fully documented schema and so configuration files can be independently validated, and benefit from autocompletion in most modern IDEs.

The configuration file must consist of a single top-level Configuration element in the com.io7m.cardant:configuration:1 namespace. In modern IDEs, simply creating a file containing this element will immediately fill in all the other required child elements.

3.2. Smallest Working Configuration

The smallest working configuration file, assuming a database at db.example.com and an idstore server at idstore.example.com:

3.2.2. Example

<?xml version="1.0" encoding="UTF-8" ?>

<Configuration xmlns="com.io7m.cardant:configuration:1"
               xmlns:ct="com.io7m.cardant:tls:1">

  <InventoryService ListenAddress="[::]"
                    ListenPort="30000"
                    SessionExpiration="PT30M"
                    ExternalAddress="http://cardant.example.com:30000">
    <ct:TLSDisabled/>
  </InventoryService>

  <Database Kind="POSTGRESQL"
            OwnerRoleName="cardant_install"
            OwnerRolePassword="892a2b68-2ddf-478a-a8ab-37172f6ac2fe"
            WorkerRolePassword="e61135dc-1d3f-4ab2-85ef-95ef49d66285"
            ReaderRolePassword="c2026069-97e7-45b1-85c4-a2349bbb847b"
            Address="db.example.com"
            Port="5432"
            Name="cardant"
            Create="true"
            Upgrade="true"
            Language="english"/>

  <Idstore BaseURI="https://idstore.example.com:50000"
           PasswordResetURI="https://idstore.example.com:50001/reset"/>

  <Limits MaximumFileUploadSizeOctets="10000000"
          MaximumCommandSizeOctets="10000000"/>

  <Maintenance TLSReloadInterval="PT24H"/>

  <OpenTelemetry LogicalServiceName="cardant01">
    <Logs Endpoint="http://logs.example.com:4317"
          Protocol="GRPC"/>
    <Metrics Endpoint="http://metrics.example.com:4317"
             Protocol="GRPC"/>
    <Traces Endpoint="http://traces.example.com:4317"
            Protocol="GRPC"/>
  </OpenTelemetry>

</Configuration>

3.3. InventoryService

3.3.1. Description

The InventoryService section of the configuration file configures the main inventory service.

The ListenAddress and ListenPort attributes specify the address and port to which to the HTTP service will bind.

The ExternalAddress attribute specifies the external address that clients will use to connect to this server.

By convention, the inventory service should listen on TCP port 30000.

The InventoryService element must contain either a TLSEnabled or TLSDisabled element specifying whether TLS should be enabled or disabled, respectively. The TLSEnabled element describes the key store and trust store. The cardant server automatically reloads certificates periodically in order to work well in environments using the ACME protocol to issue certificates.

3.3.2. Example

An example service configuration:

3.3.2.2. Example

<?xml version="1.0" encoding="UTF-8" ?>

<InventoryService xmlns="com.io7m.cardant:configuration:1"
                  xmlns:tls="com.io7m.cardant:tls:1"
                  ListenAddress="[::]"
                  ListenPort="30000"
                  SessionExpiration="PT30M"
                  ExternalAddress="http://cardant.example.com:30000">
  <tls:TLSEnabled>
    <tls:KeyStore Type="CANONMILL"
                  Provider="CANONMILL"
                  Password="ignored"
                  File="/cardant/keystore.xml"/>
    <tls:TrustStore Type="JKS"
                    Provider="SUN"
                    Password="changeit"
                    File="/usr/lib/jvm/java-21-openjdk/lib/security/cacerts"/>
  </tls:TLSEnabled>
</InventoryService>

3.4. Idstore

3.4.1. Overview

The Idstore section of the configuration file configures the external idstore server.

3.4.2. Description

The BaseURI attribute specifies the base URI of the User API of the external idstore server. This server is used to authenticate users whenever they try to log in to the cardant server.

The PasswordResetURI attribute specifies the URI to which users should be redirected if they want to reset their passwords. This is the URI of the User View service on the external idstore server.

3.4.3. Example

An example service configuration:

3.4.3.2. Example

<?xml version="1.0" encoding="UTF-8" ?>

<Idstore xmlns="com.io7m.cardant:configuration:1"
         BaseURI="https://idstore.example.com:50000"
         PasswordResetURI="https://idstore.example.com:50001/reset"/>

3.5. Maintenance

3.5.1. Overview

The Maintenance section of the configuration file configures the maintenance service.

3.5.2. TLSReloadInterval

The TLSReloadInterval attribute specifies how frequently the server will reload the TLS certificates for the HTTP services; the server will reload certificates every time this interval elapses. The attribute must be formatted as an ISO 8601 duration string.

3.5.3. Example

An example maintenance configuration:

3.5.3.2. Example

<Maintenance TLSReloadInterval="PT30M"/>

3.6. Limits

3.6.1. Overview

The Limits section of the configuration file configures various limits for the server.

3.6.2. MaximumFileUploadSizeOctets

The MaximumFileUploadSizeOctets attribute specifies the maximum size allowed for files uploaded the server. Requests to upload files larger than this limit will be rejected.

3.6.3. MaximumCommandSizeOctets

The MaximumCommandSizeOctets attribute specifies the maximum size allowed for commands sent to the server. Commands larger than this limit will be rejected.

3.6.4. Example

An example configuration:

3.6.4.2. Example

<Limits MaximumFileUploadSizeOctets="10000000"
        MaximumCommandSizeOctets="10000000"/>

3.7. Database

3.7.1. Overview

The Database section of the configuration file configures the database.

The OwnerRoleName attribute specifies the name of the role that owns the database. Conventionally, this should be cardant_install, but can be set independently by the database administrator.

The OwnerRolePassword attribute specifies the password of the owner role.

The WorkerRolePassword attribute specifies the password of the worker role used for normal database operation.

The ReaderRolePassword attribute specifies the password of the reader role used for read-only database access. If this attribute is not specified, logging in using this role will be prevented.

The MinimumPoolConnections attribute specifies the number of database connections to keep idle in the internal database connection pool. If this attribute is not specified, the default is 0.

The MaximumPoolConnections attribute specifies the maximum number of database connections to allow in the internal database connection pool. If this attribute is not specified, the default is 10. If the number of connections in the internal database pool reaches this value, the application will be forced to wait for a connection to become idle before it can obtain a new connection.

The Name attribute specifies the database name.

The Create attribute specifies that the database schema should be created on startup.

The Upgrade attribute specifies that the database schema should be upgraded on startup.

The Language attribute specifies the language that will be used internally for full-text searching.

3.7.2. Example

An example database configuration:

3.7.2.2. Example

<Database Kind="POSTGRESQL"
          OwnerRoleName="cardant_install"
          OwnerRolePassword="mydatabase"
          WorkerRolePassword="willquickly"
          ReaderRolePassword="becompromised"
          Address="db.example.com"
          Port="5432"
          Name="cardant"
          Create="true"
          Upgrade="true"
          Language="english"
          MinimumPoolConnections="1"
          MaximumPoolConnections="5"/>

3.8. OpenTelemetry

3.8.1. Overview

The OpenTelemetry section of the configuration file configures Open Telemetry. This section is optional and telemetry is disabled if the section is not present.

The logical service name should be provided in the LogicalServiceName attribute.

3.8.2. Traces

If the OpenTelemetry element contains a Traces element, OTLP traces will be sent to a specified endpoint. The Endpoint attribute specifies the endpoint, and the Protocol attribute can either be GRPC or HTTP.

3.8.3. Metrics

If the OpenTelemetry element contains a Metrics element, OTLP metrics will be sent to a specified endpoint. The Endpoint attribute specifies the endpoint, and the Protocol attribute can either be GRPC or HTTP.

3.8.4. Logs

If the OpenTelemetry element contains a Logs element, OTLP logs will be sent to a specified endpoint. The Endpoint attribute specifies the endpoint, and the Protocol attribute can either be GRPC or HTTP.

3.8.5. Example

An example Open Telemetry configuration:

3.8.5.2. Example

<OpenTelemetry LogicalServiceName="idstore">
  <Logs Endpoint="http://logs.example.com:4317"
        Protocol="GRPC"/>
  <Metrics Endpoint="http://metrics.example.com:4317"
           Protocol="GRPC"/>
  <Traces Endpoint="http://traces.example.com:4317"
          Protocol="GRPC"/>
</OpenTelemetry>

3.9. Schema

The XSD schema for the configuration file is as follows:

3.9.2. Configuration Schema

<?xml version="1.0" encoding="UTF-8" ?>

<!--
  Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-->

<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="com.io7m.cardant:configuration:1"
        xmlns:ct="com.io7m.cardant:tls:1"
        xmlns:c="com.io7m.cardant:configuration:1">

  <import namespace="com.io7m.cardant:tls:1"/>

  <annotation>
    <documentation>
      The schema for server configuration files.
    </documentation>
  </annotation>

  <simpleType name="DatabaseKind">
    <annotation>
      <documentation>
        The kind of the target database. Currently, only PostgreSQL is supported.
      </documentation>
    </annotation>

    <restriction base="string">
      <enumeration value="POSTGRESQL">
        <annotation>
          <documentation>
            The database is PostgreSQL.
          </documentation>
        </annotation>
      </enumeration>
    </restriction>
  </simpleType>

  <element name="Idstore">
    <annotation>
      <documentation>
        Configuration for the idstore server that will be used for user identity information.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="BaseURI"
                 type="anyURI"
                 use="required">
        <annotation>
          <documentation>
            The base URI of the idstore user API.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="PasswordResetURI"
                 type="anyURI"
                 use="required">
        <annotation>
          <documentation>
            The password reset URI to which to redirect users who want to reset their password.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <simpleType name="OpenTelemetryProtocol">
    <annotation>
      <documentation>
        The protocol used to deliver OpenTelemetry data.
      </documentation>
    </annotation>

    <restriction base="string">
      <enumeration value="GRPC">
        <annotation>
          <documentation>
            The data will be sent using gRPC.
          </documentation>
        </annotation>
      </enumeration>
      <enumeration value="HTTP">
        <annotation>
          <documentation>
            The data will be sent using HTTP(s).
          </documentation>
        </annotation>
      </enumeration>
    </restriction>
  </simpleType>

  <element name="Logs">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry logs.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Endpoint"
                 use="required"
                 type="anyURI">
        <annotation>
          <documentation>
            The endpoint to which OTLP log data will be sent.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Protocol"
                 use="required"
                 type="c:OpenTelemetryProtocol">
        <annotation>
          <documentation>
            The protocol used to send log data.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Metrics">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry metrics.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Endpoint"
                 use="required"
                 type="anyURI">
        <annotation>
          <documentation>
            The endpoint to which OTLP metrics data will be sent.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Protocol"
                 use="required"
                 type="c:OpenTelemetryProtocol">
        <annotation>
          <documentation>
            The protocol used to send metrics data.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Traces">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry traces.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Endpoint"
                 use="required"
                 type="anyURI">
        <annotation>
          <documentation>
            The endpoint to which OTLP trace data will be sent.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Protocol"
                 use="required"
                 type="c:OpenTelemetryProtocol">
        <annotation>
          <documentation>
            The protocol used to send trace data.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="OpenTelemetry">
    <annotation>
      <documentation>
        Configuration information for OpenTelemetry.
      </documentation>
    </annotation>

    <complexType>
      <sequence>
        <element ref="c:Logs"
                 minOccurs="0"
                 maxOccurs="1"/>
        <element ref="c:Metrics"
                 minOccurs="0"
                 maxOccurs="1"/>
        <element ref="c:Traces"
                 minOccurs="0"
                 maxOccurs="1"/>
      </sequence>

      <attribute name="LogicalServiceName"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The logical name of the service as it will appear in OpenTelemetry.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Database">
    <annotation>
      <documentation>
        Configuration information for the database.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="Kind"
                 type="c:DatabaseKind"
                 use="required"/>

      <attribute name="OwnerRoleName"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The name of the role that owns the database. This is used for the initial database setup, and for upgrades.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="OwnerRolePassword"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The password of the role that owns the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="WorkerRolePassword"
                 use="required"
                 type="string">
        <annotation>
          <documentation>
            The password of the role used for normal database operation. This is an unprivileged role that does not have
            the ability to perform DDL or other database-changing operations.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="ReaderRolePassword"
                 use="optional"
                 type="string">
        <annotation>
          <documentation>
            The password of the role used for read-only database operation. If this attribute is not specified, the
            read-only role is not allowed to log in.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Address"
                 type="string"
                 use="required">
        <annotation>
          <documentation>
            The address of the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Port"
                 type="integer"
                 use="required">
        <annotation>
          <documentation>
            The port used to connect to the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Name"
                 type="string"
                 use="required">
        <annotation>
          <documentation>
            The name of the database.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Create"
                 type="boolean"
                 use="required">
        <annotation>
          <documentation>
            If set to true, the database and tables will be created if they do not already exist.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Upgrade"
                 type="boolean"
                 use="required">
        <annotation>
          <documentation>
            If set to true, the database and tables will be upgraded to the latest supported schema version.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="Language"
                 type="string"
                 use="required">
        <annotation>
          <documentation>
            The language used for database search indexes (such as 'english'). See
            https://www.postgresql.org/docs/current/locale.html.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="MinimumPoolConnections"
                 use="optional"
                 default="1"
                 type="unsignedInt">
        <annotation>
          <documentation>
            The minimum number of connections to keep idle in the database connection pool.
          </documentation>
        </annotation>
      </attribute>

      <attribute name="MaximumPoolConnections"
                 use="optional"
                 default="10"
                 type="unsignedInt">
        <annotation>
          <documentation>
            The maximum number of connections to allow in the database connection pool. When this number of
            connections is active in the pool, the application will be forced to wait until a connection
            becomes idle upon requesting another connection.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <complexType name="HTTPService">
    <sequence minOccurs="1"
              maxOccurs="1">
      <group ref="ct:TLSGroup"/>
    </sequence>

    <attribute name="ListenAddress"
               type="string"
               use="required">
      <annotation>
        <documentation>
          The address upon which this HTTP service will listen.
        </documentation>
      </annotation>
    </attribute>

    <attribute name="ListenPort"
               type="integer"
               use="required">
      <annotation>
        <documentation>
          The port upon which this HTTP service will listen.
        </documentation>
      </annotation>
    </attribute>

    <attribute name="ExternalAddress"
               type="anyURI"
               use="required">
      <annotation>
        <documentation>
          The address by which this service is accessible to the outside world. The service will typically be configured
          behind a reverse proxy to provide TLS.
        </documentation>
      </annotation>
    </attribute>

    <attribute name="SessionExpiration"
               type="duration"
               use="optional">
      <annotation>
        <documentation>
          The expiration time for sessions.
        </documentation>
      </annotation>
    </attribute>
  </complexType>

  <element name="InventoryService"
           type="c:HTTPService">
    <annotation>
      <documentation>
        Configuration for the Inventory API service.
      </documentation>
    </annotation>
  </element>

  <element name="Limits">
    <annotation>
      <documentation>
        Configuration for various limits.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="MaximumFileUploadSizeOctets"
                 type="unsignedLong"
                 use="required">
        <annotation>
          <documentation>
            The maximum permitted size of uploaded files (in octets).
          </documentation>
        </annotation>
      </attribute>

      <attribute name="MaximumCommandSizeOctets"
                 type="unsignedLong"
                 use="required">
        <annotation>
          <documentation>
            The maximum permitted size of ordinary commands (in octets).
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Maintenance">
    <annotation>
      <documentation>
        Configuration for the server's periodic maintenance tasks.
      </documentation>
    </annotation>

    <complexType>
      <attribute name="TLSReloadInterval"
                     type="duration"
                     use="optional">
        <annotation>
          <documentation>
            The interval at which TLS contexts will be reloaded. If not
            specified, TLS contexts will not be reloaded.
          </documentation>
        </annotation>
      </attribute>
    </complexType>
  </element>

  <element name="Configuration">
    <annotation>
      <documentation>
        The top-level configuration element.
      </documentation>
    </annotation>

    <complexType>
      <sequence>
        <element ref="c:InventoryService"/>
        <element ref="c:Database"/>
        <element ref="c:Idstore"/>
        <element ref="c:Limits"/>
        <element ref="c:Maintenance"/>
        <element ref="c:OpenTelemetry"
                 minOccurs="0"
                 maxOccurs="1"/>
      </sequence>
    </complexType>
  </element>

</schema>

3.9.3. TLS Schema

<?xml version="1.0" encoding="UTF-8" ?>

<!--
  Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-->

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="com.io7m.cardant:tls:1"
            xmlns:nt="com.io7m.cardant:tls:1">

  <xsd:complexType name="StoreType"
                   abstract="true">
    <xsd:attribute name="Type"
                   type="xsd:string"
                   use="required"/>
    <xsd:attribute name="Provider"
                   type="xsd:string"
                   use="required"/>
    <xsd:attribute name="Password"
                   type="xsd:string"
                   use="required"/>
    <xsd:attribute name="File"
                   type="xsd:string"
                   use="required"/>
  </xsd:complexType>

  <xsd:complexType name="KeyStoreType">
    <xsd:complexContent>
      <xsd:extension base="nt:StoreType"/>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:complexType name="TrustStoreType">
    <xsd:complexContent>
      <xsd:extension base="nt:StoreType"/>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="KeyStore"
               type="nt:KeyStoreType"/>

  <xsd:element name="TrustStore"
               type="nt:TrustStoreType"/>

  <xsd:complexType name="TLSType"
                   abstract="true"/>

  <xsd:complexType name="TLSDisabledType">
    <xsd:complexContent>
      <xsd:extension base="nt:TLSType"/>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TLSDisabled"
               type="nt:TLSDisabledType"/>

  <xsd:complexType name="TLSEnabledType">
    <xsd:complexContent>
      <xsd:extension base="nt:TLSType">
        <xsd:sequence>
          <xsd:element ref="nt:KeyStore"/>
          <xsd:element ref="nt:TrustStore"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TLSEnabled"
               type="nt:TLSEnabledType"/>

  <xsd:group name="TLSGroup">
    <xsd:choice>
      <xsd:element ref="nt:TLSDisabled"/>
      <xsd:element ref="nt:TLSEnabled"/>
    </xsd:choice>
  </xsd:group>

</xsd:schema>

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

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.

This section of the documentation describes the internal cardant model.

4.2. Items

4.2.1. Overview

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

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

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.

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.

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

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.

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

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

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.

Stock instances have globally-unique UUID identifier values.

4.3.2. Set Instance

A set instance is a stock instance that describes a set of items that, by themselves, do not have any kind of unique identities.

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.

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

A serial instance is a stock instance that describes a single item that may have one or more serial numbers associated with it.

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.

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.

A serial number in the cardant package is a pair consisting of a type and an arbitrary string value. The type categorizes the serial number. For example, a purchased product might include the manufacturer-assigned serial number, and the inventory manager might choose to categorize serial numbers of this type by setting the type of the serial number to manufacturer_serial. The cardant package does not ascribe any particular semantics to serial number types, and types may be freely chosen by the inventory manager and do not need to be declared in any form ahead of time. Serial numbers are assumed to be unique for a given item class but are not assumed be globally unique, and uniqueness is not enforced by the system. 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.

4.3.4. Repositing

4.3.4.1. Overview

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

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

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

4.3.4.4. Definitions And Invariants

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

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.

A reposit (CAStockRepositRemove i) removes the stock instance i.

A reposit (CAStockRepositSerialMove i l) moves an existing serial stock instance i from the location it is currently in to the new location l.

A reposit (CAStockRepositSerialNumberAdd i s) adds a new serial number s to an existing serial stock instance i.

A reposit (CAStockRepositSerialNumberRemove i s) removes a serial number s from an existing serial stock instance i.

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.

A reposit (CAStockRepositSetAdd i c) adds c items to an existing set stock instance i.

A reposit (CAStockRepositSetMove i0 i1 l c) moves c items from an existing set stock instance i0 to the set stock instance i1.

A reposit (CAStockRepositSetRemove i c) removes c items from an existing set stock instance i.

4.4. Locations

4.4.1. Overview

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

Locations carry metadata in the same manner as items.

4.4.3. Types

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

4.4.4. Attachments

Locations can have attachments in the same manner as items.

4.4.5. Hierarchy

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.

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.

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

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

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

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.

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

Type packages are serialized using the given XML schema.

4.6. Security

4.6.1. Overview

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

4.6.2. Roles

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.

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.

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

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

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.

Each operation that changes the underlying database typically results in an event being logged to the audit log.

4.8. Inventory API

The inventory API is the interface exposed to user clients. It exposes a JSON-based API over HTTP, using the included schema.

The inventory API is the primary means by which clients perform operations on the server.

5. Monitoring

5.1. Overview

5.2. Metrics

5.2.1. Names

5.1. Overview

The cardant package is extensively instrumented with OpenTelemetry in order to allow for the server to be continually monitored. The package publishes metrics, logs, and traces, all of which can be independently enabled or disabled. Most installations will only want to enable metrics or logs in production; traces are more useful when trying to diagnose performance problems, or for doing actual development on the cardant package.

5.2. Metrics

5.2.1. Names

The package publishes the following metrics that can be used for monitoring:

5.2.1.2. Metrics

Name | Description
cardant_up | A gauge that displays a constant 1 value while the server is up.
cardant_http_time | A gauge that logs the time each HTTP request has taken in nanoseconds.
cardant_http_requests | A counter that is incremented every time an HTTP request is handled.
cardant_http_requests_size | A counter that is incremented with the size of every HTTP request.
cardant_http_responses_size | A counter that is incremented with the size of every produced HTTP response.
cardant_http_responses_2xx | A counter that is incremented with every HTTP response that produces a 2xx status code.
cardant_http_responses_4xx | A counter that is incremented with every HTTP response that produces a 4xx status code. A 4xx status code should be understood to mean "blame the client".
cardant_http_responses_5xx | A counter that is incremented with every HTTP response that produces a 5xx status code. A 5xx status code should be understood to mean "blame the server".
cardant_sessions | A gauge that displays the number of currently active user sessions.

The package may produce other metrics, however these are undocumented and should not be relied upon.

6. Command-Line Interface

6.1. Overview

6.2. initialize

6.2.1. Name

6.2.2. Description

6.2.3. Parameters

6.2.4. Examples

6.3. package get

6.3.1. Name

6.3.2. Description

6.3.3. Parameters

6.3.4. Examples

6.4. package list

6.4.1. Name

6.4.2. Description

6.4.3. Parameters

6.4.4. Examples

6.5. server

6.5.1. Name

6.5.2. Description

6.5.3. Parameters

6.5.4. Examples

6.6. shell

6.6.1. Name

6.6.2. Description

6.6.3. Parameters

6.6.4. Examples

6.7. version

6.7.1. Name

6.7.2. Description

6.7.3. Parameters

6.7.4. Examples

6.1. Overview

The cardant package provides a command-line interface for performing tasks such as starting the server, checking configuration files, and etc. The base cardant command is broken into a number of subcommands which are documented over the following sections.

6.1.2. Command-Line Overview

cardant: usage: cardant [command] [arguments ...]

  The cardant server command-line application.

  Use the "help" command to examine specific commands:

    $ cardant help help.

  Command-line arguments can be placed one per line into a file, and
  the file can be referenced using the @ symbol:

    $ echo help > file.txt
    $ echo help >> file.txt
    $ cardant @file.txt

  Commands:
    help          Show usage information for a command.
    initialize    Initialize the server and database.
    server        Start the server.
    shell         Start the shell.
    version       Show the application version.

  Documentation:
    https://www.io7m.com/software/cardant/

All subcommands accept a --verbose parameter that may be set to one of trace, debug, info, warn, or error. This parameter sets the lower bound for the severity of messages that will be logged. For example, at debug verbosity, only messages of severity debug and above will be logged. Setting the verbosity to trace level effectively causes everything to be logged, and will produce large volumes of debugging output.

The cardant command-line tool uses quarrel to parse command-line arguments, and therefore supports placing command-line arguments into a file, one argument per line, and then referencing that file with @. For example:

6.1.5. @ Syntax

$ cardant server --configuration server.conf

$ (cat <<EOF
--configuration
server.conf
EOF
) > args.txt

$ cardant @args.txt

All subcommands, unless otherwise specified, yield an exit code of 0 on success, and a non-zero exit code on failure.

6.2. initialize

6.2.1. Name

6.2.2. Description

6.2.3. Parameters

6.2.4. Examples

6.2.1. Name

initialize - Initialize the server

6.2.2. Description

The initialize command initializes or updates the database and the initial administrator.

6.2.3. Parameters

6.2.3.1. --admin-id

Attribute | Value
Name | --admin-id
Type | com.io7m.cardant.model.CAUserID
Default Value |
Cardinality | [1, 1]
Description | The ID of the user that will be the initial administrator.

6.2.3.2. --admin-name

Attribute | Value
Name | --admin-name
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The name of the user that will be the initial administrator.

6.2.3.3. --configuration

Attribute | Value
Name | --configuration
Type | java.nio.file.Path
Default Value |
Cardinality | [1, 1]
Description | The configuration file.

6.2.3.4. --verbose

Attribute | Value
Name | --verbose
Type | com.io7m.quarrel.ext.logback.QLogLevel
Default Value | info
Cardinality | [1, 1]
Description | Set the logging level of the application.

6.2.4. Examples

6.2.4.1. Example

$ cardant initialize \
  --admin-id '92f83bce-3973-4db8-8aaf-d401443a9772' \
  --admin-name 'someone' \
  --configuration server.conf

6.3. package get

6.3.1. Name

6.3.2. Description

6.3.3. Parameters

6.3.4. Examples

6.3.1. Name

package get - Get the text of a package

6.3.2. Description

The package get command gets the text of a built-in type package. The text of the package can be written to a file and then optionally installed with type-package-install shell command.

6.3.3. Parameters

6.3.3.1. --name

Attribute | Value
Name | --name
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The package name.

6.3.3.2. --output

Attribute | Value
Name | --output
Type | java.nio.file.Path
Default Value |
Cardinality | [0, 1]
Description | The output file.

6.3.3.3. --version

Attribute | Value
Name | --version
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The package version.

6.3.4. Examples

6.3.4.1. Example

$ cardant package get --name cardant.product --version 1.0.0
<?xml version="1.0" encoding="UTF-8" ?>
<Package xmlns="com.io7m.cardant:type_packages:1">
  <PackageInfo Name="cardant.product"
               Version="1.0.0"
               Description="Manufactured products."/>
  <TypeScalarText Name="manufacturer"
...

$ cardant package get --name cardant.product --version 1.0.0 --output out.xml

6.4. package list

6.4.1. Name

6.4.2. Description

6.4.3. Parameters

6.4.4. Examples

6.4.1. Name

package list - List packages that are available for install

6.4.2. Description

The package list command lists the built-in type packages that are available to install.

6.4.3. Parameters

The command has no parameters.

6.4.4. Examples

6.4.4.1. Example

$ cardant package list
# Package         Version
cardant.product   1.0.0-SNAPSHOT

6.5. server

6.5.1. Name

6.5.2. Description

6.5.3. Parameters

6.5.4. Examples

6.5.1. Name

server - Start the server

6.5.2. Description

The server command starts the server.

6.5.3. Parameters

6.5.3.1. --configuration

Attribute | Value
Name | --configuration
Type | java.nio.file.Path
Default Value |
Cardinality | [1, 1]
Description | The configuration file.

6.5.3.2. --verbose

Attribute | Value
Name | --verbose
Type | com.io7m.quarrel.ext.logback.QLogLevel
Default Value | info
Cardinality | [1, 1]
Description | Set the logging level of the application.

6.5.4. Examples

6.5.4.1. Example

$ cardant server --configuration server.conf
info: [localhost/<unresolved>:30000] Inventory API server started

6.6. shell

6.6.1. Name

6.6.2. Description

6.6.3. Parameters

6.6.4. Examples

6.6.1. Name

shell - Start the shell

6.6.2. Description

The server command starts the shell.

6.6.3. Parameters

6.6.3.1. --verbose

Attribute | Value
Name | --verbose
Type | com.io7m.quarrel.ext.logback.QLogLevel
Default Value | info
Cardinality | [1, 1]
Description | Set the logging level of the application.

6.6.4. Examples

6.6.4.1. Example

$ cardant shell
[cardant]# version
com.io7m.cardant 0.0.1-SNAPSHOT 20af71248a7784b0e5247eab4b1ebd28de284739

6.7. version

6.7.1. Name

6.7.2. Description

6.7.3. Parameters

6.7.4. Examples

6.7.1. Name

version - Display the package version

6.7.2. Description

The version command displays the current version of the package.

6.7.3. Parameters

The command has no parameters.

6.7.4. Examples

6.7.4.1. Example

cardant: usage: version

  Show the application version.

  The command does not accept any named arguments.

  The command does not accept any positional arguments.

  The version command produces the following output, in order:

    * The application ID (such as "com.io7m.quarrel")
    * The application version (such as "1.2.0")
    * The application build (such as "eacd59a2")

  For example, for a hypothetical application named "quarrel":

    $ quarrel version
    com.io7m.quarrel 1.2.0 eacd59a2

7. Shell

7.1. Usage

7.1.1. Overview

7.1.2. Tab Completion

7.1.3. History

7.1.4. Quoting

7.1.5. Newlines

7.1.6. Formatter

7.1.7. Bookmarks

7.1.8. Searching

7.1.8.1. Description

7.1.8.2. Name Matching

7.1.8.3. Type Matching

7.1.8.4. Description Matching

7.1.8.5. Media Type Matching

7.1.8.6. Serial Matching

7.1.8.7. Package Matching

7.1.8.8. Field Matching

7.2. Shell Command Reference

7.2.1. audit-search-begin

7.2.1.1. Name

7.2.1.2. Description

7.2.1.3. Parameters

7.2.1.4. Examples

7.2.2. audit-search-next

7.2.2.1. Name

7.2.2.2. Description

7.2.3. audit-search-previous

7.2.3.1. Name

7.2.3.2. Description

7.2.4. bookmark-list

7.2.4.1. Name

7.2.4.2. Description

7.2.5. bookmark-login

7.2.5.1. Name

7.2.5.2. Description

7.2.5.3. Parameters

7.2.6. bookmark-put

7.2.6.1. Name

7.2.6.2. Description

7.2.6.3. Parameters

7.2.7. bookmark-remove

7.2.7.1. Name

7.2.7.2. Description

7.2.7.3. Parameters

7.2.8. file-get

7.2.8.1. Name

7.2.8.2. Description

7.2.8.3. Parameters

7.2.9. file-put

7.2.9.1. Name

7.2.9.2. Description

7.2.9.3. Parameters

7.2.10. file-search-begin

7.2.10.1. Name

7.2.10.2. Description

7.2.10.3. Parameters

7.2.11. file-search-next

7.2.11.1. Name

7.2.11.2. Description

7.2.12. file-search-previous

7.2.12.1. Name

7.2.12.2. Description

7.2.13. files-recent

7.2.13.1. Name

7.2.13.2. Description

7.2.14. help

7.2.14.1. Name

7.2.14.2. Description

7.2.14.3. Examples

7.2.15. item-attachment-add

7.2.15.1. Name

7.2.15.2. Description

7.2.15.3. Parameters

7.2.16. item-attachment-remove

7.2.16.1. Name

7.2.16.2. Description

7.2.16.3. Parameters

7.2.17. item-create

7.2.17.1. Name

7.2.17.2. Description

7.2.17.3. Parameters

7.2.18. item-get

7.2.18.1. Name

7.2.18.2. Description

7.2.18.3. Parameters

7.2.19. item-metadata-put

7.2.19.1. Name

7.2.19.2. Description

7.2.19.3. Parameters

7.2.20. item-metadata-remove

7.2.20.1. Name

7.2.20.2. Description

7.2.20.3. Parameters

7.2.21. item-search-begin

7.2.21.1. Name

7.2.21.2. Description

7.2.21.3. Parameters

7.2.22. item-search-next

7.2.22.1. Name

7.2.22.2. Description

7.2.23. item-search-previous

7.2.23.1. Name

7.2.23.2. Description

7.2.24. item-types-assign

7.2.24.1. Name

7.2.24.2. Description

7.2.24.3. Parameters

7.2.25. item-types-revoke

7.2.25.1. Name

7.2.25.2. Description

7.2.25.3. Parameters

7.2.26. location-attachment-add

7.2.26.1. Name

7.2.26.2. Description

7.2.26.3. Parameters

7.2.27. location-attachment-remove

7.2.27.1. Name

7.2.27.2. Description

7.2.27.3. Parameters

7.2.28. location-get

7.2.28.1. Name

7.2.28.2. Description

7.2.28.3. Parameters

7.2.29. location-list

7.2.29.1. Name

7.2.29.2. Description

7.2.30. location-put

7.2.30.1. Name

7.2.30.2. Description

7.2.30.3. Parameters

7.2.31. login

7.2.31.1. Name

7.2.31.2. Description

7.2.32. logout

7.2.32.1. Name

7.2.32.2. Description

7.2.33. roles-assign

7.2.33.1. Name

7.2.33.2. Description

7.2.33.3. Parameters

7.2.34. roles-get

7.2.34.1. Name

7.2.34.2. Description

7.2.34.3. Parameters

7.2.35. roles-revoke

7.2.35.1. Name

7.2.35.2. Description

7.2.35.3. Parameters

7.2.36. self

7.2.36.1. Name

7.2.36.2. Description

7.2.36.3. Examples

7.2.37. set

7.2.37.1. Name

7.2.37.2. Description

7.2.37.3. Parameters

7.2.38. stock-reposit-remove

7.2.38.1. Name

7.2.38.2. Description

7.2.38.3. Parameters

7.2.38.4. Examples

7.2.39. stock-reposit-serial-introduce

7.2.39.1. Name

7.2.39.2. Description

7.2.39.3. Parameters

7.2.39.4. Examples

7.2.40. stock-reposit-serial-move

7.2.40.1. Name

7.2.40.2. Description

7.2.40.3. Parameters

7.2.40.4. Examples

7.2.41. stock-reposit-serial-number-add

7.2.41.1. Name

7.2.41.2. Description

7.2.41.3. Parameters

7.2.41.4. Examples

7.2.42. stock-reposit-serial-number-remove

7.2.42.1. Name

7.2.42.2. Description

7.2.42.3. Parameters

7.2.42.4. Examples

7.2.43. stock-reposit-set-add

7.2.43.1. Name

7.2.43.2. Description

7.2.43.3. Parameters

7.2.43.4. Examples

7.2.44. stock-reposit-set-introduce

7.2.44.1. Name

7.2.44.2. Description

7.2.44.3. Parameters

7.2.44.4. Examples

7.2.45. stock-reposit-set-move

7.2.45.1. Name

7.2.45.2. Description

7.2.45.3. Parameters

7.2.45.4. Examples

7.2.46. stock-reposit-set-remove

7.2.46.1. Name

7.2.46.2. Description

7.2.46.3. Parameters

7.2.46.4. Examples

7.2.47. stock-search-begin

7.2.47.1. Name

7.2.47.2. Description

7.2.47.3. Parameters

7.2.47.4. Examples

7.2.48. stock-search-next

7.2.48.1. Name

7.2.48.2. Description

7.2.48.3. Examples

7.2.49. stock-search-previous

7.2.49.1. Name

7.2.49.2. Description

7.2.49.3. Examples

7.2.50. syntax-list

7.2.50.1. Name

7.2.50.2. Description

7.2.50.3. Examples

7.2.50.4. Parameters

7.2.51. syntax-show

7.2.51.1. Name

7.2.51.2. Description

7.2.51.3. Examples

7.2.51.4. Parameters

7.2.52. type-package-get-text

7.2.52.1. Name

7.2.52.2. Description

7.2.52.3. Parameters

7.2.52.4. Examples

7.2.53. type-package-install

7.2.53.1. Name

7.2.53.2. Description

7.2.53.3. Parameters

7.2.54. type-package-schema

7.2.54.1. Name

7.2.54.2. Description

7.2.54.3. Parameters

7.2.54.4. Examples

7.2.55. type-package-search-begin

7.2.55.1. Name

7.2.55.2. Description

7.2.55.3. Parameters

7.2.56. type-package-search-next

7.2.56.1. Name

7.2.56.2. Description

7.2.57. type-package-search-previous

7.2.57.1. Name

7.2.57.2. Description

7.2.58. type-package-uninstall

7.2.58.1. Name

7.2.58.2. Description

7.2.58.3. Parameters

7.2.59. type-package-upgrade

7.2.59.1. Name

7.2.59.2. Description

7.2.59.3. Parameters

7.2.60. version

7.2.60.1. Name

7.2.60.2. Description

7.2.60.3. Examples

7.1. Usage

7.1.1. Overview

7.1.2. Tab Completion

7.1.3. History

7.1.4. Quoting

7.1.5. Newlines

7.1.6. Formatter

7.1.7. Bookmarks

7.1.8. Searching

7.1.8.1. Description

7.1.8.2. Name Matching

7.1.8.3. Type Matching

7.1.8.4. Description Matching

7.1.8.5. Media Type Matching

7.1.8.6. Serial Matching

7.1.8.7. Package Matching

7.1.8.8. Field Matching

7.1.1. Overview

In addition to the API access the server provides, the cardant package includes an interactive command-line shell for performing tasks.

The shell is started using the shell command. The shell supports basic tab-completion and history accessed with the up and down arrows.

7.1.2. Tab Completion

When running on an appropriate terminal, the shell supports tab completion for command and most command arguments. Begin typing the name of a command, or the name of a command argument, and then press tab. A set of completion options will be displayed.

7.1.2.2. Command Completion

7.1.2.3. Argument Completion

7.1.3. History

When running on an appropriate terminal, the command shell stores the history of commands in memory (the history is not saved to disk, for security reasons). Press the up and down arrows to navigate to previously executed commands.

7.1.4. Quoting

Arguments to shell commands may be quoted using the " or ' characters. This is required when calling commands that take arguments that may need to contain strings.

7.1.4.2. Strings

7.1.5. Newlines

Typically, the ENTER key ends the current line. This will cause the shell to interpret the contents of a line as a command and execute it. Pressing ALT+ENTER inserts an actual newline character without executing the command. This can be useful if an argument to a command needs to contain a newline character:

7.1.5.2. Strings

When in this mode, the cursor can be moved around freely with the arrow keys to allow for editing lines. Pressing the ENTER key ends the multiline editing mode and executes the command.

7.1.6. Formatter

The shell provides different formatting options for tabular data.

7.1.6.2. Formatters

Name | Description
PRETTY | Provides pretty Unicode tables.
RAW | Provides raw tables.

The formatter can be set using the set command.

7.1.6.4. Example

[cardant]$ set --formatter PRETTY
[cardant]$ audit-search-begin
Search results: Page 1 of 1
┌────┬──────────────────────────────────────┬────────────────┬─────────────────────────────┬─────────────────────────────────────────────────────────────────────────┐
│ ID │ Owner                                │ Type           │ Time                        │ Data                                                                    │
├────┼──────────────────────────────────────┼────────────────┼─────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ 1  │ c5574d46-7413-43c8-b6db-31001c382ca3 │ USER_LOGGED_IN │ 2023-12-21T11:30:11.171839Z │ {UserAgent=com.io7m.cardant.client/0.0.1-SNAPSHOT, Host=10.1.6.1:53236} │
└────┴──────────────────────────────────────┴────────────────┴─────────────────────────────┴─────────────────────────────────────────────────────────────────────────┘

[cardant]$ set --formatter RAW
[cardant]$ audit-search-begin
# Search results: Page 1 of 1
#--------------------------------
1 c5574d46-7413-43c8-b6db-31001c382ca3 USER_LOGGED_IN 2023-12-21T11:30:11.171839Z {UserAgent=com.io7m.cardant.client/0.0.1-SNAPSHOT, Host=10.1.6.1:53236}

7.1.7. Bookmarks

The shell allows for setting server bookmarks. A server bookmark is essentially the information required to log in to a particular server as a particular user.

Bookmarks can be created with the bookmark-put command, listed with the bookmark-list command, and used with the bookmark-login command.

7.1.7.3. Example

[cardant]$ bookmark-put --user example --password F7B7D37C620C70BF03353148582AC97D --hostname 10.1.6.1 --name local0

[cardant]$ bookmark-list
┌─────────────────┬─────────────────────────┬───────┬───────┬──────────────────┐
│ Name            │ Host                    │ Port  │ TLS   │ User             │
├─────────────────┼─────────────────────────┼───────┼───────┼──────────────────┤
│ local0          │ 10.1.6.1                │ 30000 │ false │ example          │
└─────────────────┴─────────────────────────┴───────┴───────┴──────────────────┘
[cardant]$ bookmark-login --name local0

[cardant]$ self
User ID: c5574d46-7413-43c8-b6db-31001c382ca3
┌────────────────────────────────────────────────────────────────────────────────┐
│ Role                                                                           │
├────────────────────────────────────────────────────────────────────────────────┤
│ audit.reader                                                                   │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.admin                                                                │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.files.reader                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.files.writer                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.items.reader                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.items.writer                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.locations.reader                                                     │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.locations.writer                                                     │
└────────────────────────────────────────────────────────────────────────────────┘

7.1.8. Searching

7.1.8.1. Description

The cardant package exposes many commands for searching the database.

All search commands in the cardant package provide automatic pagination. Searches are performed by beginning a search with a begin command which will yield the first page of results. Searches are then continued with next and previous commands which will return the next and previous pages of results, respectively. It is an error to try to execute a next or previous command without first having executed a begin command.

Each page of search results includes the number of the current page, and the number of pages of search results available. Attempting to seek beyond the end of the set of pages with a next command is not an error; the server will simply repeatedly return the last page in the set. Similarly, attempting to seek before the first page of results with a previous command will simply return the first page of results, repeatedly.

The search commands typically accept different filtering expressions to allow for very rich search capabilities. The syntactic forms of all the different expression types are listed in the following sections of the documentation, and can also be inspected using the syntax-list and syntax-show shell commands.

7.1.8.2. Name Matching

A name match expression is an expression used to filter search results. The expression is evaluated using the object's name as input and the object is included in search results if the expression evaluates to true.

An expression takes one of the following forms:

7.1.8.2.3. Forms

with-any-name

(with-name-equal-to n)

(with-name-not-equal-to n)

(with-name-similar-to n)

(with-name-not-similar-to n)

Expressions have the following semantics, given in terms of a match_name_evaluate function:

7.1.8.2.5. Semantics

match_name_evaluate with-any-name n                 ⇒ true
match_name_evaluate (with-name-equal-to m) n        ⇒ n = m
match_name_evaluate (with-name-not-equal-to m) n    ⇒ n ≠ m
match_name_evaluate (with-name-similar-to m) n      ⇒ n ≃ m
match_name_evaluate (with-name-not-similar-to m) n  ⇒ not (n ≃ m)

7.1.8.2.6. Semantics Explanation

An expression with-any-name always evaluates to true.

For all names m, (with-name-equal-to n) m evaluates to true iff m = n.

For all names m, (with-name-not-equal-to n) m evaluates to true iff m ≠ n.

For all names m, (with-name-similar-to n) m evaluates to true iff m is sufficiently similar to n according to an implementation-defined, language-specific similarity function.

For all names m, (with-name-not-similar-to n) m evaluates to true iff m is not sufficiently similar to n according to an implementation-defined, language-specific similarity function.

Specifically, the "similarity" function is currently implemented in terms of PostgreSQL's full text search functionality.

7.1.8.2.8. Syntax

match_name ::=
    "with-any-name"
  | "(" "with-name-equal-to" <name> ")"
  | "(" "with-name-not-equal-to" <name> ")"
  | "(" "with-name-similar-to" <string> ")"
  | "(" "with-name-not-similar-to" <string> ")"
  ;

7.1.8.3. Type Matching

A type match expression is an expression used to filter search results. The expression is evaluated using the object's set of types as input and the object is included in search results if the expression evaluates to true.

An expression takes one of the following forms:

7.1.8.3.3. Forms

with-any-types

(with-types-equal-to n)

(with-types-not-equal-to n)

(with-types-superset-of n)

(with-types-subset-of n)

(with-types-overlapping n)

Expressions have the following semantics, given in terms of a match_type_evaluate function:

7.1.8.3.5. Semantics

match_name_evaluate with-any-type s                 ⇒ true
match_name_evaluate (with-types-to t) s             ⇒ s = t
match_name_evaluate (with-types-not-equal-to t) s   ⇒ s ≠ t
match_name_evaluate (with-types-superset-of t) s    ⇒ s ⊆ t
match_name_evaluate (with-types-subset-of t) s      ⇒ s ⊇ t
match_name_evaluate (with-types-overlapping t) s    ⇒ ∃ e. e ∈ t ∧ e ∈ s

7.1.8.3.6. Semantics Explanation

An expression with-any-types always evaluates to true.

For all descriptions s, (with-types-equal-to t) s evaluates to true iff t = s. Note that sets are not ordered.

For all descriptions s, (with-types-not-equal-to t) s evaluates to true iff s ≠ t. Note that sets are not ordered.

For all descriptions s, (with-types-subset-of t) s evaluates to true iff s is a subset of t.

For all descriptions s, (with-types-superset-of t) s evaluates to true iff s is a superset of t.

For all descriptions s, (with-types-overlapping t) s evaluates to true iff there exists some element e that is present in both s and t.

7.1.8.3.7. Syntax

match_type ::=
    "with-any-type"
  | "(" "with-types-equal-to" <type-record-identifier> [<type-record-identifier>, ...] ")"
  | "(" "with-types-not-equal-to" <type-record-identifier> [<type-record-identifier>, ...] ")"
  | "(" "with-types-superset-of" <type-record-identifier> [<type-record-identifier>, ...] ")"
  | "(" "with-types-subset-of" <type-record-identifier> [<type-record-identifier>, ...] ")"
  | "(" "with-types-overlapping" <type-record-identifier> [<type-record-identifier>, ...] ")"
  ;

7.1.8.4. Description Matching

A description match expression is an expression used to filter search results. The expression is evaluated using the object's description as input and the object is included in search results if the expression evaluates to true.

An expression takes one of the following forms:

7.1.8.4.3. Forms

with-any-description

(with-description-equal-to n)

(with-description-not-equal-to n)

(with-description-similar-to n)

(with-description-not-similar-to n)

Expressions have the following semantics, given in terms of a match_description_evaluate function:

7.1.8.4.5. Semantics

match_description_evaluate with-any-description n                 ⇒ true
match_description_evaluate (with-description-equal-to m) n        ⇒ n = m
match_description_evaluate (with-description-not-equal-to m) n    ⇒ n ≠ m
match_description_evaluate (with-description-similar-to m) n      ⇒ n ≃ m
match_description_evaluate (with-description-not-similar-to m) n  ⇒ not (n ≃ m)

7.1.8.4.6. Semantics Explanation

An expression with-any-description always evaluates to true.

For all descriptions m, (with-description-equal-to n) m evaluates to true iff m = n.

For all descriptions m, (with-description-not-equal-to n) m evaluates to true iff m ≠ n.

For all descriptions m, (with-description-similar-to n) m evaluates to true iff m is sufficiently similar to n according to an implementation-defined, language-specific similarity function.

For all descriptions m, (with-description-not-similar-to n) m evaluates to true iff m is not sufficiently similar to n according to an implementation-defined, language-specific similarity function.

Specifically, the "similarity" function is currently implemented in terms of PostgreSQL's full text search functionality.

7.1.8.4.8. Syntax

match_description ::=
    "with-any-description"
  | "(" "with-description-equal-to" <description> ")"
  | "(" "with-description-not-equal-to" <description> ")"
  | "(" "with-description-similar-to" <string> ")"
  | "(" "with-description-not-similar-to" <string> ")"
  ;

7.1.8.5. Media Type Matching

A media type match expression is an expression used to filter search results. The expression is evaluated using the object's media type as input and the object is included in search results if the expression evaluates to true.

An expression takes one of the following forms:

7.1.8.5.3. Forms

with-any-mediatype

(with-mediatype-equal-to n)

(with-mediatype-not-equal-to n)

(with-mediatype-similar-to n)

(with-mediatype-not-similar-to n)

Expressions have the following semantics, given in terms of a match_mediatype_evaluate function:

7.1.8.5.5. Semantics

match_mediatype_evaluate with-any-mediatype n                 ⇒ true
match_mediatype_evaluate (with-mediatype-equal-to m) n        ⇒ n = m
match_mediatype_evaluate (with-mediatype-not-equal-to m) n    ⇒ n ≠ m
match_mediatype_evaluate (with-mediatype-similar-to m) n      ⇒ n ≃ m
match_mediatype_evaluate (with-mediatype-not-similar-to m) n  ⇒ not (n ≃ m)

7.1.8.5.6. Semantics Explanation

An expression with-any-mediatype always evaluates to true.

For all media types m, (with-mediatype-equal-to n) m evaluates to true iff m = n.

For all media types m, (with-mediatype-not-equal-to n) m evaluates to true iff m ≠ n.

For all media types m, (with-mediatype-similar-to n) m evaluates to true iff m is sufficiently similar to n according to an implementation-defined, language-specific similarity function.

For all media types m, (with-mediatype-not-similar-to n) m evaluates to true iff m is not sufficiently similar to n according to an implementation-defined, language-specific similarity function.

Specifically, the "similarity" function is currently implemented in terms of PostgreSQL's full text search functionality.

7.1.8.5.8. Syntax

match_mediatype ::=
    "with-any-mediatype"
  | "(" "with-mediatype-equal-to" <mediatype> ")"
  | "(" "with-mediatype-not-equal-to" <mediatype> ")"
  | "(" "with-mediatype-similar-to" <string> ")"
  | "(" "with-mediatype-not-similar-to" <string> ")"
  ;

7.1.8.6. Serial Matching

A serial match expression is an expression used to filter search results. The expression is evaluated using the object's serial number as input and the object is included in search results if the expression evaluates to true.

An expression takes one of the following forms:

7.1.8.6.3. Forms

with-any-serial

(with-serial-equal-to n)

(with-serial-not-equal-to n)

Expressions have the following semantics, given in terms of a match_serial_evaluate function:

7.1.8.6.5. Semantics

match_serial_evaluate with-any-serial n                 ⇒ true
match_serial_evaluate (with-serial-equal-to m) n        ⇒ n = m
match_serial_evaluate (with-serial-not-equal-to m) n    ⇒ n ≠ m

7.1.8.6.6. Semantics Explanation

An expression with-any-serial always evaluates to true.

For all descriptions m, (with-serial-equal-to n) m evaluates to true iff m = n.

For all descriptions m, (with-serial-not-equal-to n) m evaluates to true iff m ≠ n.

Specifically, the "similarity" function is currently implemented in terms of PostgreSQL's full text search functionality.

7.1.8.6.8. Syntax

match_serial ::=
    "with-any-serial"
  | "(" "with-serial-equal-to" <serial> ")"
  | "(" "with-serial-not-equal-to" <serial> ")"
  ;

7.1.8.7. Package Matching

A package match expression is an expression used to filter search results. The expression is evaluated using the object's type package as input and the object is included in search results if the expression evaluates to true.

An expression takes one of the following forms:

7.1.8.7.3. Forms

with-any-package

(with-package-equal-to n)

(with-package-not-equal-to n)

Expressions have the following semantics, given in terms of a match_package_evaluate function:

7.1.8.7.5. Semantics

match_package_evaluate with-any-package n                 ⇒ true
match_package_evaluate (with-package-equal-to m) n        ⇒ n = m
match_package_evaluate (with-package-not-equal-to m) n    ⇒ n ≠ m

7.1.8.7.6. Semantics Explanation

An expression with-any-package always evaluates to true.

For all descriptions m, (with-package-equal-to n) m evaluates to true iff m = n.

For all descriptions m, (with-package-not-equal-to n) m evaluates to true iff m ≠ n.

7.1.8.7.7. Syntax

match_package ::=
    "with-any-package"
  | "(" "with-package-equal-to" <package> ")"
  | "(" "with-package-not-equal-to" <package> ")"
  ;

7.1.8.8. Field Matching

A field match expression is an expression used to filter search results. The expression is evaluated using the object's field name as input and the object is included in search results if the expression evaluates to true.

An expression takes one of the following forms:

7.1.8.8.3. Forms

with-any-field

(with-field-equal-to n)

(with-field-not-equal-to n)

Expressions have the following semantics, given in terms of a match_field_evaluate function:

7.1.8.8.5. Semantics

match_field_evaluate with-any-field n                 ⇒ true
match_field_evaluate (with-field-equal-to m) n        ⇒ n = m
match_field_evaluate (with-field-not-equal-to m) n    ⇒ n ≠ m

7.1.8.8.6. Semantics Explanation

An expression with-any-field always evaluates to true.

For all descriptions m, (with-field-equal-to n) m evaluates to true iff m = n.

For all descriptions m, (with-field-not-equal-to n) m evaluates to true iff m ≠ n.

7.1.8.8.7. Syntax

match_field ::=
    "with-any-field"
  | "(" "with-field-equal-to" <type-record-field-identifier> ")"
  | "(" "with-field-not-equal-to" <type-record-field-identifier> ")"
  ;

7.2. Shell Command Reference

7.2.1. audit-search-begin

7.2.1.1. Name

7.2.1.2. Description

7.2.1.3. Parameters

7.2.1.4. Examples

7.2.2. audit-search-next

7.2.2.1. Name

7.2.2.2. Description

7.2.3. audit-search-previous

7.2.3.1. Name

7.2.3.2. Description

7.2.4. bookmark-list

7.2.4.1. Name

7.2.4.2. Description

7.2.5. bookmark-login

7.2.5.1. Name

7.2.5.2. Description

7.2.5.3. Parameters

7.2.6. bookmark-put

7.2.6.1. Name

7.2.6.2. Description

7.2.6.3. Parameters

7.2.7. bookmark-remove

7.2.7.1. Name

7.2.7.2. Description

7.2.7.3. Parameters

7.2.8. file-get

7.2.8.1. Name

7.2.8.2. Description

7.2.8.3. Parameters

7.2.9. file-put

7.2.9.1. Name

7.2.9.2. Description

7.2.9.3. Parameters

7.2.10. file-search-begin

7.2.10.1. Name

7.2.10.2. Description

7.2.10.3. Parameters

7.2.11. file-search-next

7.2.11.1. Name

7.2.11.2. Description

7.2.12. file-search-previous

7.2.12.1. Name

7.2.12.2. Description

7.2.13. files-recent

7.2.13.1. Name

7.2.13.2. Description

7.2.14. help

7.2.14.1. Name

7.2.14.2. Description

7.2.14.3. Examples

7.2.15. item-attachment-add

7.2.15.1. Name

7.2.15.2. Description

7.2.15.3. Parameters

7.2.16. item-attachment-remove

7.2.16.1. Name

7.2.16.2. Description

7.2.16.3. Parameters

7.2.17. item-create

7.2.17.1. Name

7.2.17.2. Description

7.2.17.3. Parameters

7.2.18. item-get

7.2.18.1. Name

7.2.18.2. Description

7.2.18.3. Parameters

7.2.19. item-metadata-put

7.2.19.1. Name

7.2.19.2. Description

7.2.19.3. Parameters

7.2.20. item-metadata-remove

7.2.20.1. Name

7.2.20.2. Description

7.2.20.3. Parameters

7.2.21. item-search-begin

7.2.21.1. Name

7.2.21.2. Description

7.2.21.3. Parameters

7.2.22. item-search-next

7.2.22.1. Name

7.2.22.2. Description

7.2.23. item-search-previous

7.2.23.1. Name

7.2.23.2. Description

7.2.24. item-types-assign

7.2.24.1. Name

7.2.24.2. Description

7.2.24.3. Parameters

7.2.25. item-types-revoke

7.2.25.1. Name

7.2.25.2. Description

7.2.25.3. Parameters

7.2.26. location-attachment-add

7.2.26.1. Name

7.2.26.2. Description

7.2.26.3. Parameters

7.2.27. location-attachment-remove

7.2.27.1. Name

7.2.27.2. Description

7.2.27.3. Parameters

7.2.28. location-get

7.2.28.1. Name

7.2.28.2. Description

7.2.28.3. Parameters

7.2.29. location-list

7.2.29.1. Name

7.2.29.2. Description

7.2.30. location-put

7.2.30.1. Name

7.2.30.2. Description

7.2.30.3. Parameters

7.2.31. login

7.2.31.1. Name

7.2.31.2. Description

7.2.32. logout

7.2.32.1. Name

7.2.32.2. Description

7.2.33. roles-assign

7.2.33.1. Name

7.2.33.2. Description

7.2.33.3. Parameters

7.2.34. roles-get

7.2.34.1. Name

7.2.34.2. Description

7.2.34.3. Parameters

7.2.35. roles-revoke

7.2.35.1. Name

7.2.35.2. Description

7.2.35.3. Parameters

7.2.36. self

7.2.36.1. Name

7.2.36.2. Description

7.2.36.3. Examples

7.2.37. set

7.2.37.1. Name

7.2.37.2. Description

7.2.37.3. Parameters

7.2.38. stock-reposit-remove

7.2.38.1. Name

7.2.38.2. Description

7.2.38.3. Parameters

7.2.38.4. Examples

7.2.39. stock-reposit-serial-introduce

7.2.39.1. Name

7.2.39.2. Description

7.2.39.3. Parameters

7.2.39.4. Examples

7.2.40. stock-reposit-serial-move

7.2.40.1. Name

7.2.40.2. Description

7.2.40.3. Parameters

7.2.40.4. Examples

7.2.41. stock-reposit-serial-number-add

7.2.41.1. Name

7.2.41.2. Description

7.2.41.3. Parameters

7.2.41.4. Examples

7.2.42. stock-reposit-serial-number-remove

7.2.42.1. Name

7.2.42.2. Description

7.2.42.3. Parameters

7.2.42.4. Examples

7.2.43. stock-reposit-set-add

7.2.43.1. Name

7.2.43.2. Description

7.2.43.3. Parameters

7.2.43.4. Examples

7.2.44. stock-reposit-set-introduce

7.2.44.1. Name

7.2.44.2. Description

7.2.44.3. Parameters

7.2.44.4. Examples

7.2.45. stock-reposit-set-move

7.2.45.1. Name

7.2.45.2. Description

7.2.45.3. Parameters

7.2.45.4. Examples

7.2.46. stock-reposit-set-remove

7.2.46.1. Name

7.2.46.2. Description

7.2.46.3. Parameters

7.2.46.4. Examples

7.2.47. stock-search-begin

7.2.47.1. Name

7.2.47.2. Description

7.2.47.3. Parameters

7.2.47.4. Examples

7.2.48. stock-search-next

7.2.48.1. Name

7.2.48.2. Description

7.2.48.3. Examples

7.2.49. stock-search-previous

7.2.49.1. Name

7.2.49.2. Description

7.2.49.3. Examples

7.2.50. syntax-list

7.2.50.1. Name

7.2.50.2. Description

7.2.50.3. Examples

7.2.50.4. Parameters

7.2.51. syntax-show

7.2.51.1. Name

7.2.51.2. Description

7.2.51.3. Examples

7.2.51.4. Parameters

7.2.52. type-package-get-text

7.2.52.1. Name

7.2.52.2. Description

7.2.52.3. Parameters

7.2.52.4. Examples

7.2.53. type-package-install

7.2.53.1. Name

7.2.53.2. Description

7.2.53.3. Parameters

7.2.54. type-package-schema

7.2.54.1. Name

7.2.54.2. Description

7.2.54.3. Parameters

7.2.54.4. Examples

7.2.55. type-package-search-begin

7.2.55.1. Name

7.2.55.2. Description

7.2.55.3. Parameters

7.2.56. type-package-search-next

7.2.56.1. Name

7.2.56.2. Description

7.2.57. type-package-search-previous

7.2.57.1. Name

7.2.57.2. Description

7.2.58. type-package-uninstall

7.2.58.1. Name

7.2.58.2. Description

7.2.58.3. Parameters

7.2.59. type-package-upgrade

7.2.59.1. Name

7.2.59.2. Description

7.2.59.3. Parameters

7.2.60. version

7.2.60.1. Name

7.2.60.2. Description

7.2.60.3. Examples

7.2.1. audit-search-begin

7.2.1.1. Name

7.2.1.2. Description

7.2.1.3. Parameters

7.2.1.4. Examples

7.2.1.1. Name

audit-search-begin - Begin searching for audit records.

7.2.1.2. Description

The audit-search-begin command begins searching for audit records.

7.2.1.3. Parameters

7.2.1.3.1. --limit

Attribute | Value
Name | --limit
Type | java.lang.Integer
Default Value | 10
Cardinality | [1, 1]
Description | The maximum number of results per page.

7.2.1.3.2. --time-from

Attribute | Value
Name | --time-from
Type | java.time.OffsetDateTime
Default Value | 1970-01-01T00:00Z
Cardinality | [1, 1]
Description | Return audit events later than this date.

7.2.1.3.3. --time-to

Attribute | Value
Name | --time-to
Type | java.time.OffsetDateTime
Default Value | +101970-01-01T00:00Z
Cardinality | [1, 1]
Description | Return audit events earlier than this date.

7.2.1.3.4. --type-equal-to

Attribute | Value
Name | --type-equal-to
Type | java.lang.String
Default Value |
Cardinality | [0, 1]
Description | Filter events by type.

7.2.1.3.5. --type-not-equal-to

Attribute | Value
Name | --type-not-equal-to
Type | java.lang.String
Default Value |
Cardinality | [0, 1]
Description | Filter events by type.

7.2.1.3.6. --user

Attribute | Value
Name | --user
Type | com.io7m.cardant.model.CAUserID
Default Value |
Cardinality | [0, 1]
Description | Filter events by user.

7.2.1.4. Examples

7.2.1.4.1. Example

$ audit-search-begin
Search results: Page 1 of 1
┌────┬──────────────────────────────────────┬────────────────┬─────────────────────────────┬─────────────────────────────────────────────────────────────────────────┐
│ ID │ Owner                                │ Type           │ Time                        │ Data                                                                    │
├────┼──────────────────────────────────────┼────────────────┼─────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ 1  │ c5574d46-7413-43c8-b6db-31001c382ca3 │ USER_LOGGED_IN │ 2023-12-21T11:30:11.171839Z │ {UserAgent=com.io7m.cardant.client/0.0.1-SNAPSHOT, Host=10.1.6.1:53236} │
└────┴──────────────────────────────────────┴────────────────┴─────────────────────────────┴─────────────────────────────────────────────────────────────────────────┘

7.2.2. audit-search-next

7.2.2.1. Name

7.2.2.2. Description

7.2.2.1. Name

audit-search-next - Go to the next page of audit events.

7.2.2.2. Description

The audit-search-next command goes to the next page of audit events.

The command can only be used after the associated begin command.

7.2.3. audit-search-previous

7.2.3.1. Name

7.2.3.2. Description

7.2.3.1. Name

audit-search-previous - Go to the previous page of audit events.

7.2.3.2. Description

The audit-search-previous command goes to the previous page of audit events.

The command can only be used after the associated begin command.

7.2.4. bookmark-list

7.2.4.1. Name

7.2.4.2. Description

7.2.4.1. Name

bookmark-list - List server bookmarks.

7.2.4.2. Description

The bookmark-list command lists the local server bookmarks.

7.2.5. bookmark-login

7.2.5.1. Name

7.2.5.2. Description

7.2.5.3. Parameters

7.2.5.1. Name

bookmark-login - Log in using a bookmark.

7.2.5.2. Description

The bookmark-login command logs into a server using a bookmark.

7.2.5.3. Parameters

7.2.5.3.1. --name

Attribute | Value
Name | --name
Type | java.lang.String
Default Value |
Cardinality | [0, 1]
Description | The name of the bookmark.

7.2.6. bookmark-put

7.2.6.1. Name

7.2.6.2. Description

7.2.6.3. Parameters

7.2.6.1. Name

bookmark-put - Create or update a server bookmark.

7.2.6.2. Description

The bookmark-put command creates or updates a bookmark.

7.2.6.3. Parameters

7.2.6.3.1. --hostname

Attribute | Value
Name | --hostname
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The hostname of the server.

7.2.6.3.2. --name

Attribute | Value
Name | --name
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The name of the bookmark.

7.2.6.3.3. --password

Attribute | Value
Name | --password
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The password for the server.

7.2.6.3.4. --port

Attribute | Value
Name | --port
Type | java.lang.Integer
Default Value | 30000
Cardinality | [1, 1]
Description | The port used for the server.

7.2.6.3.5. --tls

Attribute | Value
Name | --tls
Type | java.lang.Boolean
Default Value | false
Cardinality | [1, 1]
Description | Whether to use TLS to connect to the server.

7.2.6.3.6. --user

Attribute | Value
Name | --user
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The username for the server.

7.2.7. bookmark-remove

7.2.7.1. Name

7.2.7.2. Description

7.2.7.3. Parameters

7.2.7.1. Name

bookmark-remove - Remove a server bookmark.

7.2.7.2. Description

The bookmark-remove command removes a bookmark.

7.2.7.3. Parameters

7.2.7.3.1. --name

Attribute | Value
Name | --name
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The name of the bookmark.

7.2.8. file-get

7.2.8.1. Name

7.2.8.2. Description

7.2.8.3. Parameters

7.2.8.1. Name

file-get - Download a file.

7.2.8.2. Description

The file-get command downloads a file from the server.

7.2.8.3. Parameters

7.2.8.3.1. --download-to

Attribute | Value
Name | --download-to
Type | java.nio.file.Path
Default Value |
Cardinality | [0, 1]
Description | If specified, the file will be downloaded to this path.

7.2.8.3.2. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAFileID
Default Value |
Cardinality | [1, 1]
Description | The file ID.

7.2.9. file-put

7.2.9.1. Name

7.2.9.2. Description

7.2.9.3. Parameters

7.2.9.1. Name

file-put - Upload a file.

7.2.9.2. Description

The file-put command creates or updates a file on the server.

7.2.9.3. Parameters

7.2.9.3.1. --content-type

Attribute | Value
Name | --content-type
Type | java.lang.String
Default Value |
Cardinality | [0, 1]
Description | The content type (inferred if not specified).

7.2.9.3.2. --description

Attribute | Value
Name | --description
Type | java.lang.String
Default Value |
Cardinality | [0, 1]
Description | The file description.

7.2.9.3.3. --file

Attribute | Value
Name | --file
Type | java.nio.file.Path
Default Value |
Cardinality | [1, 1]
Description | The file.

7.2.9.3.4. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAFileID
Default Value |
Cardinality | [1, 1]
Description | The file ID.

7.2.10. file-search-begin

7.2.10.1. Name

7.2.10.2. Description

7.2.10.3. Parameters

7.2.10.1. Name

file-search-begin - Start searching for files.

7.2.10.2. Description

The file-search-begin command begins searching for files on the server.

Files can be filtered based on matching their media types against a given media type match expression.

Files can be filtered based on matching their descriptions against a given description match expression.

7.2.10.3. Parameters

7.2.10.3.1. --description-match

Attribute | Value
Name | --description-match
Type | com.io7m.cardant.model.CADescriptionMatch
Default Value | with-any-description
Cardinality | [1, 1]
Description | Only include files that have descriptions matching the given expression.

7.2.10.3.2. --limit

Attribute | Value
Name | --limit
Type | java.lang.Long
Default Value | 100
Cardinality | [1, 1]
Description | The maximum number of results per page.

7.2.10.3.3. --mediatype-match

Attribute | Value
Name | --mediatype-match
Type | com.io7m.cardant.model.CAMediaTypeMatch
Default Value | with-any-mediatype
Cardinality | [1, 1]
Description | Only include files that have media types matching the given expression.

7.2.10.3.4. --size-maximum

Attribute | Value
Name | --size-maximum
Type | java.lang.Long
Default Value | 9223372036854775807
Cardinality | [1, 1]
Description | The maximum file size.

7.2.10.3.5. --size-minimum

Attribute | Value
Name | --size-minimum
Type | java.lang.Long
Default Value | 0
Cardinality | [1, 1]
Description | The minimum file size.

7.2.11. file-search-next

7.2.11.1. Name

7.2.11.2. Description

7.2.11.1. Name

file-search-next - Go to the next page of files.

7.2.11.2. Description

The file-search-next command goes to the next page of file search results.

The command can only be used after the associated begin command.

7.2.12. file-search-previous

7.2.12.1. Name

7.2.12.2. Description

7.2.12.1. Name

file-search-previous - Go to the previous page of files.

7.2.12.2. Description

The file-search-previous command goes to the previous page of file search results.

The command can only be used after the associated begin command.

7.2.13. files-recent

7.2.13.1. Name

7.2.13.2. Description

7.2.13.1. Name

files-recent - List the recent files.

7.2.13.2. Description

The files-recent command lists the files recently used by shell commands such as file-put.

7.2.14. help

7.2.14.1. Name

7.2.14.2. Description

7.2.14.3. Examples

7.2.14.1. Name

help - Display help for a given command.

7.2.14.2. Description

The help command displays help for the given command.

7.2.14.3. Examples

7.2.14.3.1. Example

[cardant]$ help file-put
cardant: usage: file-put [named-arguments ...]

  Upload a file.

  Named parameters:
    --content-type
      Description       : The content type (inferred if not specified).
      Type              : String
      Cardinality       : [0, 1]; Specify at most once.
      Syntax            : <any sequence of characters>
    --description
      Description       : The file description.
      Type              : String
      Cardinality       : [0, 1]; Specify at most once.
      Syntax            : <any sequence of characters>
  * --file
      Description       : The file.
      Type              : Path
      Cardinality       : [1]; Specify exactly once.
      Syntax            : <platform-specific path syntax>
  * --id
      Description       : The file ID.
      Type              : CAFileID
      Cardinality       : [1]; Specify exactly once.
      Syntax            : [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}

  The command does not accept any positional arguments.

7.2.15. item-attachment-add

7.2.15.1. Name

7.2.15.2. Description

7.2.15.3. Parameters

7.2.15.1. Name

item-attachment-add - Add or update an attachment on an item.

7.2.15.2. Description

The item-attachment-add command adds an attachment to an item.

7.2.15.3. Parameters

7.2.15.3.1. --file-id

Attribute | Value
Name | --file-id
Type | com.io7m.cardant.model.CAFileID
Default Value |
Cardinality | [1, 1]
Description | The file ID.

7.2.15.3.2. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.15.3.3. --relation

Attribute | Value
Name | --relation
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The attachment relation.

7.2.16. item-attachment-remove

7.2.16.1. Name

7.2.16.2. Description

7.2.16.3. Parameters

7.2.16.1. Name

item-attachment-remove - Remove an attachment from an item.

7.2.16.2. Description

The item-attachment-remove command removes an attachment from an item.

7.2.16.3. Parameters

7.2.16.3.1. --file-id

Attribute | Value
Name | --file-id
Type | com.io7m.cardant.model.CAFileID
Default Value |
Cardinality | [1, 1]
Description | The file ID.

7.2.16.3.2. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.16.3.3. --relation

Attribute | Value
Name | --relation
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The attachment relation.

7.2.17. item-create

7.2.17.1. Name

7.2.17.2. Description

7.2.17.3. Parameters

7.2.17.1. Name

item-create - Create an item.

7.2.17.2. Description

The item-create command creates a new item.

7.2.17.3. Parameters

7.2.17.3.1. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [0, 1]
Description | The item ID.

7.2.17.3.2. --name

Attribute | Value
Name | --name
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The item name.

7.2.18. item-get

7.2.18.1. Name

7.2.18.2. Description

7.2.18.3. Parameters

7.2.18.1. Name

item-get - Retrieve an item.

7.2.18.2. Description

The item-get command retrieves an item.

7.2.18.3. Parameters

7.2.18.3.1. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.19. item-metadata-put

7.2.19.1. Name

7.2.19.2. Description

7.2.19.3. Parameters

7.2.19.1. Name

item-metadata-put - Add or update metadata on an item.

7.2.19.2. Description

The item-metadata-put command adds or updates metadata on an item.

7.2.19.3. Parameters

7.2.19.3.1. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.19.3.2. --metadata

Attribute | Value
Name | --metadata
Type | com.io7m.cardant.model.CAMetadataType
Default Value | []
Cardinality | [0, N]
Description | The metadata key.

7.2.20. item-metadata-remove

7.2.20.1. Name

7.2.20.2. Description

7.2.20.3. Parameters

7.2.20.1. Name

item-metadata-remove - Remove metadata from an item.

7.2.20.2. Description

The item-metadata-remove command removes metadata from an item.

7.2.20.3. Parameters

7.2.20.3.1. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.20.3.2. --key

Attribute | Value
Name | --key
Type | com.io7m.cardant.model.CATypeRecordFieldIdentifier
Default Value | []
Cardinality | [1, N]
Description | The metadata key.

7.2.21. item-search-begin

7.2.21.1. Name

7.2.21.2. Description

7.2.21.3. Parameters

7.2.21.1. Name

item-search-begin - Start searching for items.

7.2.21.2. Description

The item-search-begin command begins searching for items.

Items can be filtered based on matching their names against a given name match expression.

Items can be filtered based on matching their descriptions against a given description match expression.

Items can be filtered based on matching their types against a given type match expression.

7.2.21.3. Parameters

7.2.21.3.1. --description-match

Attribute | Value
Name | --description-match
Type | com.io7m.cardant.model.CADescriptionMatch
Default Value | with-any-description
Cardinality | [1, 1]
Description | Only include items that have descriptions matching the given expression.

7.2.21.3.2. --limit

Attribute | Value
Name | --limit
Type | java.lang.Integer
Default Value | 100
Cardinality | [1, 1]
Description | The maximum number of results per page.

7.2.21.3.3. --location-match

Attribute | Value
Name | --location-match
Type | com.io7m.cardant.model.CALocationMatchType
Default Value | any-location
Cardinality | [1, 1]
Description | Only include items in locations matching the given expression.

7.2.21.3.4. --metadata-match

Attribute | Value
Name | --metadata-match
Type | com.io7m.cardant.model.CAMetadataElementMatchType
Default Value | anything
Cardinality | [1, 1]
Description | Only include items with metadata matching the given expression.

7.2.21.3.5. --name-match

Attribute | Value
Name | --name-match
Type | com.io7m.cardant.model.CANameMatchFuzzy
Default Value | with-any-name
Cardinality | [1, 1]
Description | Only include items that have names matching the given expression.

7.2.21.3.6. --serial-match

Attribute | Value
Name | --serial-match
Type | com.io7m.cardant.model.CAItemSerialMatch
Default Value | with-any-serial
Cardinality | [1, 1]
Description | Only include items with serial numbers matching the given expression.

7.2.21.3.7. --type-match

Attribute | Value
Name | --type-match
Type | com.io7m.cardant.model.CATypeMatch
Default Value | with-any-type
Cardinality | [1, 1]
Description | Only include items that have types matching the given expression.

7.2.22. item-search-next

7.2.22.1. Name

7.2.22.2. Description

7.2.22.1. Name

item-search-next - Go to the next page of items.

7.2.22.2. Description

The item-search-next command goes to the next page of item search results.

The command can only be used after the associated begin command.

7.2.23. item-search-previous

7.2.23.1. Name

7.2.23.2. Description

7.2.23.1. Name

item-search-previous - Go to the previous page of items.

7.2.23.2. Description

The item-search-previous command goes to the previous page of item search results.

The command can only be used after the associated begin command.

7.2.24. item-types-assign

7.2.24.1. Name

7.2.24.2. Description

7.2.24.3. Parameters

7.2.24.1. Name

item-types-assign - Assign types to an item.

7.2.24.2. Description

The item-types-assign command assigns types to an item.

7.2.24.3. Parameters

7.2.24.3.1. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.24.3.2. --type

Attribute | Value
Name | --type
Type | com.io7m.cardant.model.CATypeRecordIdentifier
Default Value | []
Cardinality | [0, N]
Description | The item types.

7.2.25. item-types-revoke

7.2.25.1. Name

7.2.25.2. Description

7.2.25.3. Parameters

7.2.25.1. Name

item-types-revoke - Revoke types from an item.

7.2.25.2. Description

The item-types-revoke command revokes types from an item.

7.2.25.3. Parameters

7.2.25.3.1. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.25.3.2. --type

Attribute | Value
Name | --type
Type | com.io7m.cardant.model.CATypeRecordIdentifier
Default Value | []
Cardinality | [0, N]
Description | The item types.

7.2.26. location-attachment-add

7.2.26.1. Name

7.2.26.2. Description

7.2.26.3. Parameters

7.2.26.1. Name

location-attachment-add - Add or update an attachment on an location.

7.2.26.2. Description

The location-attachment-add command adds an attachment to a location.

7.2.26.3. Parameters

7.2.26.3.1. --file-id

Attribute | Value
Name | --file-id
Type | com.io7m.cardant.model.CAFileID
Default Value |
Cardinality | [1, 1]
Description | The file ID.

7.2.26.3.2. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [1, 1]
Description | The location ID.

7.2.26.3.3. --relation

Attribute | Value
Name | --relation
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The attachment relation.

7.2.27. location-attachment-remove

7.2.27.1. Name

7.2.27.2. Description

7.2.27.3. Parameters

7.2.27.1. Name

location-attachment-remove - Remove an attachment from an location.

7.2.27.2. Description

The location-attachment-remove command removes an attachment from a location.

7.2.27.3. Parameters

7.2.27.3.1. --file-id

Attribute | Value
Name | --file-id
Type | com.io7m.cardant.model.CAFileID
Default Value |
Cardinality | [1, 1]
Description | The file ID.

7.2.27.3.2. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [1, 1]
Description | The location ID.

7.2.27.3.3. --relation

Attribute | Value
Name | --relation
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The attachment relation.

7.2.28. location-get

7.2.28.1. Name

7.2.28.2. Description

7.2.28.3. Parameters

7.2.28.1. Name

location-get - Retrieve a location.

7.2.28.2. Description

The location-get command retrieves a location.

7.2.28.3. Parameters

7.2.28.3.1. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [1, 1]
Description | The location ID.

7.2.29. location-list

7.2.29.1. Name

7.2.29.2. Description

7.2.29.1. Name

location-list - List locations.

7.2.29.2. Description

The location-list command lists locations.

7.2.30. location-put

7.2.30.1. Name

7.2.30.2. Description

7.2.30.3. Parameters

7.2.30.1. Name

location-put - Create or update a location.

7.2.30.2. Description

The location-put command creates or updates a location.

7.2.30.3. Parameters

7.2.30.3.1. --detach

Attribute | Value
Name | --detach
Type | java.lang.Boolean
Default Value |
Cardinality | [0, 1]
Description | Detach the location from its parent.

7.2.30.3.2. --id

Attribute | Value
Name | --id
Type | com.io7m.cardant.model.CALocationID
Default Value | d37d0dd8-8f98-4f55-80f7-752471271bb3
Cardinality | [1, 1]
Description | The location ID.

7.2.30.3.3. --name

Attribute | Value
Name | --name
Type | java.lang.String
Default Value |
Cardinality | [0, 1]
Description | The location name.

7.2.30.3.4. --parent

Attribute | Value
Name | --parent
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [0, 1]
Description | The parent location ID.

7.2.31. login

7.2.31.1. Name

7.2.31.2. Description

7.2.31.1. Name

login - Log in.

7.2.31.2. Description

The login command logs in.

7.2.32. logout

7.2.32.1. Name

7.2.32.2. Description

7.2.32.1. Name

logout - Log out.

7.2.32.2. Description

The logout command logs out.

7.2.33. roles-assign

7.2.33.1. Name

7.2.33.2. Description

7.2.33.3. Parameters

7.2.33.1. Name

roles-assign - Assign roles to the given user.

7.2.33.2. Description

The roles-assign command assigns roles to a user.

7.2.33.3. Parameters

7.2.33.3.1. --role

Attribute | Value
Name | --role
Type | com.io7m.medrina.api.MRoleName
Default Value | []
Cardinality | [0, N]
Description | The role name.

7.2.33.3.2. --user

Attribute | Value
Name | --user
Type | com.io7m.cardant.model.CAUserID
Default Value |
Cardinality | [1, 1]
Description | The user ID.

7.2.34. roles-get

7.2.34.1. Name

7.2.34.2. Description

7.2.34.3. Parameters

7.2.34.1. Name

roles-get - Return the set of roles held by the given user.

7.2.34.2. Description

The roles-get command retrieves roles for a user.

7.2.34.3. Parameters

7.2.34.3.1. --user

Attribute | Value
Name | --user
Type | com.io7m.cardant.model.CAUserID
Default Value |
Cardinality | [1, 1]
Description | The user ID.

7.2.35. roles-revoke

7.2.35.1. Name

7.2.35.2. Description

7.2.35.3. Parameters

7.2.35.1. Name

roles-revoke - Revoke roles from the given user.

7.2.35.2. Description

The roles-revoke command revokes roles from a user.

7.2.35.3. Parameters

7.2.35.3.1. --role

Attribute | Value
Name | --role
Type | com.io7m.medrina.api.MRoleName
Default Value | []
Cardinality | [0, N]
Description | The role name.

7.2.35.3.2. --user

Attribute | Value
Name | --user
Type | com.io7m.cardant.model.CAUserID
Default Value |
Cardinality | [1, 1]
Description | The user ID.

7.2.36. self

7.2.36.1. Name

7.2.36.2. Description

7.2.36.3. Examples

7.2.36.1. Name

self - Return details about the current user.

7.2.36.2. Description

The self command returns the current user's ID and roles.

7.2.36.3. Examples

7.2.36.3.1. Example

[cardant]$ self
User ID: c5574d46-7413-43c8-b6db-31001c382ca3
┌────────────────────────────────────────────────────────────────────────────────┐
│ Role                                                                           │
├────────────────────────────────────────────────────────────────────────────────┤
│ audit.reader                                                                   │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.admin                                                                │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.files.reader                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.files.writer                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.items.reader                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.items.writer                                                         │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.locations.reader                                                     │
├────────────────────────────────────────────────────────────────────────────────┤
│ inventory.locations.writer                                                     │
└────────────────────────────────────────────────────────────────────────────────┘

7.2.37. set

7.2.37.1. Name

7.2.37.2. Description

7.2.37.3. Parameters

7.2.37.1. Name

set - Set shell options.

7.2.37.2. Description

The set command sets shell options.

7.2.37.3. Parameters

7.2.37.3.1. --formatter

Attribute | Value
Name | --formatter
Type | com.io7m.cardant.shell.internal.CAShellCmdSet.Formatter
Default Value |
Cardinality | [0, 1]
Description | Set the shell formatter.

7.2.37.3.2. --terminate-on-errors

Attribute | Value
Name | --terminate-on-errors
Type | java.lang.Boolean
Default Value |
Cardinality | [0, 1]
Description | Terminate execution on the first command that returns an error.

7.2.38. stock-reposit-remove

7.2.38.1. Name

7.2.38.2. Description

7.2.38.3. Parameters

7.2.38.4. Examples

7.2.38.1. Name

stock-reposit-remove - Remove a stock instance.

7.2.38.2. Description

The stock-reposit-remove command removes stock instances.

7.2.38.3. Parameters

7.2.38.3.1. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.38.4. Examples

7.2.38.4.1. Example

[cardant]$ stock-reposit-remove --instance 3cb641ac-182f-4f44-98f6-a3e0fe752297

7.2.39. stock-reposit-serial-introduce

7.2.39.1. Name

7.2.39.2. Description

7.2.39.3. Parameters

7.2.39.4. Examples

7.2.39.1. Name

stock-reposit-serial-introduce - Add an instance of an item to a location.

7.2.39.2. Description

The stock-reposit-serial-introduce command introduces serial stock instances.

7.2.39.3. Parameters

7.2.39.3.1. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.39.3.2. --item

Attribute | Value
Name | --item
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.39.3.3. --location

Attribute | Value
Name | --location
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [1, 1]
Description | The location ID.

7.2.39.3.4. --serial

Attribute | Value
Name | --serial
Type | com.io7m.cardant.model.CAItemSerial
Default Value |
Cardinality | [1, 1]
Description | The item serial number.

7.2.39.4. Examples

7.2.39.4.1. Example

[cardant]$ stock-reposit-serial-introduce \
  --instance 3cb641ac-182f-4f44-98f6-a3e0fe752297 \
  --item 98725a33-5202-4143-820e-75b60a1df4d3 \
  --location 2bbc8132-cae3-4d51-95a0-0ab5318b3745 \
  --serial manufacturer_serial:91FA61CC

7.2.40. stock-reposit-serial-move

7.2.40.1. Name

7.2.40.2. Description

7.2.40.3. Parameters

7.2.40.4. Examples

7.2.40.1. Name

stock-reposit-serial-move - Move an instance of an item between locations.

7.2.40.2. Description

The stock-reposit-serial-move command moves serial stock instances.

7.2.40.3. Parameters

7.2.40.3.1. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.40.3.2. --location-to

Attribute | Value
Name | --location-to
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [1, 1]
Description | The destination location ID.

7.2.40.4. Examples

7.2.40.4.1. Example

[cardant]$ stock-reposit-serial-move \
  --instance 3cb641ac-182f-4f44-98f6-a3e0fe752297 \
  --location-to 2bbc8132-cae3-4d51-95a0-0ab5318b3745

7.2.41. stock-reposit-serial-number-add

7.2.41.1. Name

7.2.41.2. Description

7.2.41.3. Parameters

7.2.41.4. Examples

7.2.41.1. Name

stock-reposit-serial-number-add - Add a serial number to a stock instance.

7.2.41.2. Description

The stock-reposit-serial-number-add command adds serial numbers to a serial stock instance.

7.2.41.3. Parameters

7.2.41.3.1. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.41.3.2. --serial

Attribute | Value
Name | --serial
Type | com.io7m.cardant.model.CAItemSerial
Default Value |
Cardinality | [1, 1]
Description | The item serial number.

7.2.41.4. Examples

7.2.41.4.1. Example

[cardant]$ stock-reposit-serial-number-add \
  --instance 3cb641ac-182f-4f44-98f6-a3e0fe752297 \
  --serial manufacturer_serial:33CBE10A

7.2.42. stock-reposit-serial-number-remove

7.2.42.1. Name

7.2.42.2. Description

7.2.42.3. Parameters

7.2.42.4. Examples

7.2.42.1. Name

stock-reposit-serial-number-remove - Remove a serial number from a stock instance.

7.2.42.2. Description

The stock-reposit-serial-number-remove command removes serial numbers from stock instances.

7.2.42.3. Parameters

7.2.42.3.1. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.42.3.2. --serial

Attribute | Value
Name | --serial
Type | com.io7m.cardant.model.CAItemSerial
Default Value |
Cardinality | [1, 1]
Description | The item serial number.

7.2.42.4. Examples

7.2.42.4.1. Example

[cardant]$ stock-reposit-serial-number-remove \
  --instance 3cb641ac-182f-4f44-98f6-a3e0fe752297 \
  --serial manufacturer_serial:33CBE10A

7.2.43. stock-reposit-set-add

7.2.43.1. Name

7.2.43.2. Description

7.2.43.3. Parameters

7.2.43.4. Examples

7.2.43.1. Name

stock-reposit-set-add - Add stock instances to locations.

7.2.43.2. Description

The stock-reposit-set-add command adds more items to existing set stock instances.

7.2.43.3. Parameters

7.2.43.3.1. --count

Attribute | Value
Name | --count
Type | java.lang.Long
Default Value |
Cardinality | [1, 1]
Description | The number of instances of the item to add.

7.2.43.3.2. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.43.4. Examples

7.2.43.4.1. Example

[cardant]$ stock-reposit-set-add \
  --instance 3cb641ac-182f-4f44-98f6-a3e0fe752297 \
  --count 100

7.2.44. stock-reposit-set-introduce

7.2.44.1. Name

7.2.44.2. Description

7.2.44.3. Parameters

7.2.44.4. Examples

7.2.44.1. Name

stock-reposit-set-introduce - Introduces instances of items to locations.

7.2.44.2. Description

The stock-reposit-set-introduce command creates set stock instances.

7.2.44.3. Parameters

7.2.44.3.1. --count

Attribute | Value
Name | --count
Type | java.lang.Long
Default Value |
Cardinality | [1, 1]
Description | The number of instances of the item to introduce.

7.2.44.3.2. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.44.3.3. --item

Attribute | Value
Name | --item
Type | com.io7m.cardant.model.CAItemID
Default Value |
Cardinality | [1, 1]
Description | The item ID.

7.2.44.3.4. --location

Attribute | Value
Name | --location
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [1, 1]
Description | The location ID.

7.2.44.4. Examples

7.2.44.4.1. Example

[cardant]$ stock-reposit-set-introduce \
  --instance 3cb641ac-182f-4f44-98f6-a3e0fe752297 \
  --location 55311cea-052f-4f72-9e34-bc01d0e43fee \
  --item 102c2df9-bbb4-4e5d-948f-0d8620704b97 \
  --count 100

7.2.45. stock-reposit-set-move

7.2.45.1. Name

7.2.45.2. Description

7.2.45.3. Parameters

7.2.45.4. Examples

7.2.45.1. Name

stock-reposit-set-move - Move instances of items between locations.

7.2.45.2. Description

The stock-reposit-set-move command moves items between set stock instances.

7.2.45.3. Parameters

7.2.45.3.1. --count

Attribute | Value
Name | --count
Type | java.lang.Long
Default Value |
Cardinality | [1, 1]
Description | The number of instances of the item to remove.

7.2.45.3.2. --instance-from

Attribute | Value
Name | --instance-from
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The source stock instance ID.

7.2.45.3.3. --instance-to

Attribute | Value
Name | --instance-to
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The target stock instance ID.

7.2.45.3.4. --location-to

Attribute | Value
Name | --location-to
Type | com.io7m.cardant.model.CALocationID
Default Value |
Cardinality | [1, 1]
Description | The destination location ID.

7.2.45.4. Examples

7.2.45.4.1. Example

[cardant]$ stock-reposit-set-move \
  --instance-from 0b041ff1-4bbe-4265-b0f2-51f0c5ff6757 \
  --instance-to d7c18055-cadb-4701-aa3d-9207711f6c8a
  --location-to 55311cea-052f-4f72-9e34-bc01d0e43fee \
  --count 50

7.2.46. stock-reposit-set-remove

7.2.46.1. Name

7.2.46.2. Description

7.2.46.3. Parameters

7.2.46.4. Examples

7.2.46.1. Name

stock-reposit-set-remove - Remove stock instances from locations.

7.2.46.2. Description

The stock-reposit-set-remove command removes items from set stock instances.

7.2.46.3. Parameters

7.2.46.3.1. --count

Attribute | Value
Name | --count
Type | java.lang.Long
Default Value |
Cardinality | [1, 1]
Description | The number of instances of the item to remove.

7.2.46.3.2. --instance

Attribute | Value
Name | --instance
Type | com.io7m.cardant.model.CAStockInstanceID
Default Value |
Cardinality | [1, 1]
Description | The stock instance ID.

7.2.46.4. Examples

7.2.46.4.1. Example

[cardant]$ stock-reposit-set-remove \
  --instance 0b041ff1-4bbe-4265-b0f2-51f0c5ff6757 \
  --count 50

7.2.47. stock-search-begin

7.2.47.1. Name

7.2.47.2. Description

7.2.47.3. Parameters

7.2.47.4. Examples

7.2.47.1. Name

stock-search-begin - Start searching for stock.

7.2.47.2. Description

The stock-search-begin command begins searching for stock.

7.2.47.3. Parameters

7.2.47.3.1. --exclude-stock-kind

Attribute | Value
Name | --exclude-stock-kind
Type | com.io7m.cardant.model.CAStockOccurrenceKind
Default Value | []
Cardinality | [0, N]
Description | Exclude stock occurrences of the given kinds.

7.2.47.3.2. --item-match

Attribute | Value
Name | --item-match
Type | com.io7m.cardant.model.CAItemIDMatch
Default Value | with-any-item
Cardinality | [1, 1]
Description | Only include items with IDs matching the given expression.

7.2.47.3.3. --limit

Attribute | Value
Name | --limit
Type | java.lang.Integer
Default Value | 100
Cardinality | [1, 1]
Description | The maximum number of results per page.

7.2.47.3.4. --location-match

Attribute | Value
Name | --location-match
Type | com.io7m.cardant.model.CALocationMatchType
Default Value | any-location
Cardinality | [1, 1]
Description | Only include stock in locations matching the given expression.

7.2.47.4. Examples

7.2.47.4.1. Example

[cardant]$ stock-search-begin

7.2.48. stock-search-next

7.2.48.1. Name

7.2.48.2. Description

7.2.48.3. Examples

7.2.48.1. Name

stock-search-next - Go to the next page of stock.

7.2.48.2. Description

The stock-search-next command returns the next page of search results.

7.2.48.3. Examples

7.2.48.3.1. Example

[cardant]$ stock-search-next

7.2.49. stock-search-previous

7.2.49.1. Name

7.2.49.2. Description

7.2.49.3. Examples

7.2.49.1. Name

stock-search-previous - Go to the previous page of stock.

7.2.49.2. Description

The stock-search-previous command returns the previous page of search results.

7.2.49.3. Examples

7.2.49.3.1. Example

[cardant]$ stock-search-previous

7.2.50. syntax-list

7.2.50.1. Name

7.2.50.2. Description

7.2.50.3. Examples

7.2.50.4. Parameters

7.2.50.1. Name

syntax-list - List the available syntax definitions.

7.2.50.2. Description

The syntax-list command lists all the known syntax rules.

7.2.50.3. Examples

7.2.50.3.1. Example

[cardant]$ syntax-list
┌───────────────────────────────────────────────────────────────────────────────────┐
│ Name                                                                              │
├───────────────────────────────────────────────────────────────────────────────────┤
│ description-equal-to                                                              │
├───────────────────────────────────────────────────────────────────────────────────┤
│ description-match                                                                 │
├───────────────────────────────────────────────────────────────────────────────────┤
│ description-not-equal-to                                                          │
├───────────────────────────────────────────────────────────────────────────────────┤
│ description-not-similar-to                                                        │
├───────────────────────────────────────────────────────────────────────────────────┤
│ description-similar-to                                                            │
├───────────────────────────────────────────────────────────────────────────────────┤
│ description-with-any                                                              │
├───────────────────────────────────────────────────────────────────────────────────┤
...

7.2.50.4. Parameters

The command has no parameters.

7.2.51. syntax-show

7.2.51.1. Name

7.2.51.2. Description

7.2.51.3. Examples

7.2.51.4. Parameters

7.2.51.1. Name

syntax-show - Show the given syntax definition.

7.2.51.2. Description

The syntax-show command displays definitions and/or examples for the given syntax rule.

7.2.51.3. Examples

7.2.51.3.1. Example

[cardant]$ syntax-show --rule metadata-type-match
metadata-type-match :=
  metadata-type-any
  | metadata-type-equal-to
  | metadata-type-not-equal-to
metadata-type-any :=
  with-any-type
metadata-type-equal-to :=
  (with-type-equal-to <type>)
metadata-type-not-equal-to :=
  (with-type-not-equal-to <type>)

[cardant]$ syntax-show --rule metadata-type-match --example true
[with-type-equal-to "com.io7m:t"]

[with-type-not-equal-to "com.io7m:t"]

7.2.51.4. Parameters

7.2.51.4.1. --example

Attribute | Value
Name | --example
Type | java.lang.Boolean
Default Value | false
Cardinality | [1, 1]
Description | Show a syntax example.

7.2.51.4.2. --rule

Attribute | Value
Name | --rule
Type | java.lang.String
Default Value |
Cardinality | [1, 1]
Description | The syntax rule name.

7.2.52. type-package-get-text

7.2.52.1. Name

7.2.52.2. Description

7.2.52.3. Parameters

7.2.52.4. Examples

7.2.52.1. Name

type-package-get-text - Retrieve the text of a type package.

7.2.52.2. Description

The type-package-get-text command retrieves the raw text of an installed type package.

7.2.52.3. Parameters

7.2.52.3.1. --name

Attribute | Value
Name | --name
Type | com.io7m.lanark.core.RDottedName
Default Value |
Cardinality | [1, 1]
Description | The type package name.

7.2.52.3.2. --output

Attribute | Value
Name | --output
Type | java.nio.file.Path
Default Value |
Cardinality | [0, 1]
Description | The output file.

7.2.52.3.3. --version

Attribute | Value
Name | --version
Type | com.io7m.verona.core.Version
Default Value |
Cardinality | [1, 1]
Description | The type package version.

7.2.52.4. Examples

7.2.52.4.1. Example

[cardant]$ type-package-get-text --name com.io7m.example --version 1.0.0 --output file.xml

7.2.53. type-package-install

7.2.53.1. Name

7.2.53.2. Description

7.2.53.3. Parameters

7.2.53.1. Name

type-package-install - Install a type package.

7.2.53.2. Description

The type-package-install command installs a type package from a file. Once installed, type packages may be upgraded or uninstalled.

7.2.53.3. Parameters

7.2.53.3.1. --file

Attribute | Value
Name | --file
Type | java.nio.file.Path
Default Value |
Cardinality | [1, 1]
Description | The type package file.

7.2.54. type-package-schema

7.2.54.1. Name

7.2.54.2. Description

7.2.54.3. Parameters

7.2.54.4. Examples

7.2.54.1. Name

type-package-schema - Retrieve the text of the type package schema.

7.2.54.2. Description

The type-package-schema command retrieves the text of the type package schema.

7.2.54.3. Parameters

7.2.54.3.1. --output

Attribute | Value
Name | --output
Type | java.nio.file.Path
Default Value |
Cardinality | [0, 1]
Description | The output file.

7.2.54.4. Examples

7.2.54.4.1. Example

[cardant]$ type-package-schema
<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:p="com.io7m.cardant:type_packages:1"
            targetNamespace="com.io7m.cardant:type_packages:1">

  <xsd:simpleType name="UnqualifiedNameType">
    <xsd:annotation>
...

7.2.55. type-package-search-begin

7.2.55.1. Name

7.2.55.2. Description

7.2.55.3. Parameters

7.2.55.1. Name

type-package-search-begin - Start searching for type packages

7.2.55.2. Description

The type-package-search-begin command starts searching for installed type packages.

Packages can be filtered based on matching their descriptions against a given description match expression.

7.2.55.3. Parameters

7.2.55.3.1. --description-match

Attribute | Value
Name | --description-match
Type | com.io7m.cardant.model.CADescriptionMatch
Default Value | with-any-description
Cardinality | [1, 1]
Description | Only include types that have descriptions matching the given expression.

7.2.55.3.2. --limit

Attribute | Value
Name | --limit
Type | java.lang.Integer
Default Value | 100
Cardinality | [1, 1]
Description | The maximum number of results per page.

7.2.56. type-package-search-next

7.2.56.1. Name

7.2.56.2. Description

7.2.56.1. Name

type-package-search-next - Go to the next page of type packages.

7.2.56.2. Description

The type-package-search-next command goes to the next page of type packages.

The command can only be used after the associated begin command.

7.2.57. type-package-search-previous

7.2.57.1. Name

7.2.57.2. Description

7.2.57.1. Name

type-package-search-previous - Go to the previous page of type packages.

7.2.57.2. Description

The type-package-search-previous command goes to the previous page of type packages.

The command can only be used after the associated begin command.

7.2.58. type-package-uninstall

7.2.58.1. Name

7.2.58.2. Description

7.2.58.3. Parameters

7.2.58.1. Name

type-package-uninstall - Uninstall a type package.

7.2.58.2. Description

The type-package-uninstall command uninstalls an installed type package.

7.2.58.3. Parameters

7.2.58.3.1. --behavior

Attribute | Value
Name | --behavior
Type | com.io7m.cardant.model.type_package.CATypePackageTypeRemovalBehavior
Default Value | TYPE_REMOVAL_FAIL_IF_TYPES_REFERENCED
Cardinality | [1, 1]
Description | The uninstall behavior.

7.2.58.3.2. --name

Attribute | Value
Name | --name
Type | com.io7m.lanark.core.RDottedName
Default Value |
Cardinality | [1, 1]
Description | The type package name.

7.2.58.3.3. --version

Attribute | Value
Name | --version
Type | com.io7m.verona.core.Version
Default Value |
Cardinality | [1, 1]
Description | The type package version.

7.2.59. type-package-upgrade

7.2.59.1. Name

7.2.59.2. Description

7.2.59.3. Parameters

7.2.59.1. Name

type-package-upgrade - Upgrade a type package.

7.2.59.2. Description

The type-package-upgrade command upgrades (or optionally downgrades) an installed type package.

7.2.59.3. Parameters

7.2.59.3.1. --file

Attribute | Value
Name | --file
Type | java.nio.file.Path
Default Value |
Cardinality | [1, 1]
Description | The type package file.

7.2.59.3.2. --type-removal-behavior

Attribute | Value
Name | --type-removal-behavior
Type | com.io7m.cardant.model.type_package.CATypePackageTypeRemovalBehavior
Default Value | TYPE_REMOVAL_FAIL_IF_TYPES_REFERENCED
Cardinality | [1, 1]
Description | The type removal behavior.

7.2.59.3.3. --version-behavior

Attribute | Value
Name | --version-behavior
Type | com.io7m.cardant.model.type_package.CATypePackageVersionBehavior
Default Value | VERSION_DISALLOW_DOWNGRADES
Cardinality | [1, 1]
Description | The version behavior.

7.2.60. version

7.2.60.1. Name

7.2.60.2. Description

7.2.60.3. Examples

7.2.60.1. Name

version - Display the shell version.

7.2.60.2. Description

The version command displays the shell version.

7.2.60.3. Examples

7.2.60.3.1. Example

...

8. API Access

8.1. Inventory Protocol

8.1.1. Versioning

8.1.2. Health

8.1.3. Version 1.0

8.1.3.1. Encoding

8.1.3.2. Login

8.1.3.3. Commands

8.1.3.4. Transactions

8.1.3.5. Schema

8.1. Inventory Protocol

8.1.1. Versioning

8.1.2. Health

8.1.3. Version 1.0

8.1.3.1. Encoding

8.1.3.2. Login

8.1.3.3. Commands

8.1.3.4. Transactions

8.1.3.5. Schema

8.1.1. Versioning

The Inventory API service exposes one or more versions of the Inventory protocol. The service uses the ventrad protocol to advertise which versions of the Inventory protocol are available. Executing a GET request to the root endpoint will yield a ventrad message showing which versions of the Inventory protocol are available. The Inventory protocol is assigned the protocol identifier 8ee23158-f8db-317a-a58b-45bd9d702040.

As an example, the following shows that the Inventory protocol version 1 is available at /inventory/1/0/:

8.1.1.3. Ventrad Example

$ curl https://cardant.example.com:30000/ | jq
{
  "%Schema": "urn:com.io7m.ventrad:1",
  "Protocols": [
    {
      "Id": "8ee23158-f8db-317a-a58b-45bd9d702040",
      "VersionMajor": 1,
      "VersionMinor": 0,
      "Endpoint": "/inventory/1/0/",
      "Description": "Cardant Inventory v1.0"
    }
  ]
}

8.1.2. Health

The Inventory API service exposes a health check endpoint at /health. The endpoint returns a 200 status code and the string OK if the server's most recent internal health checks succeeded. The server returns a 500 status code and string not equal to OK if the server's most recent internal health checks failed. In both cases, the string is returned directly as a text/plain UTF-8 value.

8.1.3. Version 1.0

8.1.3.1. Encoding

The version 1 Inventory protocol uses JSON-encoded messages over HTTP(s).

8.1.3.2. Login

Send a CJ1CommandLogin command to /inventory/1/0/login. If the login succeeds, a cookie named CARDANT_INVENTORY_SESSION will be set. This cookie must be included with all subsequent requests.

8.1.3.2.2. Login Example

$ cat message.json
{
  "@type": "Login",
  "userName": "example",
  "password": "validpassword"
}

$ curl -c cookies.txt -d @message.json http://cardant.example.com:30000/inventory/1/0/login | jq
{
  "@type": "ResponseLogin",
  "requestId": "23d56c39-9582-42af-a3a3-7d94bf944f35",
  "userId": "57733ee9-2c62-4b62-bd7f-b5bbc9cd915a"
}

$ cat cookies.txt
cardant.example.com FALSE /inventory/1/0/ FALSE 1761297157 CARDANT_INVENTORY_SESSION 47E3D6E4133D04FD33125F5A3598B79089F7A7DA3AC507ADB13DAEF12934B88C

8.1.3.3. Commands

After logging in successfully, send commands of type CJ1CommandType to /inventory/1/0/command. Failed commands will yield a value of type CJ1ResponseError, whilst successful results will yield values of type CJ1Response*.

8.1.3.3.2. Command Example

$ cat message.json
{
  "@type": "ItemSearchBegin",
  "parameters": {
    "matchName": {
      "@type": "Anything"
    },
    "matchDescription": {
      "@type": "Anything"
    },
    "matchTypes": {
      "@type": "Anything"
    },
    "matchMetadata": {
      "@type": "Specific",
      "packageName": {
        "@type": "Anything"
      },
      "typeName": {
        "@type": "Anything"
      },
      "fieldName": {
        "@type": "Anything"
      },
      "value": {
        "@type": "Anything"
      }
    },
    "includeDeleted": "INCLUDE_ONLY_LIVE",
    "orderBy": {
      "column": "BY_ID",
      "ascending": true
    },
    "pageSize": 5
  }
}

$ curl -b cookies.txt -d @message.json http://cardant.example.com:30000/inventory/1/0/command | jq
{
  "@type": "ResponseItemSearch",
  "requestId": "cf47d6f4-1441-4b79-9cd5-f80e21f1bc11",
  "results": {
    "items": [
      {
        "id": "0214d4fa-1fbb-47b9-bb57-f12d9bf2735e",
        "name": "Siglent SPD1305X DC Power Supply",
        "timeCreated": "2024-07-22T19:34:52.954587Z",
        "timeUpdated": "2024-07-22T19:34:52.954587Z"
      },
      {
        "id": "02f63b7e-4c0a-4f1c-81d6-862da8d2e5ac",
        "name": "Western Digital SN570 1TB",
        "timeCreated": "2024-01-12T21:01:15.973701Z",
        "timeUpdated": "2024-01-12T21:01:15.973701Z"
      },
      {
        "id": "0556121f-9aab-4e89-a413-08214d8ae74d",
        "name": "Seagate Exos X16 16TB",
        "timeCreated": "2024-01-12T21:05:33.547416Z",
        "timeUpdated": "2025-03-09T18:22:22Z"
      },
      {
        "id": "06946960-e508-4eeb-b297-715e1bcec843",
        "name": "Samsung 870 EVO 1TB",
        "timeCreated": "2024-05-18T12:28:43.607659Z",
        "timeUpdated": "2024-05-18T12:28:43.607659Z"
      },
      {
        "id": "0adb8f6a-ed35-479d-baf9-2e2f9a50b622",
        "name": "AMD Ryzen 5 3600",
        "timeCreated": "2024-01-12T21:02:01.738558Z",
        "timeUpdated": "2024-12-07T17:41:22Z"
      }
    ],
    "pageIndex": {
      "value": 1
    },
    "pageCount": {
      "value": 23
    },
    "pageFirstOffset": 0
  }
}

8.1.3.4. Transactions

It can sometimes be desirable to send sets of commands that must execute atomically; if a single command in the set fails, it must be as if none of the commands were executed.

After logging in successfully, a value of type CJ1Transaction can be sent to /inventory/1/0/transaction.

The response from the /inventory/1/0/transaction endpoint will be a value of type CJ1TransactionResponse with a response for each command in the original sequence. If any of the values in the sequence are CJ1ResponseError values, the transaction was rolled back by the server and not committed.

8.1.3.4.4. Transaction Example

$ cat transaction.json
{
  "@type": "Transaction",
  "commands": [
    {
      "@type": "ItemSearchBegin",
      "parameters": {
        "matchName": {
          "@type": "Anything"
        },
        "matchDescription": {
          "@type": "Anything"
        },
        "matchTypes": {
          "@type": "Anything"
        },
        "matchMetadata": {
          "@type": "Specific",
          "packageName": {
            "@type": "Anything"
          },
          "typeName": {
            "@type": "Anything"
          },
          "fieldName": {
            "@type": "Anything"
          },
          "value": {
            "@type": "Anything"
          }
        },
        "includeDeleted": "INCLUDE_ONLY_LIVE",
        "orderBy": {
          "column": "BY_ID",
          "ascending": true
        },
        "pageSize": 3
      }
    },
    {
      "@type": "ItemSearchNext"
    },
    {
      "@type": "ItemSearchNext"
    }
  ]
}

$ curl -b cookies.txt -d @message.json http://cardant.example.com:30000/inventory/1/0/transaction | jq
{
  "@type": "TransactionResponse",
  "requestId": "7c411039-7ca0-4e53-a9d1-0f7fd1b33919",
  "responses": [
    {
      "@type": "ResponseItemSearch",
      "requestId": "7c411039-7ca0-4e53-a9d1-0f7fd1b33919",
      "results": {
        "items": [
          {
            "id": "16208353-0cd6-4082-89b9-170b87e31000",
            "name": "AMD Radeon RX 5700",
            "timeCreated": "2024-01-12T21:02:28.13536Z",
            "timeUpdated": "2024-12-07T17:37:16Z"
          },
          {
            "id": "c1ef2558-9b2f-4a84-ba75-8a9fe5276e80",
            "name": "AMD Ryzen 3 3200G",
            "timeCreated": "2024-01-12T21:03:44.878024Z",
            "timeUpdated": "2024-12-07T17:38:49Z"
          },
          {
            "id": "0d5e8aca-0826-4e85-8a71-ffd26f4137c1",
            "name": "AMD Ryzen 5 1400",
            "timeCreated": "2024-01-12T21:06:34.568583Z",
            "timeUpdated": "2024-12-07T17:39:31Z"
          }
        ],
        "pageIndex": {
          "value": 1
        },
        "pageCount": {
          "value": 37
        },
        "pageFirstOffset": 0
      }
    },
    {
      "@type": "ResponseItemSearch",
      "requestId": "7c411039-7ca0-4e53-a9d1-0f7fd1b33919",
      "results": {
        "items": [
          {
            "id": "d9e12864-7411-43a4-9030-ebfaf94cd0bf",
            "name": "AMD Ryzen 5 3400G",
            "timeCreated": "2024-01-12T21:02:43.436395Z",
            "timeUpdated": "2024-12-07T17:40:46Z"
          },
          {
            "id": "0adb8f6a-ed35-479d-baf9-2e2f9a50b622",
            "name": "AMD Ryzen 5 3600",
            "timeCreated": "2024-01-12T21:02:01.738558Z",
            "timeUpdated": "2024-12-07T17:41:22Z"
          },
          {
            "id": "a92f27cf-aacc-48fb-aeb9-5afa92af8f46",
            "name": "AMD Ryzen 5 5600G",
            "timeCreated": "2024-01-12T21:03:57.892137Z",
            "timeUpdated": "2024-12-07T17:41:56Z"
          }
        ],
        "pageIndex": {
          "value": 2
        },
        "pageCount": {
          "value": 37
        },
        "pageFirstOffset": 3
      }
    },
    {
      "@type": "ResponseItemSearch",
      "requestId": "7c411039-7ca0-4e53-a9d1-0f7fd1b33919",
      "results": {
        "items": [
          {
            "id": "58794e07-532d-4143-905c-bcb65bdbd1e4",
            "name": "AMD Ryzen 7 3700X",
            "timeCreated": "2024-04-04T16:27:38.009937Z",
            "timeUpdated": "2024-12-07T17:42:35Z"
          },
          {
            "id": "922af91f-761e-438a-aaa9-055efa5d4360",
            "name": "Antec Neo ECO 520",
            "timeCreated": "2025-03-07T11:18:42Z",
            "timeUpdated": "2025-03-07T11:20:40Z"
          },
          {
            "id": "c75b8537-2725-452e-adb1-eaa3dfd5a286",
            "name": "Antec VP450P 450W",
            "timeCreated": "2025-03-07T11:15:24Z",
            "timeUpdated": "2025-03-07T11:16:58Z"
          }
        ],
        "pageIndex": {
          "value": 3
        },
        "pageCount": {
          "value": 37
        },
        "pageFirstOffset": 6
      }
    }
  ]
}

8.1.3.5. Schema

The JSON schema for the protocol is as follows:

8.1.3.5.2. Schema

{
  "$schema" : "https://json-schema.org/draft/2020-12/schema",
  "$id" : "urn:com.io7m.cardant.inventory:1.0",
  "title" : "Cardant Inventory 1.0",
  "oneOf" : [ {
    "$ref" : "#/$defs/CJ1MessageType"
  } ],
  "$defs" : {
    "BigDecimal" : {
      "description" : "An arbitrary real number.",
      "type" : "number"
    },
    "CAErrorCode" : {
      "description" : "An error code.",
      "type" : "string",
      "pattern" : "[a-z][a-z\\-]+"
    },
    "CJ1Attachment" : {
      "description" : "An attachment on an item or location.",
      "type" : "object",
      "properties" : {
        "file" : {
          "description" : "The file.",
          "$ref" : "#/$defs/CJ1FileType"
        },
        "relation" : {
          "description" : "The attachment relation.",
          "$ref" : "#/$defs/String"
        }
      },
      "required" : [ "file", "relation" ]
    },
    "CJ1AttachmentItem" : {
      "description" : "An attachment.",
      "type" : "object",
      "properties" : {
        "attachment" : {
          "description" : "The attachment.",
          "$ref" : "#/$defs/CJ1Attachment"
        },
        "key" : {
          "description" : "The attachment key.",
          "$ref" : "#/$defs/CJ1AttachmentKey"
        }
      },
      "required" : [ "attachment", "key" ]
    },
    "CJ1AttachmentKey" : {
      "description" : "An attachment key.",
      "type" : "object",
      "properties" : {
        "file" : {
          "description" : "The attachment file.",
          "$ref" : "#/$defs/UUID"
        },
        "relation" : {
          "description" : "The attachment relation.",
          "$ref" : "#/$defs/String"
        }
      },
      "required" : [ "file", "relation" ]
    },
    "CJ1AuditEvent" : {
      "description" : "An audit event.",
      "type" : "object",
      "properties" : {
        "data" : {
          "description" : "The event data.",
          "$ref" : "#/$defs/Map<String,String>"
        },
        "id" : {
          "description" : "The event ID.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "owner" : {
          "description" : "The event owner.",
          "$ref" : "#/$defs/UUID"
        },
        "time" : {
          "description" : "The event time.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "type" : {
          "description" : "The event type.",
          "$ref" : "#/$defs/String"
        }
      },
      "required" : [ "data", "id", "owner", "time", "type" ]
    },
    "CJ1AuditSearchParameters" : {
      "description" : "Parameters to search for audit events.",
      "type" : "object",
      "properties" : {
        "matchEventType" : {
          "description" : "Include events with types matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonExactType<String>"
        },
        "matchOwner" : {
          "description" : "Include audit results for the given user.",
          "$ref" : "#/$defs/Optional<UUID>"
        },
        "matchTimeRange" : {
          "description" : "Include events within the given time range.",
          "$ref" : "#/$defs/CJ1TimeRange"
        },
        "pageSize" : {
          "description" : "The maximum number of events per page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        }
      },
      "required" : [ "matchEventType", "matchTimeRange", "pageSize" ]
    },
    "CJ1CommandAuditSearchBegin" : {
      "description" : "Start searching for audit events.",
      "type" : "object",
      "properties" : {
        "parameters" : {
          "description" : "The search parameters.",
          "$ref" : "#/$defs/CJ1AuditSearchParameters"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "AuditSearchBegin"
        }
      },
      "required" : [ "@type", "parameters" ]
    },
    "CJ1CommandAuditSearchNext" : {
      "description" : "Get the next page of audit events.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "AuditSearchNext"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandAuditSearchPrevious" : {
      "description" : "Get the previous page of audit events.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "AuditSearchPrevious"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandFileDelete" : {
      "description" : "Delete a file.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "FileDelete"
        }
      },
      "required" : [ "@type", "id" ]
    },
    "CJ1CommandFileGet" : {
      "description" : "Get a file.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "FileGet"
        }
      },
      "required" : [ "@type", "id" ]
    },
    "CJ1CommandFilePut" : {
      "description" : "Create or update a file.",
      "type" : "object",
      "properties" : {
        "file" : {
          "description" : "The file.",
          "$ref" : "#/$defs/CJ1FileType"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "FilePut"
        }
      },
      "required" : [ "@type", "file" ]
    },
    "CJ1CommandFileSearchBegin" : {
      "description" : "Start searching for files.",
      "type" : "object",
      "properties" : {
        "parameters" : {
          "description" : "The search parameters.",
          "$ref" : "#/$defs/CJ1FileSearchParameters"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "FileSearchBegin"
        }
      },
      "required" : [ "@type", "parameters" ]
    },
    "CJ1CommandFileSearchNext" : {
      "description" : "Get the next page of files.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "FileSearchNext"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandFileSearchPrevious" : {
      "description" : "Get the previous page of files.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "FileSearchPrevious"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandItemAttachmentAdd" : {
      "description" : "Add an attachment to an item.",
      "type" : "object",
      "properties" : {
        "file" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "item" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "relation" : {
          "description" : "The attachment relation.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemAttachmentAdd"
        }
      },
      "required" : [ "@type", "file", "item", "relation" ]
    },
    "CJ1CommandItemAttachmentRemove" : {
      "description" : "Remove an attachment from an item.",
      "type" : "object",
      "properties" : {
        "file" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "item" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "relation" : {
          "description" : "The attachment relation.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemAttachmentRemove"
        }
      },
      "required" : [ "@type", "file", "item", "relation" ]
    },
    "CJ1CommandItemCreate" : {
      "description" : "Create an item.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "name" : {
          "description" : "The item name.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemCreate"
        }
      },
      "required" : [ "@type", "id", "name" ]
    },
    "CJ1CommandItemDelete" : {
      "description" : "Delete an item.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemDelete"
        }
      },
      "required" : [ "@type", "id" ]
    },
    "CJ1CommandItemGet" : {
      "description" : "Retrieve an item.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemGet"
        }
      },
      "required" : [ "@type", "id" ]
    },
    "CJ1CommandItemMetadataPut" : {
      "description" : "Create or update metadata on an item.",
      "type" : "object",
      "properties" : {
        "item" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "metadatas" : {
          "description" : "The item metadata values.",
          "$ref" : "#/$defs/Set<CJ1MetadataType>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemMetadataPut"
        }
      },
      "required" : [ "@type", "item", "metadatas" ]
    },
    "CJ1CommandItemMetadataRemove" : {
      "description" : "Remove metadata from an item.",
      "type" : "object",
      "properties" : {
        "item" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "metadataNames" : {
          "description" : "The item metadata names.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordFieldIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemMetadataRemove"
        }
      },
      "required" : [ "@type", "item", "metadataNames" ]
    },
    "CJ1CommandItemSearchBegin" : {
      "description" : "Start searching for items.",
      "type" : "object",
      "properties" : {
        "parameters" : {
          "description" : "The item search parameters.",
          "$ref" : "#/$defs/CJ1ItemSearchParameters"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemSearchBegin"
        }
      },
      "required" : [ "@type", "parameters" ]
    },
    "CJ1CommandItemSearchNext" : {
      "description" : "Get the next page of items.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "ItemSearchNext"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandItemSearchPrevious" : {
      "description" : "Get the previous page of items.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "ItemSearchPrevious"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandItemSetName" : {
      "description" : "Set the name of an item.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "name" : {
          "description" : "The item name.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemSetName"
        }
      },
      "required" : [ "@type", "id", "name" ]
    },
    "CJ1CommandItemTypesAssign" : {
      "description" : "Assign types to an item.",
      "type" : "object",
      "properties" : {
        "item" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "types" : {
          "description" : "The types.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemTypesAssign"
        }
      },
      "required" : [ "@type", "item" ]
    },
    "CJ1CommandItemTypesRevoke" : {
      "description" : "Revoke types from an item.",
      "type" : "object",
      "properties" : {
        "item" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "types" : {
          "description" : "The types.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ItemTypesRevoke"
        }
      },
      "required" : [ "@type", "item" ]
    },
    "CJ1CommandLocationAttachmentAdd" : {
      "description" : "Add an attachment to a location.",
      "type" : "object",
      "properties" : {
        "file" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "location" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "relation" : {
          "description" : "The attachment relation.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationAttachmentAdd"
        }
      },
      "required" : [ "@type", "file", "location", "relation" ]
    },
    "CJ1CommandLocationAttachmentRemove" : {
      "description" : "Remove an attachment from a location.",
      "type" : "object",
      "properties" : {
        "file" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "location" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "relation" : {
          "description" : "The attachment relation.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationAttachmentRemove"
        }
      },
      "required" : [ "@type", "file", "location", "relation" ]
    },
    "CJ1CommandLocationDelete" : {
      "description" : "Delete a location.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationDelete"
        }
      },
      "required" : [ "@type", "id" ]
    },
    "CJ1CommandLocationGet" : {
      "description" : "Retrieve a location.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationGet"
        }
      },
      "required" : [ "@type", "id" ]
    },
    "CJ1CommandLocationList" : {
      "description" : "List locations.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "LocationList"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandLocationMetadataPut" : {
      "description" : "Create or update metadata on a location.",
      "type" : "object",
      "properties" : {
        "location" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "metadatas" : {
          "description" : "The location metadata values.",
          "$ref" : "#/$defs/Set<CJ1MetadataType>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationMetadataPut"
        }
      },
      "required" : [ "@type", "location", "metadatas" ]
    },
    "CJ1CommandLocationMetadataRemove" : {
      "description" : "Remove metadata from a location.",
      "type" : "object",
      "properties" : {
        "location" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "metadataNames" : {
          "description" : "The location metadata names.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordFieldIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationMetadataRemove"
        }
      },
      "required" : [ "@type", "location", "metadataNames" ]
    },
    "CJ1CommandLocationPut" : {
      "description" : "Create or update a location.",
      "type" : "object",
      "properties" : {
        "location" : {
          "description" : "The location.",
          "$ref" : "#/$defs/CJ1Location"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationPut"
        }
      },
      "required" : [ "@type", "location" ]
    },
    "CJ1CommandLocationTypesAssign" : {
      "description" : "Assign types to a location.",
      "type" : "object",
      "properties" : {
        "location" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "types" : {
          "description" : "The location types.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationTypesAssign"
        }
      },
      "required" : [ "@type", "location" ]
    },
    "CJ1CommandLocationTypesRevoke" : {
      "description" : "Revoke types from a location.",
      "type" : "object",
      "properties" : {
        "location" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "types" : {
          "description" : "The location type names.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "LocationTypesRevoke"
        }
      },
      "required" : [ "@type", "location" ]
    },
    "CJ1CommandLogin" : {
      "description" : "Log in.",
      "type" : "object",
      "properties" : {
        "metadata" : {
          "description" : "The extra metadata.",
          "$ref" : "#/$defs/Map<String,String>"
        },
        "password" : {
          "description" : "The password.",
          "$ref" : "#/$defs/String"
        },
        "userName" : {
          "description" : "The user name.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Login"
        }
      },
      "required" : [ "@type", "password", "userName" ]
    },
    "CJ1CommandRolesAssign" : {
      "description" : "Assign roles to a user.",
      "type" : "object",
      "properties" : {
        "roles" : {
          "description" : "The roles.",
          "$ref" : "#/$defs/Set<String>"
        },
        "user" : {
          "description" : "The user ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "RolesAssign"
        }
      },
      "required" : [ "@type", "user" ]
    },
    "CJ1CommandRolesGet" : {
      "description" : "Get roles assigned to a user.",
      "type" : "object",
      "properties" : {
        "user" : {
          "description" : "The user ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "RolesGet"
        }
      },
      "required" : [ "@type", "user" ]
    },
    "CJ1CommandRolesRevoke" : {
      "description" : "Revoke roles from a user.",
      "type" : "object",
      "properties" : {
        "roles" : {
          "description" : "The roles.",
          "$ref" : "#/$defs/Set<String>"
        },
        "user" : {
          "description" : "The user ID.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "RolesRevoke"
        }
      },
      "required" : [ "@type", "user" ]
    },
    "CJ1CommandStockCount" : {
      "description" : "Count stock matching the given search parameters.",
      "type" : "object",
      "properties" : {
        "parameters" : {
          "description" : "The stock search parameters.",
          "$ref" : "#/$defs/CJ1StockSearchParameters"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "StockCount"
        }
      },
      "required" : [ "@type", "parameters" ]
    },
    "CJ1CommandStockReposit" : {
      "description" : "Execute a stock reposition.",
      "type" : "object",
      "properties" : {
        "reposit" : {
          "description" : "The stock reposition.",
          "$ref" : "#/$defs/CJ1StockRepositType"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "StockReposit"
        }
      },
      "required" : [ "@type", "reposit" ]
    },
    "CJ1CommandStockSearchBegin" : {
      "description" : "Start searching for stock.",
      "type" : "object",
      "properties" : {
        "parameters" : {
          "description" : "The stock search parameters.",
          "$ref" : "#/$defs/CJ1StockSearchParameters"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "StockSearchBegin"
        }
      },
      "required" : [ "@type", "parameters" ]
    },
    "CJ1CommandStockSearchNext" : {
      "description" : "Get the next page of stock.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "StockSearchNext"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandStockSearchPrevious" : {
      "description" : "Get the previous page of stock.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "StockSearchPrevious"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1CommandAuditSearchBegin"
      }, {
        "$ref" : "#/$defs/CJ1CommandAuditSearchNext"
      }, {
        "$ref" : "#/$defs/CJ1CommandAuditSearchPrevious"
      }, {
        "$ref" : "#/$defs/CJ1CommandFileDelete"
      }, {
        "$ref" : "#/$defs/CJ1CommandFileGet"
      }, {
        "$ref" : "#/$defs/CJ1CommandFilePut"
      }, {
        "$ref" : "#/$defs/CJ1CommandFileSearchBegin"
      }, {
        "$ref" : "#/$defs/CJ1CommandFileSearchNext"
      }, {
        "$ref" : "#/$defs/CJ1CommandFileSearchPrevious"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemAttachmentAdd"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemAttachmentRemove"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemCreate"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemDelete"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemGet"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemMetadataPut"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemMetadataRemove"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemSearchBegin"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemSearchNext"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemSearchPrevious"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemSetName"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemTypesAssign"
      }, {
        "$ref" : "#/$defs/CJ1CommandItemTypesRevoke"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationAttachmentAdd"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationAttachmentRemove"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationDelete"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationGet"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationList"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationMetadataPut"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationMetadataRemove"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationPut"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationTypesAssign"
      }, {
        "$ref" : "#/$defs/CJ1CommandLocationTypesRevoke"
      }, {
        "$ref" : "#/$defs/CJ1CommandLogin"
      }, {
        "$ref" : "#/$defs/CJ1CommandRolesAssign"
      }, {
        "$ref" : "#/$defs/CJ1CommandRolesGet"
      }, {
        "$ref" : "#/$defs/CJ1CommandRolesRevoke"
      }, {
        "$ref" : "#/$defs/CJ1CommandStockCount"
      }, {
        "$ref" : "#/$defs/CJ1CommandStockReposit"
      }, {
        "$ref" : "#/$defs/CJ1CommandStockSearchBegin"
      }, {
        "$ref" : "#/$defs/CJ1CommandStockSearchNext"
      }, {
        "$ref" : "#/$defs/CJ1CommandStockSearchPrevious"
      }, {
        "$ref" : "#/$defs/CJ1CommandTypePackageGetText"
      }, {
        "$ref" : "#/$defs/CJ1CommandTypePackageInstall"
      }, {
        "$ref" : "#/$defs/CJ1CommandTypePackageSearchBegin"
      }, {
        "$ref" : "#/$defs/CJ1CommandTypePackageSearchNext"
      }, {
        "$ref" : "#/$defs/CJ1CommandTypePackageSearchPrevious"
      }, {
        "$ref" : "#/$defs/CJ1CommandTypePackageUninstall"
      }, {
        "$ref" : "#/$defs/CJ1CommandTypePackageUpgrade"
      } ]
    },
    "CJ1CommandTypePackageGetText" : {
      "description" : "Get the text of a type package.",
      "type" : "object",
      "properties" : {
        "identifier" : {
          "description" : "The type package identifier.",
          "$ref" : "#/$defs/CJ1TypePackageIdentifier"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TypePackageGetText"
        }
      },
      "required" : [ "@type", "identifier" ]
    },
    "CJ1CommandTypePackageInstall" : {
      "description" : "Install a type package.",
      "type" : "object",
      "properties" : {
        "text" : {
          "description" : "The type package text.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TypePackageInstall"
        }
      },
      "required" : [ "@type", "text" ]
    },
    "CJ1CommandTypePackageSearchBegin" : {
      "description" : "Start searching for type packages.",
      "type" : "object",
      "properties" : {
        "parameters" : {
          "description" : "The type package search parameters.",
          "$ref" : "#/$defs/CJ1TypePackageSearchParameters"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TypePackageSearchBegin"
        }
      },
      "required" : [ "@type", "parameters" ]
    },
    "CJ1CommandTypePackageSearchNext" : {
      "description" : "Get the next page of type packages.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "TypePackageSearchNext"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandTypePackageSearchPrevious" : {
      "description" : "Get the previous page of type packages.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "TypePackageSearchPrevious"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1CommandTypePackageUninstall" : {
      "description" : "Uninstall a type package.",
      "type" : "object",
      "properties" : {
        "uninstall" : {
          "description" : "The type package uninstall parameters.",
          "$ref" : "#/$defs/CJ1TypePackageUninstall"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TypePackageUninstall"
        }
      },
      "required" : [ "@type", "uninstall" ]
    },
    "CJ1CommandTypePackageUpgrade" : {
      "description" : "Upgrade a type package.",
      "type" : "object",
      "properties" : {
        "text" : {
          "description" : "The type package text.",
          "$ref" : "#/$defs/String"
        },
        "typeRemovalBehavior" : {
          "description" : "The type removal behavior.",
          "$ref" : "#/$defs/CJ1TypePackageTypeRemovalBehavior"
        },
        "versionBehavior" : {
          "description" : "The type version behavior.",
          "$ref" : "#/$defs/CJ1TypePackageVersionBehavior"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TypePackageUpgrade"
        }
      },
      "required" : [ "@type", "text", "typeRemovalBehavior", "versionBehavior" ]
    },
    "CJ1ComparisonExactAnything<RDottedName>" : {
      "description" : "Match anything.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "Anything"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1ComparisonExactAnything<String>" : {
      "description" : "Match anything.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "Anything"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1ComparisonExactAnything<UUID>" : {
      "description" : "Match anything.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "Anything"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1ComparisonExactIsEqualTo<RDottedName>" : {
      "description" : "Matches values exactly equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/RDottedName"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonExactIsEqualTo<String>" : {
      "description" : "Matches values exactly equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonExactIsEqualTo<UUID>" : {
      "description" : "Matches values exactly equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonExactIsNotEqualTo<RDottedName>" : {
      "description" : "Matches values not equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/RDottedName"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsNotEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonExactIsNotEqualTo<String>" : {
      "description" : "Matches values not equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsNotEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonExactIsNotEqualTo<UUID>" : {
      "description" : "Matches values not equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsNotEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonExactType<RDottedName>" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1ComparisonExactAnything<RDottedName>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonExactIsEqualTo<RDottedName>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonExactIsNotEqualTo<RDottedName>"
      } ]
    },
    "CJ1ComparisonExactType<String>" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1ComparisonExactAnything<String>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonExactIsEqualTo<String>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonExactIsNotEqualTo<String>"
      } ]
    },
    "CJ1ComparisonExactType<UUID>" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1ComparisonExactAnything<UUID>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonExactIsEqualTo<UUID>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonExactIsNotEqualTo<UUID>"
      } ]
    },
    "CJ1ComparisonFuzzyAnything<String>" : {
      "description" : "Match anything.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "Anything"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1ComparisonFuzzyIsEqualTo<String>" : {
      "description" : "Matches values exactly equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonFuzzyIsNotEqualTo<String>" : {
      "description" : "Matches values not equal to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsNotEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonFuzzyIsNotSimilarTo<String>" : {
      "description" : "Matches values not similar to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsNotSimilarTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonFuzzyIsSimilarTo<String>" : {
      "description" : "Matches values similar to the given value.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsSimilarTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonFuzzyType<String>" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1ComparisonFuzzyAnything<String>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonFuzzyIsEqualTo<String>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonFuzzyIsNotEqualTo<String>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonFuzzyIsNotSimilarTo<String>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonFuzzyIsSimilarTo<String>"
      } ]
    },
    "CJ1ComparisonSetAnything<CJ1TypeRecordIdentifier>" : {
      "description" : "Match anything.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "Anything"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1ComparisonSetIsEqualTo<CJ1TypeRecordIdentifier>" : {
      "description" : "Match sets equal to the given set.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonSetIsNotEqualTo<CJ1TypeRecordIdentifier>" : {
      "description" : "Match sets not equal to the given set.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsNotEqualTo"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonSetIsOverlapping<CJ1TypeRecordIdentifier>" : {
      "description" : "Match sets overlapping the given set.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsOverlapping"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonSetIsSubsetOf<CJ1TypeRecordIdentifier>" : {
      "description" : "Match sets that are a subset of the given set.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsSubsetOf"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonSetIsSupersetOf<CJ1TypeRecordIdentifier>" : {
      "description" : "Match sets that are a superset of the given set.",
      "type" : "object",
      "properties" : {
        "value" : {
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IsSupersetOf"
        }
      },
      "required" : [ "@type", "value" ]
    },
    "CJ1ComparisonSetType<CJ1TypeRecordIdentifier>" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1ComparisonSetAnything<CJ1TypeRecordIdentifier>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonSetIsEqualTo<CJ1TypeRecordIdentifier>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonSetIsNotEqualTo<CJ1TypeRecordIdentifier>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonSetIsOverlapping<CJ1TypeRecordIdentifier>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonSetIsSubsetOf<CJ1TypeRecordIdentifier>"
      }, {
        "$ref" : "#/$defs/CJ1ComparisonSetIsSupersetOf<CJ1TypeRecordIdentifier>"
      } ]
    },
    "CJ1FileColumn" : {
      "type" : "string",
      "enum" : [ "BY_ID", "BY_DESCRIPTION" ]
    },
    "CJ1FileColumnOrdering" : {
      "type" : "object",
      "properties" : {
        "ascending" : {
          "$ref" : "#/$defs/boolean"
        },
        "column" : {
          "description" : "The column used to order results.",
          "$ref" : "#/$defs/CJ1FileColumn"
        }
      },
      "required" : [ "ascending", "column" ]
    },
    "CJ1FileSearchParameters" : {
      "description" : "Parameters to search for files.",
      "type" : "object",
      "properties" : {
        "matchDescription" : {
          "description" : "Include files with descriptions matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonFuzzyType<String>"
        },
        "matchMediaType" : {
          "description" : "Include files with media types matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonFuzzyType<String>"
        },
        "matchSizeRange" : {
          "description" : "Include files with sizes matching the given expression.",
          "$ref" : "#/$defs/CJ1SizeRange"
        },
        "orderBy" : {
          "description" : "The result ordering.",
          "$ref" : "#/$defs/CJ1FileColumnOrdering"
        },
        "pageSize" : {
          "description" : "The maximum number of results per page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        }
      },
      "required" : [ "matchDescription", "matchMediaType", "matchSizeRange", "orderBy", "pageSize" ]
    },
    "CJ1FileType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1FileWithData"
      }, {
        "$ref" : "#/$defs/CJ1FileWithoutData"
      } ]
    },
    "CJ1FileWithData" : {
      "description" : "A file with the data included.",
      "type" : "object",
      "properties" : {
        "data" : {
          "description" : "The file data.",
          "$ref" : "#/$defs/byte[]"
        },
        "description" : {
          "description" : "The file description.",
          "$ref" : "#/$defs/String"
        },
        "hashAlgorithm" : {
          "description" : "The file hash algorithm.",
          "$ref" : "#/$defs/String"
        },
        "hashValue" : {
          "description" : "The file hash value.",
          "$ref" : "#/$defs/String"
        },
        "id" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "mediaType" : {
          "description" : "The file media type.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "FileWithData"
        }
      },
      "required" : [ "@type", "data", "description", "hashAlgorithm", "hashValue", "id", "mediaType" ]
    },
    "CJ1FileWithoutData" : {
      "description" : "A file without the data included.",
      "type" : "object",
      "properties" : {
        "description" : {
          "description" : "The file description.",
          "$ref" : "#/$defs/String"
        },
        "hashAlgorithm" : {
          "description" : "The file hash algorithm.",
          "$ref" : "#/$defs/String"
        },
        "hashValue" : {
          "description" : "The file hash value.",
          "$ref" : "#/$defs/String"
        },
        "id" : {
          "description" : "The file ID.",
          "$ref" : "#/$defs/UUID"
        },
        "mediaType" : {
          "description" : "The file media type.",
          "$ref" : "#/$defs/String"
        },
        "size" : {
          "description" : "The file size.",
          "$ref" : "#/$defs/long"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "FileWithoutData"
        }
      },
      "required" : [ "@type", "description", "hashAlgorithm", "hashValue", "id", "mediaType", "size" ]
    },
    "CJ1IncludeDeleted" : {
      "type" : "string",
      "enum" : [ "INCLUDE_ONLY_LIVE", "INCLUDE_ONLY_DELETED", "INCLUDE_BOTH_LIVE_AND_DELETED" ]
    },
    "CJ1Item" : {
      "description" : "An item.",
      "type" : "object",
      "properties" : {
        "attachments" : {
          "description" : "The item attachments.",
          "$ref" : "#/$defs/List<CJ1AttachmentItem>"
        },
        "id" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "metadata" : {
          "description" : "The item metadata.",
          "$ref" : "#/$defs/Map<CJ1TypeRecordFieldIdentifier,CJ1MetadataType>"
        },
        "name" : {
          "description" : "The item name.",
          "$ref" : "#/$defs/String"
        },
        "timeCreated" : {
          "description" : "The item creation time.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "timeUpdated" : {
          "description" : "The item most recent update time.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "types" : {
          "description" : "The item types.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        }
      },
      "required" : [ "id", "name", "timeCreated", "timeUpdated" ]
    },
    "CJ1ItemColumn" : {
      "type" : "string",
      "enum" : [ "BY_ID", "BY_NAME" ]
    },
    "CJ1ItemColumnOrdering" : {
      "type" : "object",
      "properties" : {
        "ascending" : {
          "$ref" : "#/$defs/boolean"
        },
        "column" : {
          "description" : "The column used to order results.",
          "$ref" : "#/$defs/CJ1ItemColumn"
        }
      },
      "required" : [ "ascending", "column" ]
    },
    "CJ1ItemSearchParameters" : {
      "description" : "Parameters to search for items.",
      "type" : "object",
      "properties" : {
        "includeDeleted" : {
          "description" : "Include deleted items.",
          "$ref" : "#/$defs/CJ1IncludeDeleted"
        },
        "matchDescription" : {
          "description" : "Include items with descriptions matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonFuzzyType<String>"
        },
        "matchMetadata" : {
          "description" : "Include items with metadata matching the given expression.",
          "$ref" : "#/$defs/CJ1MetadataElementMatchType"
        },
        "matchName" : {
          "description" : "Include items with names matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonFuzzyType<String>"
        },
        "matchTypes" : {
          "description" : "Include items with types matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonSetType<CJ1TypeRecordIdentifier>"
        },
        "orderBy" : {
          "description" : "The result ordering.",
          "$ref" : "#/$defs/CJ1ItemColumnOrdering"
        },
        "pageSize" : {
          "description" : "The maximum number of results per page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        }
      },
      "required" : [ "includeDeleted", "matchDescription", "matchMetadata", "matchName", "matchTypes", "orderBy", "pageSize" ]
    },
    "CJ1ItemSerial" : {
      "description" : "A serial number.",
      "type" : "object",
      "properties" : {
        "type" : {
          "description" : "The serial number type.",
          "$ref" : "#/$defs/RDottedName"
        },
        "value" : {
          "description" : "The serial number value.",
          "$ref" : "#/$defs/String"
        }
      },
      "required" : [ "type", "value" ]
    },
    "CJ1ItemSummary" : {
      "description" : "An item summary.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The item ID.",
          "$ref" : "#/$defs/UUID"
        },
        "name" : {
          "description" : "The item name.",
          "$ref" : "#/$defs/String"
        },
        "timeCreated" : {
          "description" : "The item creation time.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "timeUpdated" : {
          "description" : "The item most recent update time.",
          "$ref" : "#/$defs/OffsetDateTime"
        }
      },
      "required" : [ "id", "name", "timeCreated", "timeUpdated" ]
    },
    "CJ1Location" : {
      "description" : "A location.",
      "type" : "object",
      "properties" : {
        "attachments" : {
          "description" : "The location attachments.",
          "$ref" : "#/$defs/List<CJ1AttachmentItem>"
        },
        "id" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "metadata" : {
          "description" : "The location metadata.",
          "$ref" : "#/$defs/Map<CJ1TypeRecordFieldIdentifier,CJ1MetadataType>"
        },
        "parent" : {
          "description" : "The location parent.",
          "$ref" : "#/$defs/Optional<UUID>"
        },
        "path" : {
          "description" : "The location path.",
          "$ref" : "#/$defs/List<String>"
        },
        "timeCreated" : {
          "description" : "The location creation time.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "timeUpdated" : {
          "description" : "The location most recent update time.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "types" : {
          "description" : "The location types.",
          "$ref" : "#/$defs/Set<CJ1TypeRecordIdentifier>"
        }
      },
      "required" : [ "id", "path", "timeCreated", "timeUpdated" ]
    },
    "CJ1LocationMatchAll" : {
      "description" : "Match all locations.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "All"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1LocationMatchExact" : {
      "description" : "Match an exact location.",
      "type" : "object",
      "properties" : {
        "location" : {
          "description" : "The location.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Exact"
        }
      },
      "required" : [ "@type", "location" ]
    },
    "CJ1LocationMatchType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1LocationMatchAll"
      }, {
        "$ref" : "#/$defs/CJ1LocationMatchExact"
      }, {
        "$ref" : "#/$defs/CJ1LocationMatchWithDescendants"
      } ]
    },
    "CJ1LocationMatchWithDescendants" : {
      "description" : "Match an exact location and descendants of that location.",
      "type" : "object",
      "properties" : {
        "location" : {
          "description" : "The location.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "WithDescendants"
        }
      },
      "required" : [ "@type", "location" ]
    },
    "CJ1LocationSummary" : {
      "description" : "A location summary.",
      "type" : "object",
      "properties" : {
        "id" : {
          "description" : "The location ID.",
          "$ref" : "#/$defs/UUID"
        },
        "parent" : {
          "description" : "The location parent.",
          "$ref" : "#/$defs/Optional<UUID>"
        },
        "path" : {
          "description" : "The location path.",
          "$ref" : "#/$defs/List<String>"
        },
        "timeCreated" : {
          "description" : "The location creation time.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "timeUpdated" : {
          "description" : "The location most recent update time.",
          "$ref" : "#/$defs/OffsetDateTime"
        }
      },
      "required" : [ "id", "timeCreated", "timeUpdated" ]
    },
    "CJ1MessageType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1CommandType"
      }, {
        "$ref" : "#/$defs/CJ1ResponseType"
      }, {
        "$ref" : "#/$defs/CJ1Transaction"
      }, {
        "$ref" : "#/$defs/CJ1TransactionResponse"
      } ]
    },
    "CJ1MetadataElementMatchAnd" : {
      "description" : "Match metadata elements that match both expressions.",
      "type" : "object",
      "properties" : {
        "expression0" : {
          "description" : "The left expression.",
          "$ref" : "#/$defs/CJ1MetadataElementMatchType"
        },
        "expression1" : {
          "description" : "The right expression.",
          "$ref" : "#/$defs/CJ1MetadataElementMatchType"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "And"
        }
      },
      "required" : [ "@type", "expression0", "expression1" ]
    },
    "CJ1MetadataElementMatchOr" : {
      "description" : "Match metadata elements that match either expression.",
      "type" : "object",
      "properties" : {
        "expression0" : {
          "description" : "The left expression.",
          "$ref" : "#/$defs/CJ1MetadataElementMatchType"
        },
        "expression1" : {
          "description" : "The right expression.",
          "$ref" : "#/$defs/CJ1MetadataElementMatchType"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Or"
        }
      },
      "required" : [ "@type", "expression0", "expression1" ]
    },
    "CJ1MetadataElementMatchSpecific" : {
      "description" : "Match specific metadata elements.",
      "type" : "object",
      "properties" : {
        "fieldName" : {
          "description" : "An expression that matches metadata field names.",
          "$ref" : "#/$defs/CJ1ComparisonExactType<String>"
        },
        "packageName" : {
          "description" : "An expression that matches metadata package names.",
          "$ref" : "#/$defs/CJ1ComparisonExactType<RDottedName>"
        },
        "typeName" : {
          "description" : "An expression that matches metadata type names.",
          "$ref" : "#/$defs/CJ1ComparisonExactType<String>"
        },
        "value" : {
          "description" : "An expression that matches metadata values.",
          "$ref" : "#/$defs/CJ1MetadataValueMatchType"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Specific"
        }
      },
      "required" : [ "@type", "fieldName", "packageName", "typeName", "value" ]
    },
    "CJ1MetadataElementMatchType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataElementMatchAnd"
      }, {
        "$ref" : "#/$defs/CJ1MetadataElementMatchOr"
      }, {
        "$ref" : "#/$defs/CJ1MetadataElementMatchSpecific"
      } ]
    },
    "CJ1MetadataIntegral" : {
      "description" : "An integral metadata value.",
      "type" : "object",
      "properties" : {
        "name" : {
          "description" : "The metadata field name.",
          "$ref" : "#/$defs/CJ1TypeRecordFieldIdentifier"
        },
        "value" : {
          "description" : "The metadata value.",
          "$ref" : "#/$defs/long"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Integral"
        }
      },
      "required" : [ "@type", "name", "value" ]
    },
    "CJ1MetadataMonetary" : {
      "description" : "A monetary metadata value.",
      "type" : "object",
      "properties" : {
        "currency" : {
          "description" : "The metadata currency value.",
          "$ref" : "#/$defs/CurrencyUnit"
        },
        "name" : {
          "description" : "The metadata field name.",
          "$ref" : "#/$defs/CJ1TypeRecordFieldIdentifier"
        },
        "value" : {
          "description" : "The metadata value.",
          "$ref" : "#/$defs/BigDecimal"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Monetary"
        }
      },
      "required" : [ "@type", "currency", "name", "value" ]
    },
    "CJ1MetadataReal" : {
      "description" : "A real metadata value.",
      "type" : "object",
      "properties" : {
        "name" : {
          "description" : "The metadata field name.",
          "$ref" : "#/$defs/CJ1TypeRecordFieldIdentifier"
        },
        "value" : {
          "description" : "The metadata value.",
          "$ref" : "#/$defs/double"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Real"
        }
      },
      "required" : [ "@type", "name", "value" ]
    },
    "CJ1MetadataText" : {
      "description" : "A text metadata value.",
      "type" : "object",
      "properties" : {
        "name" : {
          "description" : "The metadata field name.",
          "$ref" : "#/$defs/CJ1TypeRecordFieldIdentifier"
        },
        "value" : {
          "description" : "The metadata value.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Text"
        }
      },
      "required" : [ "@type", "name", "value" ]
    },
    "CJ1MetadataTime" : {
      "description" : "A time metadata value.",
      "type" : "object",
      "properties" : {
        "name" : {
          "description" : "The metadata field name.",
          "$ref" : "#/$defs/CJ1TypeRecordFieldIdentifier"
        },
        "value" : {
          "description" : "The metadata value.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Time"
        }
      },
      "required" : [ "@type", "name", "value" ]
    },
    "CJ1MetadataType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataIntegral"
      }, {
        "$ref" : "#/$defs/CJ1MetadataMonetary"
      }, {
        "$ref" : "#/$defs/CJ1MetadataReal"
      }, {
        "$ref" : "#/$defs/CJ1MetadataText"
      }, {
        "$ref" : "#/$defs/CJ1MetadataTime"
      } ]
    },
    "CJ1MetadataValueMatchAnyValue" : {
      "description" : "Match any metadata value.",
      "type" : "object",
      "properties" : {
        "@type" : {
          "type" : "string",
          "pattern" : "Anything"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1MetadataValueMatchIntegralType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataValueMatchIntegralWithinRange"
      } ]
    },
    "CJ1MetadataValueMatchIntegralWithinRange" : {
      "description" : "Match an integral metadata value within the given range.",
      "type" : "object",
      "properties" : {
        "lower" : {
          "description" : "The lower bound.",
          "$ref" : "#/$defs/long"
        },
        "upper" : {
          "description" : "The upper bound.",
          "$ref" : "#/$defs/long"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "IntegralWithinRange"
        }
      },
      "required" : [ "@type", "lower", "upper" ]
    },
    "CJ1MetadataValueMatchMonetaryType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataValueMatchMonetaryWithCurrency"
      }, {
        "$ref" : "#/$defs/CJ1MetadataValueMatchMonetaryWithinRange"
      } ]
    },
    "CJ1MetadataValueMatchMonetaryWithCurrency" : {
      "description" : "Match monetary metadata values with the given currency.",
      "type" : "object",
      "properties" : {
        "currency" : {
          "description" : "The currency unit.",
          "$ref" : "#/$defs/CurrencyUnit"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "MonetaryWithCurrency"
        }
      },
      "required" : [ "@type", "currency" ]
    },
    "CJ1MetadataValueMatchMonetaryWithinRange" : {
      "description" : "Match a monetary metadata value within the given range.",
      "type" : "object",
      "properties" : {
        "lower" : {
          "description" : "The lower bound.",
          "$ref" : "#/$defs/BigDecimal"
        },
        "upper" : {
          "description" : "The upper bound.",
          "$ref" : "#/$defs/BigDecimal"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "MonetaryWithinRange"
        }
      },
      "required" : [ "@type", "lower", "upper" ]
    },
    "CJ1MetadataValueMatchRealType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataValueMatchRealWithinRange"
      } ]
    },
    "CJ1MetadataValueMatchRealWithinRange" : {
      "description" : "Match a real metadata value within the given range.",
      "type" : "object",
      "properties" : {
        "lower" : {
          "description" : "The lower bound.",
          "$ref" : "#/$defs/double"
        },
        "upper" : {
          "description" : "The upper bound.",
          "$ref" : "#/$defs/double"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "RealWithinRange"
        }
      },
      "required" : [ "@type", "lower", "upper" ]
    },
    "CJ1MetadataValueMatchTextExact" : {
      "description" : "Match a text metadata value with the given text.",
      "type" : "object",
      "properties" : {
        "text" : {
          "description" : "The text value.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TextExact"
        }
      },
      "required" : [ "@type", "text" ]
    },
    "CJ1MetadataValueMatchTextSearch" : {
      "description" : "Match a text metadata value with the given search query.",
      "type" : "object",
      "properties" : {
        "query" : {
          "description" : "The search query.",
          "$ref" : "#/$defs/String"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TextSearch"
        }
      },
      "required" : [ "@type", "query" ]
    },
    "CJ1MetadataValueMatchTextType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataValueMatchTextExact"
      }, {
        "$ref" : "#/$defs/CJ1MetadataValueMatchTextSearch"
      } ]
    },
    "CJ1MetadataValueMatchTimeType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataValueMatchTimeWithinRange"
      } ]
    },
    "CJ1MetadataValueMatchTimeWithinRange" : {
      "description" : "Match a time metadata value within the given range.",
      "type" : "object",
      "properties" : {
        "lower" : {
          "description" : "The lower bound.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "upper" : {
          "description" : "The upper bound.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TimeWithinRange"
        }
      },
      "required" : [ "@type", "lower", "upper" ]
    },
    "CJ1MetadataValueMatchType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1MetadataValueMatchAnyValue"
      }, {
        "$ref" : "#/$defs/CJ1MetadataValueMatchIntegralType"
      }, {
        "$ref" : "#/$defs/CJ1MetadataValueMatchMonetaryType"
      }, {
        "$ref" : "#/$defs/CJ1MetadataValueMatchRealType"
      }, {
        "$ref" : "#/$defs/CJ1MetadataValueMatchTextType"
      }, {
        "$ref" : "#/$defs/CJ1MetadataValueMatchTimeType"
      } ]
    },
    "CJ1Page<CJ1AuditEvent>" : {
      "description" : "A page of results.",
      "type" : "object",
      "properties" : {
        "items" : {
          "description" : "The results.",
          "$ref" : "#/$defs/List<CJ1AuditEvent>"
        },
        "pageCount" : {
          "description" : "The total number of pages.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        },
        "pageFirstOffset" : {
          "description" : "The offset of the first result in the page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "pageIndex" : {
          "description" : "The page number.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        }
      },
      "required" : [ "items", "pageCount", "pageFirstOffset", "pageIndex" ]
    },
    "CJ1Page<CJ1FileWithoutData>" : {
      "description" : "A page of results.",
      "type" : "object",
      "properties" : {
        "items" : {
          "description" : "The results.",
          "$ref" : "#/$defs/List<CJ1FileWithoutData>"
        },
        "pageCount" : {
          "description" : "The total number of pages.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        },
        "pageFirstOffset" : {
          "description" : "The offset of the first result in the page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "pageIndex" : {
          "description" : "The page number.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        }
      },
      "required" : [ "items", "pageCount", "pageFirstOffset", "pageIndex" ]
    },
    "CJ1Page<CJ1ItemSummary>" : {
      "description" : "A page of results.",
      "type" : "object",
      "properties" : {
        "items" : {
          "description" : "The results.",
          "$ref" : "#/$defs/List<CJ1ItemSummary>"
        },
        "pageCount" : {
          "description" : "The total number of pages.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        },
        "pageFirstOffset" : {
          "description" : "The offset of the first result in the page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "pageIndex" : {
          "description" : "The page number.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        }
      },
      "required" : [ "items", "pageCount", "pageFirstOffset", "pageIndex" ]
    },
    "CJ1Page<CJ1StockOccurrenceType>" : {
      "description" : "A page of results.",
      "type" : "object",
      "properties" : {
        "items" : {
          "description" : "The results.",
          "$ref" : "#/$defs/List<CJ1StockOccurrenceType>"
        },
        "pageCount" : {
          "description" : "The total number of pages.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        },
        "pageFirstOffset" : {
          "description" : "The offset of the first result in the page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "pageIndex" : {
          "description" : "The page number.",
          "$ref" : "#/$defs/CJ1UnsignedInt"
        }
      },
      "required" : [ "items", "pageCount", "pageFirstOffset", "pageIndex" ]
    },
    "CJ1ResponseAuditSearch" : {
      "description" : "A response to AuditSearch.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "results" : {
          "$ref" : "#/$defs/CJ1Page<CJ1AuditEvent>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseAuditSearch"
        }
      },
      "required" : [ "@type", "requestId", "results" ]
    },
    "CJ1ResponseBlame" : {
      "type" : "string",
      "enum" : [ "BLAME_CLIENT", "BLAME_SERVER" ]
    },
    "CJ1ResponseError" : {
      "type" : "object",
      "properties" : {
        "attributes" : {
          "$ref" : "#/$defs/Map<String,String>"
        },
        "blame" : {
          "$ref" : "#/$defs/CJ1ResponseBlame"
        },
        "errorCode" : {
          "$ref" : "#/$defs/CAErrorCode"
        },
        "extras" : {
          "$ref" : "#/$defs/List<CJ1StructuredError>"
        },
        "message" : {
          "$ref" : "#/$defs/String"
        },
        "remediatingAction" : {
          "$ref" : "#/$defs/Optional<String>"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseError"
        }
      },
      "required" : [ "@type", "errorCode", "message", "requestId" ]
    },
    "CJ1ResponseFileDelete" : {
      "description" : "A response to FileDelete.",
      "type" : "object",
      "properties" : {
        "file" : {
          "$ref" : "#/$defs/UUID"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseFileDelete"
        }
      },
      "required" : [ "@type", "file", "requestId" ]
    },
    "CJ1ResponseFileGet" : {
      "description" : "A response to FileGet.",
      "type" : "object",
      "properties" : {
        "file" : {
          "$ref" : "#/$defs/CJ1FileWithoutData"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseFileGet"
        }
      },
      "required" : [ "@type", "file", "requestId" ]
    },
    "CJ1ResponseFilePut" : {
      "description" : "A response to FilePut.",
      "type" : "object",
      "properties" : {
        "file" : {
          "$ref" : "#/$defs/CJ1FileType"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseFilePut"
        }
      },
      "required" : [ "@type", "file", "requestId" ]
    },
    "CJ1ResponseFileSearch" : {
      "description" : "A response to FileSearch.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "results" : {
          "$ref" : "#/$defs/CJ1Page<CJ1FileWithoutData>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseFileSearch"
        }
      },
      "required" : [ "@type", "requestId", "results" ]
    },
    "CJ1ResponseItemAttachmentAdd" : {
      "description" : "A response to ItemAttachmentAdd.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemAttachmentAdd"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemAttachmentRemove" : {
      "description" : "A response to ItemAttachmentRemove.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemAttachmentRemove"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemCreate" : {
      "description" : "A response to ItemCreate.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemCreate"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemDelete" : {
      "description" : "A response to ItemDelete.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/UUID"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemDelete"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemGet" : {
      "description" : "A response to ItemGet.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemGet"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemMetadataPut" : {
      "description" : "A response to ItemMetadataPut.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemMetadataPut"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemMetadataRemove" : {
      "description" : "A response to ItemMetadataRemove.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemMetadataRemove"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemSearch" : {
      "description" : "A response to ItemSearch.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "results" : {
          "$ref" : "#/$defs/CJ1Page<CJ1ItemSummary>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemSearch"
        }
      },
      "required" : [ "@type", "requestId", "results" ]
    },
    "CJ1ResponseItemSetName" : {
      "description" : "A response to ItemSetName.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemSetName"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemTypesAssign" : {
      "description" : "A response to ItemTypesAssign.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemTypesAssign"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseItemTypesRevoke" : {
      "description" : "A response to ItemTypesRevoke.",
      "type" : "object",
      "properties" : {
        "item" : {
          "$ref" : "#/$defs/CJ1Item"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseItemTypesRevoke"
        }
      },
      "required" : [ "@type", "item", "requestId" ]
    },
    "CJ1ResponseLocationAttachmentAdd" : {
      "description" : "A response to LocationAttachmentAdd.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationAttachmentAdd"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationAttachmentRemove" : {
      "description" : "A response to LocationAttachmentRemove.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationAttachmentRemove"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationDelete" : {
      "description" : "A response to LocationDelete.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/UUID"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationDelete"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationGet" : {
      "description" : "A response to LocationGet.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationGet"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationList" : {
      "description" : "A response to LocationList.",
      "type" : "object",
      "properties" : {
        "locations" : {
          "$ref" : "#/$defs/Map<UUID,CJ1LocationSummary>"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationList"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseLocationMetadataPut" : {
      "description" : "A response to LocationMetadataPut.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationMetadataPut"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationMetadataRemove" : {
      "description" : "A response to LocationMetadataRemove.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationMetadataRemove"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationPut" : {
      "description" : "A response to LocationPut.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationPut"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationTypesAssign" : {
      "description" : "A response to LocationTypesAssign.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationTypesAssign"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLocationTypesRevoke" : {
      "description" : "A response to LocationTypesRevoke.",
      "type" : "object",
      "properties" : {
        "location" : {
          "$ref" : "#/$defs/CJ1Location"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLocationTypesRevoke"
        }
      },
      "required" : [ "@type", "location", "requestId" ]
    },
    "CJ1ResponseLogin" : {
      "description" : "A response to Login.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "userId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseLogin"
        }
      },
      "required" : [ "@type", "requestId", "userId" ]
    },
    "CJ1ResponseRolesAssign" : {
      "description" : "A response to RolesAssign.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseRolesAssign"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseRolesGet" : {
      "description" : "A response to RolesGet.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "roles" : {
          "$ref" : "#/$defs/Set<String>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseRolesGet"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseRolesRevoke" : {
      "description" : "A response to RolesRevoke.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseRolesRevoke"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseStockCount" : {
      "description" : "A response to StockCount.",
      "type" : "object",
      "properties" : {
        "count" : {
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseStockCount"
        }
      },
      "required" : [ "@type", "count", "requestId" ]
    },
    "CJ1ResponseStockReposit" : {
      "description" : "A response to StockReposit.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "stockOccurrence" : {
          "$ref" : "#/$defs/Optional<CJ1StockOccurrenceType>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseStockReposit"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseStockSearch" : {
      "description" : "A response to StockSearch.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "results" : {
          "$ref" : "#/$defs/CJ1Page<CJ1StockOccurrenceType>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseStockSearch"
        }
      },
      "required" : [ "@type", "requestId", "results" ]
    },
    "CJ1ResponseType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1ResponseAuditSearch"
      }, {
        "$ref" : "#/$defs/CJ1ResponseError"
      }, {
        "$ref" : "#/$defs/CJ1ResponseFileDelete"
      }, {
        "$ref" : "#/$defs/CJ1ResponseFileGet"
      }, {
        "$ref" : "#/$defs/CJ1ResponseFilePut"
      }, {
        "$ref" : "#/$defs/CJ1ResponseFileSearch"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemAttachmentAdd"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemAttachmentRemove"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemCreate"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemDelete"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemGet"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemMetadataPut"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemMetadataRemove"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemSearch"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemSetName"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemTypesAssign"
      }, {
        "$ref" : "#/$defs/CJ1ResponseItemTypesRevoke"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationAttachmentAdd"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationAttachmentRemove"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationDelete"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationGet"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationList"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationMetadataPut"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationMetadataRemove"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationPut"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationTypesAssign"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLocationTypesRevoke"
      }, {
        "$ref" : "#/$defs/CJ1ResponseLogin"
      }, {
        "$ref" : "#/$defs/CJ1ResponseRolesAssign"
      }, {
        "$ref" : "#/$defs/CJ1ResponseRolesGet"
      }, {
        "$ref" : "#/$defs/CJ1ResponseRolesRevoke"
      }, {
        "$ref" : "#/$defs/CJ1ResponseStockCount"
      }, {
        "$ref" : "#/$defs/CJ1ResponseStockReposit"
      }, {
        "$ref" : "#/$defs/CJ1ResponseStockSearch"
      }, {
        "$ref" : "#/$defs/CJ1ResponseTypePackageGetText"
      }, {
        "$ref" : "#/$defs/CJ1ResponseTypePackageInstall"
      }, {
        "$ref" : "#/$defs/CJ1ResponseTypePackageSearch"
      }, {
        "$ref" : "#/$defs/CJ1ResponseTypePackageUninstall"
      }, {
        "$ref" : "#/$defs/CJ1ResponseTypePackageUpgrade"
      } ]
    },
    "CJ1ResponseTypePackageGetText" : {
      "description" : "A response to TypePackageGetText.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseTypePackageGetText"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseTypePackageInstall" : {
      "description" : "A response to TypePackageInstall.",
      "type" : "object",
      "properties" : {
        "identifier" : {
          "$ref" : "#/$defs/CJ1TypePackageIdentifier"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseTypePackageInstall"
        }
      },
      "required" : [ "@type", "identifier", "requestId" ]
    },
    "CJ1ResponseTypePackageSearch" : {
      "description" : "A response to TypePackageSearch.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseTypePackageSearch"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseTypePackageUninstall" : {
      "description" : "A response to TypePackageUninstall.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseTypePackageUninstall"
        }
      },
      "required" : [ "@type", "requestId" ]
    },
    "CJ1ResponseTypePackageUpgrade" : {
      "description" : "A response to TypePackageUpgrade.",
      "type" : "object",
      "properties" : {
        "identifier" : {
          "$ref" : "#/$defs/CJ1TypePackageIdentifier"
        },
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "ResponseTypePackageUpgrade"
        }
      },
      "required" : [ "@type", "identifier", "requestId" ]
    },
    "CJ1SizeRange" : {
      "type" : "object",
      "properties" : {
        "sizeMaximum" : {
          "description" : "The inclusive upper bound.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "sizeMinimum" : {
          "description" : "The inclusive lower bound.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        }
      },
      "required" : [ "sizeMaximum", "sizeMinimum" ]
    },
    "CJ1StockOccurrenceKind" : {
      "type" : "string",
      "enum" : [ "SERIAL", "SET" ]
    },
    "CJ1StockOccurrenceSerial" : {
      "type" : "object",
      "properties" : {
        "instance" : {
          "$ref" : "#/$defs/UUID"
        },
        "item" : {
          "$ref" : "#/$defs/CJ1ItemSummary"
        },
        "location" : {
          "$ref" : "#/$defs/CJ1LocationSummary"
        },
        "serials" : {
          "$ref" : "#/$defs/List<CJ1ItemSerial>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Serial"
        }
      },
      "required" : [ "@type", "instance", "item", "location" ]
    },
    "CJ1StockOccurrenceSet" : {
      "type" : "object",
      "properties" : {
        "count" : {
          "$ref" : "#/$defs/long"
        },
        "instance" : {
          "$ref" : "#/$defs/UUID"
        },
        "item" : {
          "$ref" : "#/$defs/CJ1ItemSummary"
        },
        "location" : {
          "$ref" : "#/$defs/CJ1LocationSummary"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Set"
        }
      },
      "required" : [ "@type", "count", "instance", "item", "location" ]
    },
    "CJ1StockOccurrenceType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1StockOccurrenceSerial"
      }, {
        "$ref" : "#/$defs/CJ1StockOccurrenceSet"
      } ]
    },
    "CJ1StockRepositRemove" : {
      "description" : "Remove the given stock occurrence.",
      "type" : "object",
      "properties" : {
        "instance" : {
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Remove"
        }
      },
      "required" : [ "@type", "instance" ]
    },
    "CJ1StockRepositSerialIntroduce" : {
      "description" : "Introduce a new serial stock occurrence.",
      "type" : "object",
      "properties" : {
        "instance" : {
          "description" : "The stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "item" : {
          "description" : "The item.",
          "$ref" : "#/$defs/UUID"
        },
        "location" : {
          "description" : "The location.",
          "$ref" : "#/$defs/UUID"
        },
        "serial" : {
          "description" : "The serial number.",
          "$ref" : "#/$defs/CJ1ItemSerial"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SerialIntroduce"
        }
      },
      "required" : [ "@type", "instance", "item", "location", "serial" ]
    },
    "CJ1StockRepositSerialMove" : {
      "description" : "Move a serial stock occurrence to a new location.",
      "type" : "object",
      "properties" : {
        "instance" : {
          "description" : "The stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "toLocation" : {
          "description" : "The new location.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SerialMove"
        }
      },
      "required" : [ "@type", "instance", "toLocation" ]
    },
    "CJ1StockRepositSerialNumberAdd" : {
      "description" : "Add a new serial number to a stock occurrence.",
      "type" : "object",
      "properties" : {
        "instance" : {
          "description" : "The stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "serial" : {
          "description" : "The serial number.",
          "$ref" : "#/$defs/CJ1ItemSerial"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SerialNumberAdd"
        }
      },
      "required" : [ "@type", "instance", "serial" ]
    },
    "CJ1StockRepositSerialNumberRemove" : {
      "description" : "Remove a serial number from a stock occurrence.",
      "type" : "object",
      "properties" : {
        "instance" : {
          "description" : "The stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "serial" : {
          "description" : "The serial number.",
          "$ref" : "#/$defs/CJ1ItemSerial"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SerialNumberRemove"
        }
      },
      "required" : [ "@type", "instance", "serial" ]
    },
    "CJ1StockRepositSetAdd" : {
      "description" : "Add to an existing set stock occurrence.",
      "type" : "object",
      "properties" : {
        "count" : {
          "description" : "The number of items to add.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "instance" : {
          "description" : "The stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SetAdd"
        }
      },
      "required" : [ "@type", "count", "instance" ]
    },
    "CJ1StockRepositSetIntroduce" : {
      "description" : "Introduce a new set stock occurrence.",
      "type" : "object",
      "properties" : {
        "count" : {
          "description" : "The number of items to introduce.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "instance" : {
          "description" : "The stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "item" : {
          "description" : "The item.",
          "$ref" : "#/$defs/UUID"
        },
        "location" : {
          "description" : "The location.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SetIntroduce"
        }
      },
      "required" : [ "@type", "count", "instance", "item", "location" ]
    },
    "CJ1StockRepositSetMove" : {
      "description" : "Move between stock occurrences.",
      "type" : "object",
      "properties" : {
        "count" : {
          "description" : "The number of items to move.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "instanceSource" : {
          "description" : "The source stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "instanceTarget" : {
          "description" : "The target stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "toLocation" : {
          "description" : "The new location.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SetMove"
        }
      },
      "required" : [ "@type", "count", "instanceSource", "instanceTarget", "toLocation" ]
    },
    "CJ1StockRepositSetRemove" : {
      "description" : "Remove from a set stock occurrence.",
      "type" : "object",
      "properties" : {
        "count" : {
          "description" : "The number of items to remove.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        },
        "instance" : {
          "description" : "The stock occurrence.",
          "$ref" : "#/$defs/UUID"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "SetRemove"
        }
      },
      "required" : [ "@type", "count", "instance" ]
    },
    "CJ1StockRepositType" : {
      "oneOf" : [ {
        "$ref" : "#/$defs/CJ1StockRepositRemove"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSerialIntroduce"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSerialMove"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSerialNumberAdd"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSerialNumberRemove"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSetAdd"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSetIntroduce"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSetMove"
      }, {
        "$ref" : "#/$defs/CJ1StockRepositSetRemove"
      } ]
    },
    "CJ1StockSearchParameters" : {
      "description" : "Parameters to search for stock.",
      "type" : "object",
      "properties" : {
        "includeDeleted" : {
          "description" : "Include deleted stock.",
          "$ref" : "#/$defs/CJ1IncludeDeleted"
        },
        "includeOccurrences" : {
          "description" : "Include stock of the given occurrence kinds.",
          "$ref" : "#/$defs/Set<CJ1StockOccurrenceKind>"
        },
        "matchItem" : {
          "description" : "Include stock with items matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonExactType<UUID>"
        },
        "matchLocation" : {
          "description" : "Include stock with locations matching the given expression.",
          "$ref" : "#/$defs/CJ1LocationMatchType"
        },
        "pageSize" : {
          "description" : "The maximum number of results per page.",
          "$ref" : "#/$defs/CJ1UnsignedLong"
        }
      },
      "required" : [ "includeDeleted", "includeOccurrences", "matchItem", "matchLocation", "pageSize" ]
    },
    "CJ1StructuredError" : {
      "description" : "A structured error value.",
      "type" : "object",
      "properties" : {
        "attributes" : {
          "description" : "The error attributes.",
          "$ref" : "#/$defs/Map<String,String>"
        },
        "errorCode" : {
          "description" : "The error code.",
          "$ref" : "#/$defs/String"
        },
        "message" : {
          "description" : "The error message.",
          "$ref" : "#/$defs/String"
        },
        "remediatingAction" : {
          "description" : "The remediating action.",
          "$ref" : "#/$defs/Optional<String>"
        }
      },
      "required" : [ "errorCode", "message" ]
    },
    "CJ1TimeRange" : {
      "description" : "A range of time.",
      "type" : "object",
      "properties" : {
        "lower" : {
          "description" : "The inclusive lower bound.",
          "$ref" : "#/$defs/OffsetDateTime"
        },
        "upper" : {
          "description" : "The inclusive upper bound.",
          "$ref" : "#/$defs/OffsetDateTime"
        }
      },
      "required" : [ "lower", "upper" ]
    },
    "CJ1Transaction" : {
      "description" : "A set of commands to execute in a single transaction.",
      "type" : "object",
      "properties" : {
        "commands" : {
          "description" : "The commands that will be executed in the given order.",
          "$ref" : "#/$defs/List<CJ1CommandType>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "Transaction"
        }
      },
      "required" : [ "@type" ]
    },
    "CJ1TransactionResponse" : {
      "description" : "A transaction response.",
      "type" : "object",
      "properties" : {
        "requestId" : {
          "$ref" : "#/$defs/UUID"
        },
        "responses" : {
          "description" : "The command responses.",
          "$ref" : "#/$defs/List<CJ1ResponseType>"
        },
        "@type" : {
          "type" : "string",
          "pattern" : "TransactionResponse"
        }
      },
      "required" : [ "@type", "requestId", "responses" ]
    },
    "CJ1TypePackageIdentifier" : {
      "description" : "A type package identifier.",
      "type" : "string"
    },
    "CJ1TypePackageSearchParameters" : {
      "description" : "Parameters to search for type packages.",
      "type" : "object",
      "properties" : {
        "matchDescription" : {
          "description" : "Include packages with descriptions matching the given expression.",
          "$ref" : "#/$defs/CJ1ComparisonFuzzyType<String>"
        },
        "pageSize" : {
          "description" : "The maximum number of results per page.",
          "$ref" : "#/$defs/long"
        }
      },
      "required" : [ "matchDescription", "pageSize" ]
    },
    "CJ1TypePackageTypeRemovalBehavior" : {
      "description" : "Type package removal behavior.",
      "type" : "string",
      "enum" : [ "TYPE_REMOVAL_FAIL_IF_TYPES_REFERENCED", "TYPE_REMOVAL_REVOKE_TYPES" ]
    },
    "CJ1TypePackageUninstall" : {
      "description" : "Parameters for uninstalling type packages.",
      "type" : "object",
      "properties" : {
        "packageIdentifier" : {
          "description" : "The type package identifier.",
          "$ref" : "#/$defs/CJ1TypePackageIdentifier"
        },
        "typeRemovalBehavior" : {
          "description" : "The type removal behavior.",
          "$ref" : "#/$defs/CJ1TypePackageTypeRemovalBehavior"
        }
      },
      "required" : [ "packageIdentifier", "typeRemovalBehavior" ]
    },
    "CJ1TypePackageVersionBehavior" : {
      "description" : "Type package version behavior.",
      "type" : "string",
      "enum" : [ "VERSION_ALLOW_DOWNGRADES", "VERSION_DISALLOW_DOWNGRADES" ]
    },
    "CJ1TypeRecordFieldIdentifier" : {
      "description" : "A type record field identifier.",
      "type" : "string"
    },
    "CJ1TypeRecordIdentifier" : {
      "description" : "A type record identifier.",
      "type" : "string"
    },
    "CJ1UnsignedInt" : {
      "description" : "A 32-bit unsigned integer value.",
      "type" : "number",
      "minimum" : 0,
      "exclusiveMaximum" : 4294967296
    },
    "CJ1UnsignedLong" : {
      "description" : "A 64-bit unsigned integer value.",
      "type" : "number",
      "minimum" : 0,
      "exclusiveMaximum" : 18446744073709551616
    },
    "CurrencyUnit" : {
      "description" : "An ISO 4217 currency code.",
      "type" : "string",
      "pattern" : "[A-Z][A-Z][A-Z]"
    },
    "List<CJ1AttachmentItem>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1AttachmentItem"
      }
    },
    "List<CJ1AuditEvent>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1AuditEvent"
      }
    },
    "List<CJ1CommandType>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1CommandType"
      }
    },
    "List<CJ1FileWithoutData>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1FileWithoutData"
      }
    },
    "List<CJ1ItemSerial>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1ItemSerial"
      }
    },
    "List<CJ1ItemSummary>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1ItemSummary"
      }
    },
    "List<CJ1ResponseType>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1ResponseType"
      }
    },
    "List<CJ1StockOccurrenceType>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1StockOccurrenceType"
      }
    },
    "List<CJ1StructuredError>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1StructuredError"
      }
    },
    "List<String>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/String"
      }
    },
    "Map<CJ1TypeRecordFieldIdentifier,CJ1MetadataType>" : {
      "type" : "object",
      "additionalProperties" : {
        "$ref" : "#/$defs/CJ1MetadataType"
      }
    },
    "Map<String,String>" : {
      "type" : "object",
      "additionalProperties" : {
        "$ref" : "#/$defs/String"
      }
    },
    "Map<UUID,CJ1LocationSummary>" : {
      "type" : "object",
      "additionalProperties" : {
        "$ref" : "#/$defs/CJ1LocationSummary"
      }
    },
    "OffsetDateTime" : {
      "description" : "An ISO 8601 timestamp.",
      "type" : "string",
      "format" : "date-time"
    },
    "Optional<CJ1StockOccurrenceType>" : {
      "$ref" : "#/$defs/CJ1StockOccurrenceType"
    },
    "Optional<String>" : {
      "$ref" : "#/$defs/String"
    },
    "Optional<UUID>" : {
      "$ref" : "#/$defs/UUID"
    },
    "RDottedName" : {
      "type" : "string",
      "description" : "A Lanark dotted name.",
      "pattern" : "([a-z][a-z0-9_-]{0,63})(\\.[a-z][a-z0-9_-]{0,62}){0,15}"
    },
    "Set<CJ1MetadataType>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1MetadataType"
      }
    },
    "Set<CJ1StockOccurrenceKind>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1StockOccurrenceKind"
      }
    },
    "Set<CJ1TypeRecordFieldIdentifier>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1TypeRecordFieldIdentifier"
      }
    },
    "Set<CJ1TypeRecordIdentifier>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/CJ1TypeRecordIdentifier"
      }
    },
    "Set<String>" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/$defs/String"
      }
    },
    "String" : {
      "type" : "string"
    },
    "UUID" : {
      "description" : "An RFC 9562 UUID string.",
      "type" : "string",
      "format" : "uuid"
    },
    "boolean" : { },
    "byte[]" : {
      "description" : "An RFC 4648 'standard' base64 encoded byte array.",
      "type" : "string",
      "format" : "base64"
    },
    "double" : { },
    "long" : { }
  }
}

9. Security

9.1. Overview

9.2. Security

9.2.1. Overview

9.2.2. Security Policy Violations

9.1. Overview

This section of the manual attempts to describe the security properties of the cardant server.

9.2. Security

9.2.1. Overview

9.2.2. Security Policy Violations

9.2.1. Overview

All command execution in the cardant server passes through a single code path that captures OpenTelemetry traces and publishes events. Administrators should write alerting rules in their metrics system of choice to watch for instances of the traces, metrics, and events described here; they almost certainly indicate malicious behaviour.

At the time of writing, events are published as part of a containing trace, and therefore the server must be configured to publish traces in order for an external monitoring system to be able to observe the events. The reason for this is that the OpenTelemetry Events API specification is not yet stable and so traces are currently the only way to publish events. It is expected that a stable version of the Events API will be released soon, and then the cardant server will switch to using that API directly (and this will require only log telemetry to be configured as opposed to full trace collection).

9.2.2. Security Policy Violations

If an operation attempts to violate the server's built-in security policy, an exception will be raised with an cardant.errorCode attribute set to error-security-policy-denied.

10. Appendix: Schema: Type Package 1.0

Type packages are serialized using the following XML schema:

10.2. Type Package 1.0

<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:p="com.io7m.cardant:type_packages:1"
            targetNamespace="com.io7m.cardant:type_packages:1">

  <xsd:simpleType name="UnqualifiedNameType">
    <xsd:annotation>
      <xsd:documentation>
        The type of unqualified names.
      </xsd:documentation>
    </xsd:annotation>

    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-z][a-z0-9_-]{0,62}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="PackageNameType">
    <xsd:annotation>
      <xsd:documentation>
        The type of fully qualified package names.
      </xsd:documentation>
    </xsd:annotation>

    <xsd:restriction base="xsd:string">
      <xsd:pattern value="([a-z][a-z0-9_-]{0,63})(\.[a-z][a-z0-9_-]{0,62}){0,15}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="PackageVersionType">
    <xsd:annotation>
      <xsd:documentation>
        The type of package versions.
      </xsd:documentation>
    </xsd:annotation>

    <xsd:restriction base="xsd:string">
      <xsd:pattern value="([0-9]+)\.([0-9]+)\.([0-9]+)(-(.+))?"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:element name="PackageInfo">
    <xsd:complexType>
      <xsd:attribute name="Name"
                     type="p:PackageNameType"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The name of the package.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
      <xsd:attribute name="Version"
                     type="p:PackageVersionType"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The version of the package.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
      <xsd:attribute name="Description"
                     type="xsd:string"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The description of the package.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="VersionRange">
    <xsd:complexType>
      <xsd:attribute name="VersionLower"
                     type="p:PackageVersionType"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The lower bound on the versions of the imported package.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
      <xsd:attribute name="VersionLowerInclusive"
                     type="xsd:boolean"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The lower bound is inclusive.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
      <xsd:attribute name="VersionUpper"
                     type="p:PackageVersionType"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The upper bound on the versions of the imported package.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
      <xsd:attribute name="VersionUpperInclusive"
                     type="xsd:boolean"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The upper bound is inclusive.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="Import">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="p:VersionRange"/>
      </xsd:sequence>

      <xsd:attribute name="Package"
                     type="p:PackageNameType"
                     use="required">
        <xsd:annotation>
          <xsd:documentation>
            The name of the imported package.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="TypeDeclarationType"
                   abstract="true">
    <xsd:annotation>
      <xsd:documentation>
        The base type of type declarations.
      </xsd:documentation>
    </xsd:annotation>

    <xsd:attribute name="Name"
                   type="p:UnqualifiedNameType"
                   use="required">
      <xsd:annotation>
        <xsd:documentation>
          The name of the type.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>

    <xsd:attribute name="Description"
                   type="xsd:string"
                   use="required">
      <xsd:annotation>
        <xsd:documentation>
          The humanly-readable description of the type.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
  </xsd:complexType>

  <xsd:complexType name="TypeScalarType"
                   abstract="true">
    <xsd:complexContent>
      <xsd:extension base="p:TypeDeclarationType">
        <xsd:annotation>
          <xsd:documentation>
            A declaration of a scalar type.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:complexType name="TypeScalarTextType">
    <xsd:complexContent>
      <xsd:extension base="p:TypeScalarType">
        <xsd:annotation>
          <xsd:documentation>
            A declaration of a scalar text type.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:attribute name="Pattern"
                       type="xsd:string"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The pattern that constrains text values.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TypeScalarText"
               type="p:TypeScalarTextType">
    <xsd:annotation>
      <xsd:documentation>
        A declaration of a scalar text type.
      </xsd:documentation>
    </xsd:annotation>
  </xsd:element>

  <xsd:complexType name="TypeScalarIntegralType">
    <xsd:complexContent>
      <xsd:extension base="p:TypeScalarType">
        <xsd:annotation>
          <xsd:documentation>
            A declaration of a scalar integral type.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:attribute name="RangeLower"
                       type="xsd:long"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The lower inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>

        <xsd:attribute name="RangeUpper"
                       type="xsd:long"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The upper inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TypeScalarIntegral"
               type="p:TypeScalarIntegralType">
    <xsd:annotation>
      <xsd:documentation>
        A declaration of a scalar integral type.
      </xsd:documentation>
    </xsd:annotation>
  </xsd:element>

  <xsd:complexType name="TypeScalarRealType">
    <xsd:complexContent>
      <xsd:extension base="p:TypeScalarType">
        <xsd:annotation>
          <xsd:documentation>
            A declaration of a scalar real type.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:attribute name="RangeLower"
                       type="xsd:double"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The lower inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>

        <xsd:attribute name="RangeUpper"
                       type="xsd:double"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The upper inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TypeScalarReal"
               type="p:TypeScalarRealType">
    <xsd:annotation>
      <xsd:documentation>
        A declaration of a scalar real type.
      </xsd:documentation>
    </xsd:annotation>
  </xsd:element>

  <xsd:complexType name="TypeScalarTimeType">
    <xsd:complexContent>
      <xsd:extension base="p:TypeScalarType">
        <xsd:annotation>
          <xsd:documentation>
            A declaration of a scalar time type.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:attribute name="RangeLower"
                       type="xsd:dateTime"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The lower inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>

        <xsd:attribute name="RangeUpper"
                       type="xsd:dateTime"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The upper inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TypeScalarTime"
               type="p:TypeScalarTimeType">
    <xsd:annotation>
      <xsd:documentation>
        A declaration of a scalar time type.
      </xsd:documentation>
    </xsd:annotation>
  </xsd:element>

  <xsd:complexType name="TypeScalarMonetaryType">
    <xsd:complexContent>
      <xsd:extension base="p:TypeScalarType">
        <xsd:annotation>
          <xsd:documentation>
            A declaration of a scalar monetary type.
          </xsd:documentation>
        </xsd:annotation>

        <xsd:attribute name="RangeLower"
                       type="xsd:decimal"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The lower inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>

        <xsd:attribute name="RangeUpper"
                       type="xsd:decimal"
                       use="required">
          <xsd:annotation>
            <xsd:documentation>
              The upper inclusive bound.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="TypeScalarMonetary"
               type="p:TypeScalarMonetaryType">
    <xsd:annotation>
      <xsd:documentation>
        A declaration of a scalar monetary type.
      </xsd:documentation>
    </xsd:annotation>
  </xsd:element>

  <xsd:complexType name="TypeFieldType"
                   abstract="true">
    <xsd:attribute name="Name"
                   type="p:UnqualifiedNameType"
                   use="required">
      <xsd:annotation>
        <xsd:documentation>
          The name of the record field.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>

    <xsd:attribute name="Required"
                   type="xsd:boolean"
                   default="true">
      <xsd:annotation>
        <xsd:documentation>
          Whether the record field is required to be present.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>

    <xsd:attribute name="Description"
                   type="xsd:string"
                   use="required">
      <xsd:annotation>
        <xsd:documentation>
          A description of the record field.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
  </xsd:complexType>

  <xsd:complexType name="TypeFieldLocalType">
    <xsd:annotation>
      <xsd:documentation>
        A field that refers to a type within this package.
      </xsd:documentation>
    </xsd:annotation>

    <xsd:complexContent>
      <xsd:extension base="p:TypeFieldType">
        <xsd:attribute name="Type"
                       use="required"
                       type="p:UnqualifiedNameType">
          <xsd:annotation>
            <xsd:documentation>
              The scalar type of the field.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="Field"
               type="p:TypeFieldLocalType"/>

  <xsd:complexType name="TypeFieldWithExternalTypeType">
    <xsd:annotation>
      <xsd:documentation>
        A field that refers to a type within another package.
      </xsd:documentation>
    </xsd:annotation>

    <xsd:complexContent>
      <xsd:extension base="p:TypeFieldType">
        <xsd:attribute name="Package"
                       use="required"
                       type="p:PackageNameType">
          <xsd:annotation>
            <xsd:documentation>
              The package containing the target type.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>

        <xsd:attribute name="Type"
                       use="required"
                       type="p:UnqualifiedNameType">
          <xsd:annotation>
            <xsd:documentation>
              The scalar type of the field.
            </xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="FieldWithExternalType"
               type="p:TypeFieldWithExternalTypeType"/>

  <xsd:group name="TypeFieldGroup">
    <xsd:choice>
      <xsd:element ref="p:Field"/>
      <xsd:element ref="p:FieldWithExternalType"/>
    </xsd:choice>
  </xsd:group>

  <xsd:element name="TypeRecord">
    <xsd:complexType>
      <xsd:annotation>
        <xsd:documentation>
          A declaration of a record type.
        </xsd:documentation>
      </xsd:annotation>

      <xsd:complexContent>
        <xsd:extension base="p:TypeDeclarationType">
          <xsd:group ref="p:TypeFieldGroup"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>

    <xsd:unique name="TypeRecordFieldsUnique">
      <xsd:selector xpath="p:Field|p:FieldWithExternalType"/>
      <xsd:field xpath="@Name"/>
    </xsd:unique>
  </xsd:element>

  <xsd:group name="TypeDeclarationGroup">
    <xsd:choice>
      <xsd:element ref="p:TypeRecord"/>
      <xsd:element ref="p:TypeScalarIntegral"/>
      <xsd:element ref="p:TypeScalarMonetary"/>
      <xsd:element ref="p:TypeScalarReal"/>
      <xsd:element ref="p:TypeScalarText"/>
      <xsd:element ref="p:TypeScalarTime"/>
    </xsd:choice>
  </xsd:group>

  <xsd:element name="Package">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="p:PackageInfo"/>
        <xsd:sequence minOccurs="0"
                      maxOccurs="unbounded">
          <xsd:element ref="p:Import"/>
        </xsd:sequence>
        <xsd:sequence minOccurs="0"
                      maxOccurs="unbounded">
          <xsd:group ref="p:TypeDeclarationGroup"/>
        </xsd:sequence>
      </xsd:sequence>
    </xsd:complexType>

    <xsd:key name="TypeScalarsUnique">
      <xsd:annotation>
        <xsd:documentation>
          Scalar types must be uniquely named within a package.
        </xsd:documentation>
      </xsd:annotation>
      <xsd:selector xpath="p:TypeScalarIntegral|p:TypeScalarMonetary|p:TypeScalarReal|p:TypeScalarText|p:TypeScalarTime"/>
      <xsd:field xpath="@Name"/>
    </xsd:key>

    <xsd:key name="TypeRecordsUnique">
      <xsd:annotation>
        <xsd:documentation>
          Record types must be uniquely named within a package.
        </xsd:documentation>
      </xsd:annotation>
      <xsd:selector xpath="p:TypeRecord"/>
      <xsd:field xpath="@Name"/>
    </xsd:key>

    <xsd:key name="ImportsUnique">
      <xsd:annotation>
        <xsd:documentation>
          Imports must be unique within a package.
        </xsd:documentation>
      </xsd:annotation>
      <xsd:selector xpath="p:Import"/>
      <xsd:field xpath="@Package"/>
    </xsd:key>
  </xsd:element>

</xsd:schema>