# Document Index

### Index storage

Using a smart contract as a document and data index repository provides high availability, fault tolerance, immutability.

#### User (patient)

* user\_id - unique identifier
* user key pair - public key + private key, generated according to the Curve25519 elliptic curve-based cryptosystem

#### EHR (electronic health record)

Is a data structure described in the openEHR standard

* ehr\_id
* includes the documents: EHR\_STATUS, COMPOSITION, DIRECTORY, CONTRIBUTION

Each patient can have only one EHR.

#### EHR index

Sets the relationship between `ehr_id` from a specified `user_id`

#### Document index

```solidity
mapping (bytes32  => mapping(IDocs.Type => IDocs.DocumentMeta[])) ehrDocs;
```

<figure><img src="https://user-images.githubusercontent.com/8058268/190381195-7c48fe96-8f75-4d2d-a9a2-3737838ae42c.svg" alt=""><figcaption></figcaption></figure>

Sets the relationship between`doc_storage_id` and `ehr_id`

```
DocumentMeta: {
    Status    uint8
    Id        []byte
    Version   []byte
    Timestamp uint32
    IsLast    bool
    Attrs     []AttributesAttribute
}
```

#### EHRsubject index

Sets the relationship between `ehr_id` and `subject_id`, `subject_namespace`

```
subjectKey = sha3(subject_id + subject_namespace)

subjectKey -> ehr_id
```

#### docAccess index

Allows to find an encrypted `doc_key` for the specified `doc_storage_id` and `user_id`

```
key = sha3(doc_storage_id+user_id)
value = user_pub_key.Encrypt(doc_key)

key -> value
```

#### dataSearch index

Allows to find the `doc_storage_id` of documents that contain data with the specified values

```
DataEntry: {
    groupId        [16]byte   // UUID
    value          []byte     // encrypted values
    docStorIdEncr  []byte     // user_pub_key.Encrypt(doc_storage_id)
}

pathKey = sha3(path)    // path Example: '/data/events[at0006]/data/items[at0004]/value/magnitude'
pathKey  -> DataEntry
```

#### dataAccess index

`access_group` - access group, within which encrypted data is searched

```
key = sha3(user_id+access_group_id)
value = user_pub_key.Encrypt(access_group_key)

key -> value
```

### Creating EHR

1. An EHR document is created as a json file
2. Generation of a new `doc_key`
3. The document is encrypted using the `doc_key`
4. Document is saved in the document storage, `doc_storage_id` is returned
5. An entry is added to the EHR Index to link the patient and their EHR:
6. An entry is added to the Document Index to allow the document in the repository to be linked to the EHR
7. An entry is added to the EHRsubject Index to search for `ehr_id` by its subject
8. An entry is added to the AccessStore index to find the encrypted `doc_key` from the document

### Getting EHR by ehr\_id

1. Get `ehr_id` using `user_id` in EHR Index
2. Get `doc_storage_id` of a document with DocType = EHR
3. Get the encrypted `doc_key` from the AccessStore index
4. Decrypt `doc_key` with user's `priv_key`
5. Download document with `doc_storage_id` from storage
6. Decrypt the document using the decrypted `doc_key` in step 5

### Creating COMPOSITION

1. The document is created as a json file
2. The document is encrypted with the unique key `doc_key`
3. The document is saved in the document storage, `doc_storage_id` is returned
4. An entry is added to the document index, allowing you to link the document in the repository with the EHR
5. Path construction for all field values within the document
6. Determining the `access_group` for searching the values in the dataSearch index
7. Records containing paths, values encrypted with `access_group_key` and `encrypted doc_storage_id` to associate records with documents in the repository and `access_group_id` are added to the dataSearch Index for all values

### Search for documents using queries

1. Paths to the values of interest and conditions are generated from the query
2. Search for records in dataSearch index, which satisfy the specified conditions, the encrypted `doc_storage_id` of documents containing these values is returned, or the encrypted values
3. Search for an `access_group_key` in the dataAccess index
4. Decrypting `access_group_key` with `user_priv_key`
5. Decrypting field values with `access_group_key`
6. Decrypting `doc_storage_id` with `user_priv_key`
7. Search for `doc_keys` encrypted documents in the docAccess index by `doc_storage_id`
8. Decrypting `doc_keys`
9. Downloading found documents from the storage
10. Documents are decrypted using `doc_keys`
