### User This structure refers to all the users registered in the platform and contains generic (common) fields. **Firestore Collection** ``` users/{userId}/ ``` **Security Rules** ``` match /users/{userId}/{document=**} { allow write: if loggedIn() && userId == request.auth.uid ; allow read: if loggedIn(); } ``` FIELDS >>> `userId`: **String** `type`: **String** {**[USER_TYPE](#user_type)**} `organizations`: **Array<**String**>** `disabled`: **Boolean** `deleted`: **Boolean** `visible`: **Boolean** `available`: **Boolean** `providers`: **Array<**String**>** `customMetadata`: **Map** `legal`: **Map** `createdAt`: **Map** `deletedAt`: **Map** `lastActivity`: **Map** `profile`: **[Profile](#profile)** `searchFields`: **[SearchFields](#searchfields)** `professionalData`: **Map** >>> #### Profile Information about user FIELDS >>> `email` **String** `firstName` **String** `lastName` **String** `gender` **String** `profilePicture` **Map** `ssn` **String** `yearOfBirth` **String** `height` **String** `weight` **String** `mobilePhone` **String** >>> #### ProfessionalData Professional specific information FIELDS >>> `appointmentDuration`: **num** `addresses`: **Array** `description`: **String** `experience`: **String** `medicalAssociation`: **String** `specialty`: **Map** `availability`: **Map** `studies`: **String** `assistants`: **Array** `professionalPricing`: **String** >>> #### Settings This structure refers to the specific user settings in the application In the settings are kept the user's favorite doctors also. RTDB Path: `settings/{userId}/` FIELDS **key** `userid` **String** >>> `language` **String** `timezone` **String** `country` **String** `units` **[Units](#units)** >>> **Security Rules** ``` "settings":{ "$uid":{ ".read":"auth != null && auth.uid == $uid", ".write":"auth != null && auth.uid == $uid" } } ``` #### Units FIELDS >>> `distance` {`meters`, `feet`} `length` {`cm`, `inch`} `mass` {`kg`, `lbs`} `temperature` {`Celsius`, `Fahrenheit`} >>> #### USER_TYPE >>> - `user` - `doctor` - `carer` - `nutritionist` - `psychologist` - `physiotherapist` - `nurse` - `supervisor` - `admin` >>> --- ### ProfessionalNotes These entries represent the private information and notes that the professionals keep for each one of their patients. Firestore Collection: `professionalNotes/{professionalNoteId}/` FIELDS >>> `age` **String** `Icd10` **Array<[Icd10](#icd10)>** `notes` **Array<{createdAt: int, note: String}>** `patientId` **String** `professionalId` **String** `summary` **String** `tags` **Array\<String\>** >>> **Security Rules** ``` match /doctorNotes/{doctorNoteId}/{document=**} { allow create,update: if loggedIn() && (request.auth.uid == request.resource.data.professionalId) ; allow delete, read: if loggedIn() && (request.auth.uid == resource.data.professionalId) ; } ``` #### Icd10 ICD10 structure is based on the structure that the [Ministry of Health](https://www.moh.gov.gr/articles/health/domes-kai-draseis-gia-thn-ygeia/articles/ken-eswteriko/713-kwdikopoihseis) provides. Each icd10 object has an id and a description. FIELDS >>> `ref` **String** `description` **String** >>> --- ### ProfessionalInstructions These entries represent the instructions set and sent to the patients from the professionals Firestore Collection: `professionalInstructions/{instuctionId}/` FIELDS >>> `multimedia` **Map<String, Multimedia>** `medication` **Array<[Medication](#medication)>** `other` **String** `patientId` **String** `professionalId` **String** `firestoreKey` **String** `emergency` **bool** `notFeelingWell` **bool** `tags` **List** `stickyNote` **StickyNote** >>> **Security Rules** ``` match /professionalInstructions/{doctorInstructionId}/{document=**} { allow create,update: if loggedIn() && (request.auth.uid == request.resource.data.professionalId) ; allow delete: if loggedIn() && (request.auth.uid == resource.data.professionalId) ; allow read: if loggedIn() && (request.auth.uid == resource.data.professionalId || request.auth.uid == resource.data.patientId) ; } ``` #### Medication Medication structure is based on the structure that the [Ministry of Health](https://www.moh.gov.gr/articles/times-farmakwn/deltia-timwn/8147-deltio-anathewrhmenwn-timwn-farmakwn-anthrwpinhs-xrhshs-dekembrioy-2020) provides. FIELDS >>> `barcode` **int** `description` **String** `atc` **String** `notReimburse` **String** `reimburse` **String** `wholesalePrice` **double** `retailPrice` **double** `producerPrice` **double** `activeSubstance` **String** `authHolder` **String** `vat` **String** `newProduct` **String** >>> ### ProfessionalHealthRecords The professional can create health record forms for every patient he is connected with. Professionals in the same organization that is connected with the patient can see the health record forms if a _flag is enabled_. Each professional can edit the records that he had created. Firestore Collection: `professionalHealthRecords/{ehrId}/` FIELDS >>> `categoryId` **String** `createdAt` **int** `doctorId` **String** `formId` **String** `organization` **String** `userId` **String** `values` **Object** as described in [Professional's Health Record Schema](../Model/System#professionals-health-records-template) >>> ### SearchFields User search data. FIELDS >>> `organizations` **Map** All organizations as map (e.g: {bioassist: true}) `search` **Array** with userId and all combinations of letters from firstName, lastName & email. >>> --- ### Contacts RTDB This element represents the relation between a user and a professional. The relation is bidirectional and has a status, therefore an invitation is sent which must be accepted from the other party before it becomes active. Since the relation is bidirectional the path has two entries for each relation, which are synchronized using functions `RTDB` Path: - contacts/uid/otherUserId - contacts/otherUserId/uid FIELDS **key** `userId` **String** > **key** `otherUserId` **String** >> `acceptedAt` **int** >> `createdAt` **int** >> `direction` **String** [CONTACTS_DIRECTION](#contacts_direction) >> `phrAccess` **bool** >> `status` **String** [CONTACTS_STATUS](#contacts_status) **Security Rules** ``` "contacts":{ "$uid":{ ".read":"auth != null && auth.uid == $uid", "$contactId":{ ".write": "auth != null && auth.uid == $uid && (!newData.exists() || (!data.exists() && newData.child('status').val() == 'PENDING' && newData.child('direction').val() == 'out') || (data.exists() && ((data.child('status').val() == 'PENDING' && data.child('direction').val() == 'in' && newData.child('status').val() == 'ACCEPTED') || (data.child('phrAccess').val() != newData.child('phrAccess').val() && data.child('status').val() == newData.child('status').val() ))))" } } }, ``` #### CONTACTS_DIRECTION >>> - `in` - `out` >>> #### CONTACTS_STATUS >>> - `ACCEPTED` - `PENDING` >>> > :warning: A copy of the above structure is in firestore (with the same data, for security checks in firestore rules). ### Contacts firestore The contacts collection has documents with combined keys (userId + ‘_’ + contactId). Each document has the same elements as above (status, createdAt,acceptedAt, direction). Firestore Collection `contacts/{userId} + ‘_’ + {contactId}/` FIELDS >>> `acceptedAt` **int** `createdAt` **int** `direction` **String** `phrAccess` **bool** `status` **String** {**[CONTACTS_STATUS](#contacts_status)**} >>> **Security Rules** ``` match /contacts/{combinedId}/{document=**} { allow write,read: if false; } ``` ---