diff --git a/.gitignore b/.gitignore
index 96dcb8b91f42a26152653e65782156348b98193b..4923ae926b39e55ddd7f3eeb6952d8a154b584df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+target
+
 # Compiled class file
 *.class
 
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b44df56234ecbb7871237cdad4f35e5fb3d22ebf
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,11 @@
+# Based on https://gitlab.fi.muni.cz/unix/examples/ci-examples/-/blob/java-maven/.gitlab-ci.yml
+image: maven:3-openjdk-17
+
+build:
+  tags:
+    - shared-fi
+  script:
+    - mvn -ntp clean package
+
+
+
diff --git a/README.md b/README.md
index 464090415c47109523e91779d4f40e19495c9cf1..598a8095f3e50012ea3ab3db05062fb185ad5df2 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,40 @@
-# TODO
+# Smart Energy Management System
+
+## About project
+
+- **Name**: Smart Energy Management System
+- **Developers**:
+    - Marek Skácelík - _Project Leader_ @xskacel
+    - Anesa Fazlagić @xfazlag
+    - Filip Bugoš @xbugos
+    - Miroslav RouÄŤa @xrouca
+- **Assigment**:
+    - The system will allow users to manage the smart meter devices at home. For a user, it will be possible to set different smart meters for the different houses they own/rent, and track the power consumption statistics over time that is collected automatically. They can track the power consumption of different devices in different time of the day (e.g., at night). They can also shut down the power to one of their houses through the system, when power is not needed. The power distribution company can consult the power consumption statistics over period of times of all the users registered into the system.
+
+## Modules
+  - **Core**
+    - Main module
+  - **Statistics**
+    - Getting power consumption statistics
+  - **Email**
+    - Sending emails from the system
+  - **Electricity Price**
+    - Getting electricity price in current time (high or low tariff)
+
+## Roles
+
+System has three authorization roles - **Admin**, **Power Distribution Company Employee** and **Smart Energy User**.
+
+- Admin has full permissions in the system.
+- Power distribution company employee can add or modify smart devices for the company and get the houses' power consumption statistics.
+- Smart energy users manage smart devices in their houses. They can add devices to the house and then get power consumption statistics. They can also shut down the power for the smart device in the house.
+
+## Use Case diagram
+
+![](images/UseCase.jpg)
+
+## Class diagram
+
+![](images/ClassDiagram.jpg)
+
+
diff --git a/core/coreopenapi.yaml b/core/coreopenapi.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..84de02f0bd011fb1d7b13bd6cfa6241b49550359
--- /dev/null
+++ b/core/coreopenapi.yaml
@@ -0,0 +1,1267 @@
+openapi: "3.0.3"
+info:
+  title: "smart_energy_management_system API"
+  description: "smart_energy_management_system API"
+  version: "1.0.0"
+servers:
+  - url: "https://smart_energy_management_system"
+paths:
+  /api/smart-meter/{id}:
+    put:
+      summary: "PUT api/smart-meter/{id}"
+      operationId: "updateById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/SmartMeterUpdateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/SmartMeterDto"
+    delete:
+      summary: "DELETE api/smart-meter/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/SmartMeterDto"
+    get:
+      summary: "GET api/smart-meter/{id}"
+      operationId: "findById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/SmartMeterDto"
+  /api/smart-meter:
+    post:
+      summary: "POST api/smart-meter"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/SmartMeterCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/SmartMeterDto"
+    get:
+      summary: "GET api/smart-meter"
+      operationId: "findAll"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/SmartMeterDto"
+  /api/smart-meter/pageable:
+    get:
+      summary: "GET api/smart-meter/pageable"
+      operationId: "findAllPageable"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/SmartMeterDto"
+  /api/device/{id}:
+    put:
+      summary: "PUT api/device/{id}"
+      operationId: "updateById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/DeviceUpdateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/DeviceDto"
+    delete:
+      summary: "DELETE api/device/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/DeviceDto"
+    get:
+      summary: "GET api/device/{id}"
+      operationId: "findById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/DeviceDto"
+  /api/device:
+    post:
+      summary: "POST api/device"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/DeviceCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/DeviceDto"
+    get:
+      summary: "GET api/device"
+      operationId: "findAll"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/DeviceDto"
+  /api/device/pageable:
+    get:
+      summary: "GET api/device/pageable"
+      operationId: "findAllPageable"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/DeviceDto"
+  /api/user/{id}:
+    put:
+      summary: "PUT api/user/{id}"
+      operationId: "updateById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/UserUpdateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/UserDto"
+    delete:
+      summary: "DELETE api/user/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/UserDto"
+    get:
+      summary: "GET api/user/{id}"
+      operationId: "findById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/UserDto"
+  /api/user:
+    post:
+      summary: "POST api/user"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/UserCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/UserDto"
+    get:
+      summary: "GET api/user"
+      operationId: "findAll"
+      parameters:
+        - name: "page"
+          in: "query"
+          required: true
+          schema:
+            type: "integer"
+            format: "int32"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/Result"
+  /api/user/statistics:
+    post:
+      summary: "POST api/user/statistics"
+      operationId: "userHouseStatistics"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/UserStatisticsCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  type: "number"
+                  format: "double"
+  /api/user/all:
+    get:
+      summary: "GET api/user/all"
+      operationId: "findAll"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/UserDto"
+  /api/company/{id}:
+    put:
+      summary: "PUT api/company/{id}"
+      operationId: "updateById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/CompanyUpdateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/CompanyDto"
+    delete:
+      summary: "DELETE api/company/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/CompanyDto"
+    get:
+      summary: "GET api/company/{id}"
+      operationId: "findById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/CompanyDto"
+  /api/company:
+    post:
+      summary: "POST api/company"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/CompanyCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/CompanyDto"
+    get:
+      summary: "GET api/company"
+      operationId: "findAll"
+      parameters:
+        - name: "page"
+          in: "query"
+          required: true
+          schema:
+            type: "integer"
+            format: "int32"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/Result"
+  /api/company/pageable:
+    get:
+      summary: "GET api/company/pageable"
+      operationId: "findAllPageable"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/CompanyDto"
+  /api/company/all:
+    get:
+      summary: "GET api/company/all"
+      operationId: "findAll"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/CompanyDto"
+  /api/role:
+    post:
+      summary: "POST api/role"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/Role"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/Role"
+    get:
+      summary: "GET api/role"
+      operationId: "findUserRoles"
+      parameters:
+        - name: "userId"
+          in: "query"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Role"
+  /api/role/{id}:
+    delete:
+      summary: "DELETE api/role/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/Role"
+  /api/role/all:
+    get:
+      summary: "GET api/role/all"
+      operationId: "findAll"
+      parameters:
+        - name: "userId"
+          in: "query"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/Role"
+  /api/metric/{id}:
+    put:
+      summary: "PUT api/metric/{id}"
+      operationId: "updateById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/MetricsUpdateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/MetricsDto"
+    delete:
+      summary: "DELETE api/metric/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/MetricsDto"
+    get:
+      summary: "GET api/metric/{id}"
+      operationId: "findById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/MetricsDto"
+  /api/metric:
+    post:
+      summary: "POST api/metric"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/MetricsCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/MetricsDto"
+    get:
+      summary: "GET api/metric"
+      operationId: "findAll"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/MetricsDto"
+  /api/metric/pageable:
+    get:
+      summary: "GET api/metric/pageable"
+      operationId: "findAllPageable"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/MetricsDto"
+  /api/manufacturer/{id}:
+    put:
+      summary: "PUT api/manufacturer/{id}"
+      operationId: "updateById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/ManufacturerUpdateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ManufacturerDto"
+    delete:
+      summary: "DELETE api/manufacturer/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ManufacturerDto"
+    get:
+      summary: "GET api/manufacturer/{id}"
+      operationId: "findById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ManufacturerDto"
+  /api/manufacturer:
+    post:
+      summary: "POST api/manufacturer"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/ManufacturerCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ManufacturerDto"
+    get:
+      summary: "GET api/manufacturer"
+      operationId: "findAll"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/ManufacturerDto"
+  /api/manufacturer/pageable:
+    get:
+      summary: "GET api/manufacturer/pageable"
+      operationId: "findAllPageable"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/ManufacturerDto"
+  /api/house/{id}:
+    put:
+      summary: "PUT api/house/{id}"
+      operationId: "updateById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/HouseUpdateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/HouseDto"
+    delete:
+      summary: "DELETE api/house/{id}"
+      operationId: "deleteById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/HouseDto"
+    get:
+      summary: "GET api/house/{id}"
+      operationId: "findById"
+      parameters:
+        - name: "id"
+          in: "path"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/HouseDto"
+  /api/house:
+    post:
+      summary: "POST api/house"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/HouseCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/HouseDto"
+    get:
+      summary: "GET api/house"
+      operationId: "findAll"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/HouseDto"
+  /api/house/pageable:
+    get:
+      summary: "GET api/house/pageable"
+      operationId: "findAllPageable"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/HouseDto"
+  /<unknown>:
+    get:
+      summary: "GET ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    put:
+      summary: "PUT ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    post:
+      summary: "POST ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    delete:
+      summary: "DELETE ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    options:
+      summary: "OPTIONS ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    head:
+      summary: "HEAD ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    patch:
+      summary: "PATCH ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    trace:
+      summary: "TRACE ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+components:
+  schemas:
+    SmartMeterUpdateDto:
+      type: "object"
+      properties:
+        id:
+          type: "string"
+    SmartMeterDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    SmartMeterCreateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    DeviceUpdateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    DeviceDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    DeviceCreateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    UserUpdateDto:
+      type: "object"
+      properties:
+        username:
+          type: "string"
+        password:
+          type: "string"
+        email:
+          type: "string"
+        firstName:
+          type: "string"
+        lastName:
+          type: "string"
+        id:
+          type: "string"
+    UserDto:
+      type: "object"
+      properties:
+        username:
+          type: "string"
+        email:
+          type: "string"
+        firstName:
+          type: "string"
+        lastName:
+          type: "string"
+        id:
+          type: "string"
+    UserCreateDto:
+      type: "object"
+      properties:
+        username:
+          type: "string"
+        password:
+          type: "string"
+        email:
+          type: "string"
+        firstName:
+          type: "string"
+        lastName:
+          type: "string"
+        id:
+          type: "string"
+    UserStatisticsCreateDto:
+      type: "object"
+      properties:
+        id:
+          type: "string"
+        houseId:
+          type: "string"
+        startTime:
+          type: "string"
+          format: "date-time"
+        endTime:
+          type: "string"
+          format: "date-time"
+    Result:
+      type: "object"
+      properties:
+        total:
+          type: "integer"
+          format: "int64"
+        page:
+          type: "integer"
+          format: "int32"
+        pageSize:
+          type: "integer"
+          format: "int32"
+        items:
+          type: "array"
+    CompanyUpdateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    CompanyDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    CompanyCreateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    Manufacturer:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        deviceList:
+          type: "array"
+          items:
+            $ref: "#/components/schemas/Device"
+        id:
+          type: "string"
+        createdDateTime:
+          type: "string"
+          format: "date-time"
+        deletedDateTime:
+          type: "string"
+          format: "date-time"
+    Device:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        smartMeterList:
+          type: "array"
+          items:
+            $ref: "#/components/schemas/SmartMeter"
+        manufacturer:
+          $ref: "#/components/schemas/Manufacturer"
+        id:
+          type: "string"
+        createdDateTime:
+          type: "string"
+          format: "date-time"
+        deletedDateTime:
+          type: "string"
+          format: "date-time"
+    Metrics:
+      type: "object"
+      properties:
+        timeStamp:
+          type: "string"
+          format: "date-time"
+        consumptionKWH:
+          type: "number"
+          format: "double"
+        smartMeter:
+          $ref: "#/components/schemas/SmartMeter"
+        id:
+          type: "string"
+        createdDateTime:
+          type: "string"
+          format: "date-time"
+        deletedDateTime:
+          type: "string"
+          format: "date-time"
+    SmartMeter:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        device:
+          $ref: "#/components/schemas/Device"
+        house:
+          $ref: "#/components/schemas/House"
+        metricsList:
+          type: "array"
+          items:
+            $ref: "#/components/schemas/Metrics"
+        id:
+          type: "string"
+        createdDateTime:
+          type: "string"
+          format: "date-time"
+        deletedDateTime:
+          type: "string"
+          format: "date-time"
+    House:
+      type: "object"
+      properties:
+        address:
+          type: "string"
+        city:
+          type: "string"
+        state:
+          type: "string"
+        zipcode:
+          type: "string"
+        smartMeterList:
+          type: "array"
+          items:
+            $ref: "#/components/schemas/SmartMeter"
+        user:
+          $ref: "#/components/schemas/User"
+        id:
+          type: "string"
+        createdDateTime:
+          type: "string"
+          format: "date-time"
+        deletedDateTime:
+          type: "string"
+          format: "date-time"
+    User:
+      type: "object"
+      properties:
+        username:
+          type: "string"
+        userType:
+          type: "string"
+          enum:
+            - "NORMAL"
+            - "EMPLOYEE"
+            - "ADMIN"
+        password:
+          type: "string"
+        email:
+          type: "string"
+        firstName:
+          type: "string"
+        lastName:
+          type: "string"
+        housesList:
+          type: "array"
+          items:
+            $ref: "#/components/schemas/House"
+        id:
+          type: "string"
+        createdDateTime:
+          type: "string"
+          format: "date-time"
+        deletedDateTime:
+          type: "string"
+          format: "date-time"
+    Role:
+      type: "object"
+      properties:
+        user:
+          $ref: "#/components/schemas/User"
+        roleType:
+          type: "string"
+          enum:
+            - "Admin"
+            - "Employee"
+            - "Owner"
+        id:
+          type: "string"
+        createdDateTime:
+          type: "string"
+          format: "date-time"
+        deletedDateTime:
+          type: "string"
+          format: "date-time"
+    MetricsUpdateDto:
+      type: "object"
+      properties:
+        id:
+          type: "string"
+    MetricsDto:
+      type: "object"
+      properties:
+        id:
+          type: "string"
+    MetricsCreateDto:
+      type: "object"
+      properties:
+        id:
+          type: "string"
+    ManufacturerUpdateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    ManufacturerDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    ManufacturerCreateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        id:
+          type: "string"
+    HouseUpdateDto:
+      type: "object"
+      properties:
+        name:
+          type: "string"
+        city:
+          type: "string"
+        state:
+          type: "string"
+        zipcode:
+          type: "string"
+        id:
+          type: "string"
+    HouseDto:
+      type: "object"
+      properties:
+        address:
+          type: "string"
+        city:
+          type: "string"
+        state:
+          type: "string"
+        zipcode:
+          type: "string"
+        id:
+          type: "string"
+    HouseCreateDto:
+      type: "object"
+      properties:
+        address:
+          type: "string"
+        city:
+          type: "string"
+        state:
+          type: "string"
+        zipcode:
+          type: "string"
+        id:
+          type: "string"
+    Object:
+      type: "object"
+      properties: { }
+    ModelMap:
+      type: "object"
+      properties: { }
+    HttpStatusCode:
+      type: "object"
+      properties: { }
+    ModelAndView:
+      type: "object"
+      properties:
+        view:
+          $ref: "#/components/schemas/Object"
+        model:
+          $ref: "#/components/schemas/ModelMap"
+        status:
+          $ref: "#/components/schemas/HttpStatusCode"
+    HttpHeaders:
+      type: "object"
+      properties: { }
+    ResponseEntity:
+      type: "object"
+      properties:
+        headers:
+          $ref: "#/components/schemas/HttpHeaders"
\ No newline at end of file
diff --git a/core/mvnw b/core/mvnw
new file mode 100644
index 0000000000000000000000000000000000000000..8a8fb2282df5b8f7263470a5a2dc0e196f35f35f
--- /dev/null
+++ b/core/mvnw
@@ -0,0 +1,316 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /usr/local/etc/mavenrc ] ; then
+    . /usr/local/etc/mavenrc
+  fi
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="`\\unset -f command; \\command -v java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  $MAVEN_DEBUG_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" \
+  "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/core/mvnw.cmd b/core/mvnw.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..1d8ab018eaf11d9b3a4a90e7818ace373dfbb380
--- /dev/null
+++ b/core/mvnw.cmd
@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+  %JVM_CONFIG_MAVEN_PROPS% ^
+  %MAVEN_OPTS% ^
+  %MAVEN_DEBUG_OPTS% ^
+  -classpath %WRAPPER_JAR% ^
+  "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..65ef20a06630598f27f48815729b359bf064f1d8
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>smart-energy-management-system</artifactId>
+        <groupId>cz.muni.fi.pa165</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>core</artifactId>
+    <name>core</name>
+    <description>Core application for smart energy management system</description>
+    <dependencies>
+        <dependency>
+            <groupId>cz.muni.fi.pa165</groupId>
+            <artifactId>models</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+            <version>1.5.3.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.springdoc</groupId>
+                <artifactId>springdoc-openapi-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>integration-test</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <apiDocsUrl>http://localhost:8080/openapi.yaml</apiDocsUrl>
+                    <outputFileName>openapi.yaml</outputFileName>
+                    <outputDir>..</outputDir>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/CoreApplication.java b/core/src/main/java/cz/muni/fi/pa165/core/CoreApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e1b34ad31e1affcd5bf9fbc97db09598e5ec7f7
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/CoreApplication.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.core;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CoreApplication {
+
+  public static void main(String[] args) {
+    SpringApplication.run(CoreApplication.class, args);
+  }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/DataInitializer.java b/core/src/main/java/cz/muni/fi/pa165/core/DataInitializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..7fbbb746b565e9b528f57ef3604cc0d587039bf0
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/DataInitializer.java
@@ -0,0 +1,107 @@
+package cz.muni.fi.pa165.core;
+
+import cz.muni.fi.pa165.core.device.Device;
+import cz.muni.fi.pa165.core.device.DeviceService;
+import cz.muni.fi.pa165.core.house.House;
+import cz.muni.fi.pa165.core.house.HouseService;
+import cz.muni.fi.pa165.core.metrics.Metrics;
+import cz.muni.fi.pa165.core.metrics.MetricsService;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeterService;
+import cz.muni.fi.pa165.core.user.User;
+import cz.muni.fi.pa165.core.user.UserService;
+import cz.muni.fi.pa165.core.user.UserType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+@RequiredArgsConstructor
+@Component
+public class DataInitializer implements ApplicationRunner {
+  private final UserService userService;
+  private final DeviceService deviceService;
+  private final SmartMeterService smartMeterService;
+  private final MetricsService metricsService;
+  private final HouseService houseService;
+
+  @Override
+  public void run(ApplicationArguments args) throws Exception {
+    SeedUsers();
+    SeedDevice();
+    SeedSmartMeter();
+    SeedMetrics();
+  }
+
+  private void SeedUsers() {
+    User user =
+        User.builder()
+            .email("test@email.com")
+            .firstName("John")
+            .lastName("Doe")
+            .username("johnD")
+            .password("password")
+            .userType(UserType.ADMIN)
+            .build();
+    userService.create(user);
+  }
+
+  private void SeedDevice() {
+    Device device = Device.builder().name("device01").build();
+    deviceService.create(device);
+  }
+
+  private void SeedSmartMeter() {
+    Device device = Device.builder().name("device02").build();
+    deviceService.create(device);
+
+    SmartMeter smartMeter = SmartMeter.builder().device(device).build();
+    smartMeterService.create(smartMeter);
+  }
+
+  private void SeedMetrics() {
+    User user =
+            User.builder()
+                    .email("test@gmail.com")
+                    .firstName("lol")
+                    .lastName("lol")
+                    .username("lol")
+                    .password("lol")
+                    .userType(UserType.ADMIN)
+                    .build();
+    userService.create(user);
+
+    Device device = Device.builder().name("device03").build();
+    deviceService.create(device);
+
+    SmartMeter smartMeter = SmartMeter.builder().device(device).build();
+    smartMeterService.create(smartMeter);
+
+    List<SmartMeter> smartMeterList = new ArrayList<SmartMeter>();
+    smartMeterList.add(smartMeter);
+    House house = House.builder()
+            .smartMeterList(smartMeterList)
+            .address("lol")
+            .city("lol")
+            .state("lol")
+            .zipcode("lol")
+            .user(user)
+            .build();
+    houseService.create(house);
+
+
+
+    Metrics metrics = Metrics.builder()
+            .consumptionKWH(10)
+            .timeStamp(LocalDateTime.now())
+            .smartMeter(smartMeter)
+            .build();
+    metricsService.create(metrics);
+
+
+  }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/common/DomainFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..408ecd5f9add5267e0b2cf87cc737547ae874468
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainFacade.java
@@ -0,0 +1,114 @@
+package cz.muni.fi.pa165.core.common;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import cz.muni.fi.pa165.model.dto.common.Result;
+import org.springframework.data.domain.Pageable;
+
+import java.util.List;
+
+/**
+ * Abstract class that serves as a facade for accessing and manipulating data
+ * using a {@link DomainService} and a {@link DomainMapper}.
+ *
+ * @param <E> the Entity type representing the object
+ * @param <T> the DTO type representing the entity being manipulated
+ * @param <C> the DTO type representing a create operation for the entity
+ * @param <U> the DTO type representing an update operation for the entity
+ */
+public abstract class DomainFacade<E extends DomainObject,
+		T extends DomainObjectDto,
+		C extends DomainObjectDto,
+		U extends DomainObjectDto> {
+
+	/**
+	 * The service used to perform CRUD operations on the entity.
+	 */
+	private final DomainService<E> service;
+
+	/**
+	 * The mapper used to convert between entity and DTO representations.
+	 */
+	protected final DomainMapper<E, T, C, U> mapper;
+
+	/**
+	 * Constructs a new {@code DomainFacade} with the given {@code DomainService} and {@code DomainMapper}.
+	 *
+	 * @param service the service to be used for CRUD operations
+	 * @param mapper the mapper to be used for entity-DTO conversions
+	 */
+	protected DomainFacade(DomainService<E> service, DomainMapper<E, T, C, U> mapper) {
+		this.service = service;
+		this.mapper = mapper;
+	}
+
+	/**
+	 * Finds an entity by its ID and returns its DTO representation.
+	 *
+	 * @param id the ID of the entity to find
+	 * @return the DTO representation of the found entity
+	 */
+	public T findById(String id) {
+		return mapper.toDto(service.findById(id));
+	}
+
+	/**
+	 * Finds all entities in pageable format and returns their DTO representations.
+	 *
+	 * @param pageable the pagination information
+	 * @return a list of DTO representations of the found entities
+	 */
+	public List<T> findAllPageable(Pageable pageable) {
+		return mapper.toDtoList((List<E>) service.findAllPageable(pageable));
+	}
+
+	/**
+	 * Finds all entities and returns them in a {@link Result} object containing pagination and entity information.
+	 *
+	 * @param page the page number to retrieve
+	 * @return a {@code Result} object containing pagination and entity information
+	 */
+	public Result<T> findAll(int page) {
+		return mapper.toResult(service.findAllPageableInt(page));
+	}
+
+
+	/**
+	 * Finds all entities and returns their DTO representations.
+	 *
+	 * @return a list of DTO representations of the found entities
+	 */
+	public List<T> findAll() {
+		return mapper.toDtoList(service.findAll());
+	}
+
+	/**
+	 * Creates a new entity using the given DTO representation of a create operation and returns its DTO representation.
+	 *
+	 * @param createDto the DTO representation of the create operation for the entity
+	 * @return the DTO representation of the created entity
+	 */
+	public T create(C createDto) {
+		return mapper.toDto(service.create(mapper.fromCreateDto(createDto)));
+	}
+
+	/**
+	 * Updates an entity by its ID.
+	 *
+	 * @param updateDto DTO with updated entity data.
+	 * @param id        ID of the entity to be updated.
+	 * @return DTO representing the updated entity.
+	 */
+	public T updateById(U updateDto, String id) {
+		return mapper.toDto(service.update(mapper.fromUpdateDto(updateDto), id));
+	}
+
+	/**
+	 * Deletes an entity by its ID.
+	 *
+	 * @param id	ID of the entity to be deleted.
+	 * @return DTO representing the deleted entity.
+	 */
+	public T deleteById(String id) {
+		return mapper.toDto(service.deleteById(id));
+	}
+}
\ No newline at end of file
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/common/DomainMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..045031aba511846af80fb6cde21b98da3ac34841
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainMapper.java
@@ -0,0 +1,76 @@
+package cz.muni.fi.pa165.core.common;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import cz.muni.fi.pa165.model.dto.common.Result;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.springframework.data.domain.Page;
+
+import java.util.List;
+
+/**
+ * The DomainMapper interface provides methods to convert between DTOs and entities, as well as lists of them.
+ * It also defines methods to map the create and update DTOs to entities, and a method to convert a Page of entities to a Result DTO.
+ *
+ * @param <E> the type of the entity class
+ * @param <T> the type of the DTO class
+ * @param <C> the type of the create DTO class
+ * @param <U> the type of the update DTO class
+ */
+public interface DomainMapper<E extends DomainObject, T extends DomainObjectDto, C extends DomainObjectDto, U extends DomainObjectDto> {
+
+	/**
+	 * Converts an entity object to a DTO object.
+	 *
+	 * @param entity the entity object to convert
+	 * @return the corresponding dto object
+	 */
+
+	T toDto(E entity);
+
+	/**
+	 * Converts a DTO object to an entity object.
+	 *
+	 * @param dto the DTO object to convert
+	 * @return the corresponding entity object
+	 */
+	E fromDto(T dto);
+
+	/**
+	 * Converts a list of entity objects to a list of DTO objects.
+	 *
+	 * @param entities the list of entity objects to convert
+	 * @return the corresponding list of DTO objects
+	 */
+	List<T> toDtoList(List<E> entities);
+
+	/**
+	 * Converts a create DTO object to an entity object.
+	 *
+	 * @param dto the create DTO object to convert
+	 * @return the corresponding entity object
+	 */
+	E fromCreateDto(C dto);
+
+	/**
+	 * Converts an update DTO object to an entity object.
+	 *
+	 * @param dto the update DTO object to convert
+	 * @return the corresponding entity object
+	 */
+	E fromUpdateDto(U dto);
+
+	/**
+	 * Converts a Page of entities to a Result DTO.
+	 *
+	 * @param source the Page of entities to convert
+	 * @return the corresponding Result DTO
+	 */
+	@Mappings({
+			@Mapping(target = "total", expression = "java(source.getTotalElements())"),
+			@Mapping(target = "page", expression = "java(source.getNumber())"),
+			@Mapping(target = "pageSize", expression = "java(source.getSize())"),
+			@Mapping(target = "items", expression = "java(toDtoList(source.getContent()))")
+	})
+	Result<T> toResult(Page<E> source);
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/common/DomainObject.java b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainObject.java
new file mode 100644
index 0000000000000000000000000000000000000000..174c3f7758c4c1706f46657d1b7370286a3c9fe2
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainObject.java
@@ -0,0 +1,19 @@
+package cz.muni.fi.pa165.core.common;
+
+import jakarta.persistence.Id;
+import jakarta.persistence.MappedSuperclass;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+import java.util.UUID;
+
+@Getter
+@Setter
+@MappedSuperclass
+public abstract class DomainObject {
+  @Id
+  private String id = UUID.randomUUID().toString();
+  public LocalDateTime createdDateTime;
+  public LocalDateTime deletedDateTime;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/common/DomainService.java b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainService.java
new file mode 100644
index 0000000000000000000000000000000000000000..17a93eb3d9d3388b651b81d4fcf96a3141d418db
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/common/DomainService.java
@@ -0,0 +1,83 @@
+package cz.muni.fi.pa165.core.common;
+
+import jakarta.persistence.EntityNotFoundException;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public abstract class DomainService<T extends DomainObject> {
+
+  public static final int DEFAULT_PAGE_SIZE = 10;
+
+  public abstract JpaRepository<T, String> getRepository();
+
+  @Transactional
+  public T create(T entity)
+  {
+    entity.createdDateTime = LocalDateTime.now();
+    return getRepository().save(entity);
+  }
+
+  @Transactional(readOnly = true)
+  public Page<T> findAllPageable(Pageable pageable) {
+    return getRepository().findAll(pageable);
+  }
+
+  @Transactional(readOnly = true)
+  public List<T> findAll() {
+    return getRepository().findAll().stream().filter(entity -> entity.deletedDateTime == null).toList();
+  }
+
+  @Transactional(readOnly = true)
+  public Page<T> findAllPageableInt(int page) {
+    return getRepository().findAll(PageRequest.of(page, DEFAULT_PAGE_SIZE))/*.filter(entity -> entity.deletedDateTime == null)*/;
+  }
+
+  @Transactional(readOnly = true)
+  public T findById(String id) {
+    return getRepository()
+            .findById(id)
+            .filter(entity -> entity.deletedDateTime == null)
+        .orElseThrow(() -> new EntityNotFoundException("Entity with '" + id + "' not found."));
+  }
+
+  @Transactional
+  public void deleteAll()
+  {
+    List<T> entities = findAll();
+    entities.stream().map(entity -> entity.deletedDateTime = LocalDateTime.now());
+    getRepository().saveAll(entities);
+  }
+
+  @Transactional
+  public T deleteById(String id) {
+    T entity = findById(id);
+    if (entity == null)
+      throw new EntityNotFoundException("Entity '" + id + "' not found.");
+    entity.deletedDateTime = LocalDateTime.now();
+    getRepository().save(entity);
+    return entity;
+  }
+
+  @Transactional
+  public T update(T entityToUpdate, String id) {
+    T entity = findById(id);
+    if (entity == null)
+      throw new EntityNotFoundException("Entity '" + id + "' not found.");
+    // TODO: change when ORM tool available
+    entityToUpdate.setId(id);
+    getRepository().save(entityToUpdate);
+    return entity;
+  }
+
+  @Transactional
+  public void deleteAllHardDelete()
+  {
+    getRepository().deleteAll();
+  }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/company/Company.java b/core/src/main/java/cz/muni/fi/pa165/core/company/Company.java
new file mode 100644
index 0000000000000000000000000000000000000000..1befe2916dc0e6672a76536b4c67417d4f0bc0de
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/company/Company.java
@@ -0,0 +1,21 @@
+package cz.muni.fi.pa165.core.company;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_company")
+public class Company extends DomainObject {
+    private String name;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyController.java b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyController.java
new file mode 100644
index 0000000000000000000000000000000000000000..e134fa069e534f57ce44891c1db279145e4b0ab1
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyController.java
@@ -0,0 +1,110 @@
+package cz.muni.fi.pa165.core.company;
+
+import cz.muni.fi.pa165.model.dto.common.Result;
+import cz.muni.fi.pa165.model.dto.company.CompanyCreateDto;
+import cz.muni.fi.pa165.model.dto.company.CompanyDto;
+import cz.muni.fi.pa165.model.dto.company.CompanyUpdateDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/company")
+@Tag(name = "Company", description = "Device API")
+
+public class CompanyController {
+	private CompanyFacade companyFacade;
+
+	@Autowired
+	public CompanyController(CompanyFacade companyFacade) {
+		this.companyFacade = companyFacade;
+	}
+
+	@Operation(summary = "Find all companies with pagination", responses = {
+			@ApiResponse(responseCode = "200", description = "List of companies with pagination", content = {
+					@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CompanyDto.class))
+			})
+	})
+	@GetMapping("/pageable")
+	public List<CompanyDto> findAllPageable(Pageable pageable) {
+		return companyFacade.findAllPageable(pageable);
+	}
+
+	@Operation(summary = "Find all companies with pagination", responses = {
+			@ApiResponse(responseCode = "200", description = "List of companies with pagination", content = {
+					@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = Result.class))
+			})
+	})
+	@GetMapping()
+	public Result<CompanyDto> findAll(
+			@Parameter(description = "Page number of results to retrieve") @RequestParam int page) {
+		return companyFacade.findAll(page);
+	}
+
+	@Operation(summary = "Find all companies", responses = {
+			@ApiResponse(responseCode = "200", description = "List of companies", content = {
+					@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CompanyDto.class))
+			})
+	})
+	@GetMapping("/all")
+	public List<CompanyDto> findAll() {
+		return companyFacade.findAll();
+	}
+
+	@Operation(summary = "Find company by id", responses = {
+			@ApiResponse(responseCode = "200", description = "Company found", content = {
+					@Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = CompanyDto.class))
+			}),
+			@ApiResponse(responseCode = "404", description = "Company not found", content = @Content)
+	})
+	@GetMapping("/{id}")
+	public CompanyDto findById(@PathVariable @Parameter(description = "The id of the company.") String id) {
+		return companyFacade.findById(id);
+	}
+
+	@PostMapping
+	@Operation(summary = "Create a new company")
+	@ApiResponse(responseCode = "201", description = "The newly created company",
+			content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
+					schema = @Schema(implementation = CompanyDto.class)))
+	public CompanyDto create(@RequestBody @Valid CompanyCreateDto companyCreateDto) {
+		return companyFacade.create(companyCreateDto);
+	}
+
+	@PutMapping("/{id}")
+	@Operation(summary = "Update a company by ID")
+	@ApiResponse(responseCode = "200", description = "The updated company",
+			content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
+					schema = @Schema(implementation = CompanyDto.class)))
+	public CompanyDto updateById(@PathVariable @Parameter(description = "The id of the company.") String id,
+								 @RequestBody @Valid CompanyUpdateDto companyUpdateDto) {
+		return companyFacade.updateById(companyUpdateDto, id);
+	}
+
+	@DeleteMapping("/{id}")
+	@Operation(summary = "Delete a company by ID")
+	@ApiResponse(responseCode = "200", description = "The deleted company",
+			content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
+					schema = @Schema(implementation = CompanyDto.class)))
+	public CompanyDto deleteById(@PathVariable @Parameter(description = "The id of the company.") String id) {
+		return companyFacade.deleteById(id);
+	}
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..7755b3fab2d19d38b3e5d60aedc23d10fb6c1062
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyFacade.java
@@ -0,0 +1,21 @@
+package cz.muni.fi.pa165.core.company;
+
+import cz.muni.fi.pa165.core.common.DomainFacade;
+import cz.muni.fi.pa165.model.dto.company.CompanyCreateDto;
+import cz.muni.fi.pa165.model.dto.company.CompanyDto;
+import cz.muni.fi.pa165.model.dto.company.CompanyUpdateDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class CompanyFacade extends DomainFacade<Company, CompanyDto, CompanyCreateDto, CompanyUpdateDto> {
+	private final CompanyService companyService; // For the "CompanyService" specific methods
+
+	@Autowired
+	public CompanyFacade(CompanyService companyService,
+						 CompanyMapper companyMapper) {
+		super(companyService, companyMapper);
+		this.companyService = companyService;
+	}
+}
\ No newline at end of file
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..c029f98ba16b1395850910f60e543ff597372e84
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyMapper.java
@@ -0,0 +1,14 @@
+package cz.muni.fi.pa165.core.company;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.model.dto.company.CompanyCreateDto;
+import cz.muni.fi.pa165.model.dto.company.CompanyDto;
+import cz.muni.fi.pa165.model.dto.company.CompanyUpdateDto;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface CompanyMapper extends DomainMapper<Company,
+		CompanyDto,
+		CompanyCreateDto,
+		CompanyUpdateDto>
+{}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..99baaa36e21fff186ecb7d05f4f569f149d5f6e8
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyRepository.java
@@ -0,0 +1,7 @@
+package cz.muni.fi.pa165.core.company;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface CompanyRepository extends JpaRepository<Company, String> {}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyService.java b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyService.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c5215ccd986f73f8eb378d216fe944a6408e4dd
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/company/CompanyService.java
@@ -0,0 +1,18 @@
+package cz.muni.fi.pa165.core.company;
+
+import cz.muni.fi.pa165.core.common.DomainService;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CompanyService extends DomainService<Company> {
+	@Getter
+	private final CompanyRepository repository;
+
+	@Autowired
+	public CompanyService(CompanyRepository companyRepository) {
+		this.repository = companyRepository;
+	}
+}
+
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/device/Device.java b/core/src/main/java/cz/muni/fi/pa165/core/device/Device.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2b8a4370783f496e8d15de886c021e173856f3b
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/device/Device.java
@@ -0,0 +1,37 @@
+package cz.muni.fi.pa165.core.device;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.manufacturer.Manufacturer;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_device")
+public class Device extends DomainObject {
+
+  private String name;
+
+  @OneToMany
+  private List<SmartMeter> smartMeterList;
+
+  @ManyToOne
+  private Manufacturer manufacturer;
+
+  // Company ??
+  // private Company company;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceController.java b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d06588d84d150b029567280b727831a451f9b4f5
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceController.java
@@ -0,0 +1,87 @@
+package cz.muni.fi.pa165.core.device;
+
+import cz.muni.fi.pa165.model.dto.device.DeviceCreateDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceUpdateDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import org.springframework.data.domain.Pageable;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/device")
+@Tag(name = "Device", description = "Device API")
+public class DeviceController {
+
+    private DeviceFacade deviceFacade;
+
+    @Autowired
+    public DeviceController(DeviceFacade deviceFacade) {
+      this.deviceFacade = deviceFacade;
+    }
+
+
+    @Operation(
+            summary = "Get all devices pageable",
+            description = "Returns a pageable list of all devices.")
+    @GetMapping("/pageable")
+    public List<DeviceDto> findAllPageable(Pageable pageable) {
+      return deviceFacade.findAllPageable(pageable);
+    }
+
+    @Operation(
+            summary = "Get all devices",
+            description = "Returns a list of all devices.")
+    @CrossOrigin(origins = "*")
+    @GetMapping
+    public List<DeviceDto> findAll() {
+      return deviceFacade.findAll();
+    }
+
+    @Operation(
+            summary = "Get device by id",
+            description = "Returns a device with the specified id.")
+    @GetMapping("/{id}")
+    public DeviceDto findById(@PathVariable @Parameter(description = "The id of the device.") String id) {
+      return deviceFacade.findById(id);
+    }
+
+    @Operation(
+            summary = "Create device",
+            description = "Creates a new device.")
+    @PostMapping
+    public DeviceDto create(@RequestBody DeviceCreateDto deviceCreateDto) {
+      return deviceFacade.create(deviceCreateDto);
+    }
+
+    @Operation(
+            summary = "Update device",
+            description = "Updates the device with the specified id.")
+    @PutMapping("/{id}")
+    public DeviceDto updateById(@PathVariable @Parameter(description = "The id of the device.") String id,
+                            @RequestBody @Valid DeviceUpdateDto deviceUpdateDto) {
+      return deviceFacade.updateById(deviceUpdateDto, id);
+    }
+
+    @Operation(
+            summary = "Delete device",
+            description = "Deletes the device with the specified id.")
+    @DeleteMapping("/{id}")
+    public DeviceDto deleteById(
+            @PathVariable @Parameter(description = "The id of the device.") String id) {
+      return deviceFacade.deleteById(id);
+    }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..83ebcbe6ddd4c713c3731e5ca6f29df9b8e3d131
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceFacade.java
@@ -0,0 +1,20 @@
+package cz.muni.fi.pa165.core.device;
+
+import cz.muni.fi.pa165.core.common.DomainFacade;
+import cz.muni.fi.pa165.model.dto.device.DeviceCreateDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceUpdateDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DeviceFacade extends DomainFacade<Device, DeviceDto, DeviceCreateDto, DeviceUpdateDto> {
+
+	private final DeviceService deviceService; // For the "DeviceService" specific methods
+
+	@Autowired
+	public DeviceFacade(DeviceService deviceService, DeviceMapper deviceMapper) {
+		super(deviceService, deviceMapper);
+		this.deviceService = deviceService;
+	}
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..96a66374cdba5da85e520cbaa3538fbfa35d3fdb
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceMapper.java
@@ -0,0 +1,10 @@
+package cz.muni.fi.pa165.core.device;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.model.dto.device.DeviceCreateDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceUpdateDto;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface DeviceMapper extends DomainMapper<Device, DeviceDto, DeviceCreateDto, DeviceUpdateDto> { }
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..70d7a39a95db52b89dc53d39029ce0a74e2d70e5
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceRepository.java
@@ -0,0 +1,9 @@
+package cz.muni.fi.pa165.core.device;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface DeviceRepository extends JpaRepository<Device, String> {}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceService.java b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceService.java
new file mode 100644
index 0000000000000000000000000000000000000000..98a7c27e4b48de06a7824ba64f30ec0ce524034c
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/device/DeviceService.java
@@ -0,0 +1,18 @@
+package cz.muni.fi.pa165.core.device;
+
+import cz.muni.fi.pa165.core.common.DomainService;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+
+@Service
+public class DeviceService extends DomainService<Device> {
+  @Getter
+  private final DeviceRepository repository;
+
+  @Autowired
+  public DeviceService(DeviceRepository deviceRepository) {
+    repository = deviceRepository;
+  }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/house/House.java b/core/src/main/java/cz/muni/fi/pa165/core/house/House.java
new file mode 100644
index 0000000000000000000000000000000000000000..3578e107261712e51ddd7f75adcbfad274ae7d89
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/house/House.java
@@ -0,0 +1,37 @@
+package cz.muni.fi.pa165.core.house;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import cz.muni.fi.pa165.core.user.User;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_house")
+public class House extends DomainObject {
+
+  private String address;
+  private String city;
+  private String state;
+  private String zipcode;
+
+  @OneToMany
+  private List<SmartMeter> smartMeterList;
+
+  @ManyToOne
+  private User user;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/house/HouseController.java b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d080fcbbbe9cf2596d336862cd6a77284d45fe9f
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseController.java
@@ -0,0 +1,89 @@
+package cz.muni.fi.pa165.core.house;
+
+import cz.muni.fi.pa165.model.dto.house.HouseCreateDto;
+import cz.muni.fi.pa165.model.dto.house.HouseDto;
+import cz.muni.fi.pa165.model.dto.house.HouseUpdateDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/house")
+@Tag(name = "House", description = "House API")
+
+public class HouseController {
+
+  private final HouseFacade houseFacade;
+
+  @Autowired
+  public HouseController(HouseFacade houseFacade) {
+	  this.houseFacade = houseFacade;
+  }
+
+  @Operation(
+          summary = "Get all houses pageable",
+          description = "Retrieve a pageable list of all houses."
+  )
+  @GetMapping("/pageable")
+  public List<HouseDto> findAllPageable(Pageable pageable) {
+	  return houseFacade.findAllPageable(pageable);
+  }
+
+  @Operation(
+          summary = "Get all houses",
+          description = "Retrieve a list of all houses."
+  )
+  @CrossOrigin(origins = "*")
+  @GetMapping
+  public List<HouseDto> findAll() {
+	  return houseFacade.findAll();
+  }
+
+  @Operation(
+          summary = "Get a house by ID",
+          description = "Retrieve a house with the specified ID."
+  )
+  @GetMapping("/{id}")
+  public HouseDto findById(@PathVariable String id) {
+	  return houseFacade.findById(id);
+  }
+
+  @Operation(
+          summary = "Create a new house",
+          description = "Create a new house with the specified details."
+  )
+  @PostMapping
+  public HouseDto create(@RequestBody HouseCreateDto houseCreateDtoDto) {
+	  return houseFacade.create(houseCreateDtoDto);
+  }
+
+  @Operation(
+          summary = "Update specific house",
+          description = "Updates the house with the specified id."
+  )
+  @PutMapping("/{id}")
+  public HouseDto updateById(@RequestBody HouseUpdateDto houseUpdateDto, @PathVariable String id) {
+	  return houseFacade.updateById(houseUpdateDto, id);
+  }
+
+  @Operation(
+          summary = "Deletes specific house",
+          description = "Deletes the house with the specified id."
+  )
+  @DeleteMapping("/{id}")
+  public HouseDto deleteById(@PathVariable String id) {
+	  return houseFacade.deleteById(id);
+  }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/house/HouseFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..e36736bdd45381b2003a04a17eedac50ddc55621
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseFacade.java
@@ -0,0 +1,21 @@
+package cz.muni.fi.pa165.core.house;
+
+import cz.muni.fi.pa165.core.common.DomainFacade;
+import cz.muni.fi.pa165.model.dto.house.HouseCreateDto;
+import cz.muni.fi.pa165.model.dto.house.HouseDto;
+import cz.muni.fi.pa165.model.dto.house.HouseUpdateDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class HouseFacade extends DomainFacade<House, HouseDto, HouseCreateDto, HouseUpdateDto> {
+	private final HouseService houseService; // For the "HouseService" specific methods
+
+	@Autowired
+	public HouseFacade(HouseService houseService,
+					   HouseMapper houseMapper) {
+		super(houseService, houseMapper);
+		this.houseService = houseService;
+	}
+}
\ No newline at end of file
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/house/HouseMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..78940c4165fee2d543f35194d899132529c5ef18
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseMapper.java
@@ -0,0 +1,10 @@
+package cz.muni.fi.pa165.core.house;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.model.dto.house.HouseCreateDto;
+import cz.muni.fi.pa165.model.dto.house.HouseDto;
+import cz.muni.fi.pa165.model.dto.house.HouseUpdateDto;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface HouseMapper extends DomainMapper<House, HouseDto, HouseCreateDto, HouseUpdateDto> {}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/house/HouseRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..11835d023ee2758f30a7f29545eb6a57177194c0
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseRepository.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.core.house;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface HouseRepository extends JpaRepository<House, String> {
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/house/HouseService.java b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseService.java
new file mode 100644
index 0000000000000000000000000000000000000000..201232001056f2e8356665ac8fbafb5f069ed59a
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/house/HouseService.java
@@ -0,0 +1,21 @@
+package cz.muni.fi.pa165.core.house;
+
+import cz.muni.fi.pa165.core.common.DomainService;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class HouseService extends DomainService<House> {
+  @Getter
+  private final HouseRepository repository;
+
+  @Autowired
+  public HouseService(HouseRepository houseRepository) {
+    repository = houseRepository;
+  }
+
+  public Object foo(){
+	  return null;
+  }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/Manufacturer.java b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/Manufacturer.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7c40b0ef92120ff97125c96edd9ae8d2020ada0
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/Manufacturer.java
@@ -0,0 +1,28 @@
+package cz.muni.fi.pa165.core.manufacturer;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.device.Device;
+import jakarta.persistence.Entity;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_manufacturer")
+public class Manufacturer extends DomainObject {
+
+  private String name;
+
+  @OneToMany private List<Device> deviceList;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerController.java b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerController.java
new file mode 100644
index 0000000000000000000000000000000000000000..257e6b9078456bf1a0f846c352bbd8d5b18c04aa
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerController.java
@@ -0,0 +1,123 @@
+package cz.muni.fi.pa165.core.manufacturer;
+
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerCreateDto;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerDto;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerUpdateDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * Controller for managing manufacturers.
+ */
+@RestController
+@RequestMapping("/api/manufacturer")
+@Tag(name = "manufacturer", description = "Manufacturer API")
+public class ManufacturerController {
+	private final ManufacturerFacade manufacturerFacade;
+
+	@Autowired
+	public ManufacturerController(
+			ManufacturerFacade manufacturerFacade
+	) {
+		this.manufacturerFacade = manufacturerFacade;
+	}
+
+	@Operation(
+			summary = "Get all manufacturers (paginated)",
+			description = "Returns a pageable list of all manufacturers.",
+			tags= {"manufacturer"})
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "200", description = "Successfully retrieved list of manufacturers"),
+			@ApiResponse(responseCode = "400", description = "Invalid pagination parameters"),
+			@ApiResponse(responseCode = "404", description = "No manufacturers found")
+	})
+	@GetMapping("pageable")
+	public List<ManufacturerDto> findAllPageable(Pageable pageable) {
+		return manufacturerFacade.findAllPageable(pageable);
+	}
+
+	@Operation(
+			summary = "Get all manufacturers",
+			description = "Returns a list of all manufacturers.",
+			tags= {"manufacturer"})
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "200", description = "Successfully retrieved list of manufacturers"),
+			@ApiResponse(responseCode = "404", description = "No manufacturers found")
+	})
+	@CrossOrigin(origins = "*")
+	@GetMapping // CORS headers needed for JavaScript clients
+	public List<ManufacturerDto> findAll() {
+		return manufacturerFacade.findAll();
+	}
+
+	@Operation(
+			summary = "Get manufacturer by ID",
+			description = "Returns the manufacturer with the specified ID.",
+			tags= {"manufacturer"})
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "200", description = "Successfully retrieved manufacturer"),
+			@ApiResponse(responseCode = "404", description = "Manufacturer not found")
+	})
+	@GetMapping("/{id}")
+	public ManufacturerDto findById(
+			@PathVariable @Parameter(description = "The ID of the manufacturer.") String id) {
+		return manufacturerFacade.findById(id);
+	}
+
+	@Operation(
+			summary = "Create manufacturer",
+			description = "Creates a new manufacturer.",
+			tags= {"manufacturer"})
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "201", description = "Manufacturer created successfully"),
+			@ApiResponse(responseCode = "400", description = "Invalid manufacturer data supplied")
+	})
+	@PostMapping
+	public ManufacturerDto create(@RequestBody @Valid ManufacturerCreateDto manufacturerDto) {
+		return manufacturerFacade.create(manufacturerDto);
+	}
+	@Operation(
+			summary = "Update manufacturer by ID",
+			description = "Updates the manufacturer with the specified ID.")
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "200", description = "The manufacturer was updated."),
+			@ApiResponse(responseCode = "404", description = "The manufacturer with the specified ID was not found."),
+			@ApiResponse(responseCode = "400", description = "The request was malformed.")
+	})
+    @PutMapping("/{id}")
+    public ManufacturerDto updateById(@PathVariable @Parameter(description = "The id of the manufacturer.") String id,
+                                  @RequestBody @Valid ManufacturerUpdateDto manufacturerUpdateDto) {
+        return manufacturerFacade.updateById(manufacturerUpdateDto, id);
+    }
+	@Operation(
+			summary = "Delete manufacturer",
+			description = "Deletes the manufacturer with the specified ID.",
+			tags = {"manufacturer"})
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "204", description = "Manufacturer deleted successfully"),
+			@ApiResponse(responseCode = "404", description = "Manufacturer not found"),
+			@ApiResponse(responseCode = "500", description = "Internal server error")
+	})
+	@DeleteMapping("/{id}")
+    public ManufacturerDto deleteById(
+            @PathVariable @Parameter(description = "The id of the manufacturer.") String id) {
+        return manufacturerFacade.deleteById(id);
+    }
+}
\ No newline at end of file
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..bbf439a62eb99eb15f264461a9d1a4de5b98fa21
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerFacade.java
@@ -0,0 +1,23 @@
+package cz.muni.fi.pa165.core.manufacturer;
+
+import cz.muni.fi.pa165.core.common.DomainFacade;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerCreateDto;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerDto;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerUpdateDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ManufacturerFacade extends DomainFacade<Manufacturer,
+		ManufacturerDto,
+		ManufacturerCreateDto,
+		ManufacturerUpdateDto> {
+
+	private ManufacturerService manufacturerService; // For the "ManufacturerService" specific methods
+	@Autowired
+	public ManufacturerFacade(ManufacturerService manufacturerService,
+						ManufacturerMapper manufacturerMapper) {
+		super(manufacturerService, manufacturerMapper);
+		this.manufacturerService = manufacturerService;
+	}
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..019720bb2c9496f2dc42b834a318a231b1bed4bf
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerMapper.java
@@ -0,0 +1,15 @@
+package cz.muni.fi.pa165.core.manufacturer;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerCreateDto;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerDto;
+import cz.muni.fi.pa165.model.dto.manufacturer.ManufacturerUpdateDto;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface ManufacturerMapper extends DomainMapper<
+        Manufacturer,
+        ManufacturerDto,
+        ManufacturerCreateDto,
+        ManufacturerUpdateDto
+        > {}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..b599e4c98d71867e6e3a688c1f412f8ee3f10a99
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerRepository.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.core.manufacturer;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ManufacturerRepository extends JpaRepository<Manufacturer, String> {
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerService.java b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerService.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6b2d74e38356b8a429cc76afe4539794220d3ea
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/manufacturer/ManufacturerService.java
@@ -0,0 +1,18 @@
+package cz.muni.fi.pa165.core.manufacturer;
+
+import cz.muni.fi.pa165.core.common.DomainService;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ManufacturerService extends DomainService<Manufacturer> {
+  @Getter
+  private final ManufacturerRepository repository;
+
+  @Autowired
+  public ManufacturerService(ManufacturerRepository manufacturerRepository) {
+    repository = manufacturerRepository;
+  }
+
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/metrics/Metrics.java b/core/src/main/java/cz/muni/fi/pa165/core/metrics/Metrics.java
new file mode 100644
index 0000000000000000000000000000000000000000..367a00ee9be431f06eb3cd836ca28fc83e34f848
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/metrics/Metrics.java
@@ -0,0 +1,30 @@
+package cz.muni.fi.pa165.core.metrics;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_metrics")
+public class Metrics extends DomainObject {
+    private LocalDateTime timeStamp;
+
+    private double consumptionKWH;
+    @ManyToOne
+    private SmartMeter smartMeter;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsController.java b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsController.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fb045a6329bb4739da07c7ee98b21ccd5fd3071
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsController.java
@@ -0,0 +1,80 @@
+package cz.muni.fi.pa165.core.metrics;
+
+import cz.muni.fi.pa165.model.dto.metrics.MetricsCreateDto;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsDto;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsUpdateDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/metric")
+@Tag(name = "metric", description = "Metric API")
+public class MetricsController {
+	private MetricsFacade metricsFacade;
+
+	@Autowired
+	public MetricsController(MetricsFacade metricsFacade) {
+		this.metricsFacade = metricsFacade;
+	}
+
+	@Operation(summary = "Find all metrics (pageable)", description = "Returns a pageable list of all metrics.")
+	@GetMapping("/pageable")
+	@ApiResponse(responseCode = "200", description = "Successfully retrieved the pageable list of metrics.")
+	public List<MetricsDto> findAllPageable(Pageable pageable) {
+		return metricsFacade.findAllPageable(pageable);
+	}
+
+	@Operation(summary = "Find all metrics", description = "Returns a list of all metrics.")
+	@GetMapping
+	@ApiResponse(responseCode = "200", description = "Successfully retrieved the list of metrics.")
+	public List<MetricsDto> findAll() {
+		return metricsFacade.findAll();
+	}
+
+	@Operation(summary = "Find metric by ID", description = "Returns the metric with the specified ID.")
+	@GetMapping("/{id}")
+	@ApiResponse(responseCode = "200", description = "Successfully retrieved the metric.")
+	@ApiResponse(responseCode = "404", description = "Metric not found.")
+	public MetricsDto findById(@PathVariable @Parameter(description = "The ID of the metric to retrieve.") String id) {
+		return metricsFacade.findById(id);
+	}
+
+	@Operation(summary = "Create metric", description = "Creates a new metric.")
+	@PostMapping
+	@ApiResponse(responseCode = "201", description = "Successfully created a new metric.")
+	public MetricsDto create(@RequestBody @Valid MetricsCreateDto metricsCreateDto) {
+		return metricsFacade.create(metricsCreateDto);
+	}
+
+	@Operation(summary = "Update metric", description = "Updates the metric with the specified ID.")
+	@PutMapping("/{id}")
+	@ApiResponse(responseCode = "200", description = "Successfully updated the metric.")
+	@ApiResponse(responseCode = "404", description = "Metric not found.")
+	public MetricsDto updateById(@PathVariable @Parameter(description = "The ID of the metric to update.") String id,
+								 @RequestBody @Valid MetricsUpdateDto metricsUpdateDto) {
+		return metricsFacade.updateById(metricsUpdateDto, id);
+	}
+
+	@Operation(summary = "Delete metric", description = "Deletes the metric with the specified ID.")
+	@DeleteMapping("/{id}")
+	@ApiResponse(responseCode = "200", description = "Successfully deleted the metric.")
+	@ApiResponse(responseCode = "404", description = "Metric not found.")
+	public MetricsDto deleteById(@PathVariable @Parameter(description = "The ID of the metric to delete.") String id) {
+		return metricsFacade.deleteById(id);
+	}
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6e112aded8af539aaea8131a9c4bf9878cc06c1
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsFacade.java
@@ -0,0 +1,22 @@
+package cz.muni.fi.pa165.core.metrics;
+
+import cz.muni.fi.pa165.core.common.DomainFacade;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsCreateDto;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsDto;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsUpdateDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MetricsFacade extends DomainFacade<Metrics,
+		MetricsDto,
+		MetricsCreateDto,
+		MetricsUpdateDto> {
+	private MetricsService metricsService; // For the "MetricsService" specific methods
+	@Autowired
+	public MetricsFacade(MetricsService metricsService,
+						 MetricsMapper metricsMapper) {
+		super(metricsService, metricsMapper);
+		this.metricsService = metricsService;
+	}
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..720c84d918d068aadaf447581810af12a1664934
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsMapper.java
@@ -0,0 +1,13 @@
+package cz.muni.fi.pa165.core.metrics;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsCreateDto;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsDto;
+import cz.muni.fi.pa165.model.dto.metrics.MetricsUpdateDto;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface MetricsMapper extends DomainMapper<Metrics,
+		MetricsDto,
+		MetricsCreateDto,
+		MetricsUpdateDto> {}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..75ad6628321582cca453c337a8d34479afebd516
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsRepository.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.core.metrics;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface MetricsRepository extends JpaRepository<Metrics, String> {
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsService.java b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsService.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d847dc6a24645504ca672895f90a8d1a70b6caf
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/metrics/MetricsService.java
@@ -0,0 +1,17 @@
+package cz.muni.fi.pa165.core.metrics;
+
+import cz.muni.fi.pa165.core.common.DomainService;
+import lombok.Getter;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MetricsService extends DomainService<Metrics> {
+
+    @Getter
+    private final MetricsRepository repository;
+
+    public MetricsService(MetricsRepository repository) {
+        this.repository = repository;
+    }
+
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeter.java b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8e8517b7e797e3ba65c270e93d208a8d8d6b1a4
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeter.java
@@ -0,0 +1,38 @@
+package cz.muni.fi.pa165.core.smartmeter;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.device.Device;
+import cz.muni.fi.pa165.core.house.House;
+import cz.muni.fi.pa165.core.metrics.Metrics;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_smartMeter")
+public class SmartMeter extends DomainObject {
+
+    private String name;
+
+    @ManyToOne
+    private Device device;
+
+    @ManyToOne
+    private House house;
+
+    @OneToMany
+    private List<Metrics> metricsList;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterController.java b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterController.java
new file mode 100644
index 0000000000000000000000000000000000000000..64ca2fe2441afd709b5693fce29ca21855bedfaa
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterController.java
@@ -0,0 +1,83 @@
+package cz.muni.fi.pa165.core.smartmeter;
+
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterCreateDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterUpdateDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/smart-meter")
+@Tag(name = "smart-meter", description = "SmartMeter API")
+public class SmartMeterController {
+
+	private final SmartMeterFacade smartMeterFacade;
+
+	@Autowired
+	public SmartMeterController(SmartMeterFacade smartMeterFacade) {
+		this.smartMeterFacade = smartMeterFacade;
+	}
+
+	@Operation(summary = "Find all smart meters (pageable)", description = "Returns a pageable list of all smart meters.")
+	@GetMapping("/pageable")
+	@ApiResponse(responseCode = "200", description = "Successfully retrieved the pageable list of smart meters.")
+	public List<SmartMeterDto> findAllPageable(Pageable pageable) {
+		return smartMeterFacade.findAllPageable(pageable);
+	}
+
+	@Operation(summary = "Find all smart meters", description = "Returns a list of all smart meters.")
+	@GetMapping
+	@ApiResponse(responseCode = "200", description = "Successfully retrieved the list of smart meters.")
+	@CrossOrigin(origins = "*") // CORS headers needed for JavaScript clients
+	public List<SmartMeterDto> findAll() {
+		return smartMeterFacade.findAll();
+	}
+
+	@Operation(summary = "Find smart meter by ID", description = "Returns the smart meter with the specified ID.")
+	@GetMapping("/{id}")
+	@ApiResponse(responseCode = "200", description = "Successfully retrieved the smart meter.")
+	@ApiResponse(responseCode = "404", description = "Smart meter not found.")
+	public SmartMeterDto findById(@PathVariable @Parameter(description = "The ID of the smart meter to retrieve.") String id) {
+		return smartMeterFacade.findById(id);
+	}
+
+	@Operation(summary = "Create smart meter", description = "Creates a new smart meter.")
+	@PostMapping
+	@ApiResponse(responseCode = "201", description = "Successfully created a new smart meter.")
+	public SmartMeterDto create(@RequestBody @Valid SmartMeterCreateDto smartMeterCreateDto) {
+		return smartMeterFacade.create(smartMeterCreateDto);
+	}
+
+	@Operation(summary = "Delete smart meter", description = "Deletes the smart meter with the specified ID.")
+	@DeleteMapping("/{id}")
+	@ApiResponse(responseCode = "200", description = "Successfully deleted the smart meter.")
+	@ApiResponse(responseCode = "404", description = "Smart meter not found.")
+	public SmartMeterDto deleteById(@PathVariable @Parameter(description = "The ID of the smart meter to delete.") String id) {
+		return smartMeterFacade.deleteById(id);
+	}
+
+	@Operation(summary = "Update smart meter", description = "Updates the smart meter with the specified ID.")
+	@PutMapping("/{id}")
+	@ApiResponse(responseCode = "200", description = "Successfully updated the smart meter.")
+	@ApiResponse(responseCode = "404", description = "Smart meter not found.")
+	public SmartMeterDto updateById(@PathVariable @Parameter(description = "The ID of the smart meter to update.") String id,
+									@RequestBody @Valid SmartMeterUpdateDto smartMeterUpdateDto) {
+		return smartMeterFacade.updateById(smartMeterUpdateDto, id);
+	}
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..4312f57c888b5f412535cf896fbfb8de8ae0f5d5
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterFacade.java
@@ -0,0 +1,24 @@
+package cz.muni.fi.pa165.core.smartmeter;
+
+import cz.muni.fi.pa165.core.common.DomainFacade;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterCreateDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterUpdateDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SmartMeterFacade extends DomainFacade<SmartMeter,
+		SmartMeterDto,
+		SmartMeterCreateDto,
+		SmartMeterUpdateDto> {
+	private final SmartMeterService smartMeterService; // For the "SmartMeterService" specific methods
+
+	@Autowired
+	public SmartMeterFacade(SmartMeterService smartMeterService,
+							SmartMeterMapper smartMeterMapper
+	) {
+		super(smartMeterService, smartMeterMapper);
+		this.smartMeterService = smartMeterService;
+	}
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..3779a6a1eb4351c18cb9adafb229b70845320b66
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterMapper.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.core.smartmeter;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterCreateDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterUpdateDto;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface SmartMeterMapper extends DomainMapper<SmartMeter, SmartMeterDto, SmartMeterCreateDto, SmartMeterUpdateDto> {}
+
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..582cf9382d7bc1d91cdb9f0f78b7cf64f893eea9
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterRepository.java
@@ -0,0 +1,9 @@
+package cz.muni.fi.pa165.core.smartmeter;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface SmartMeterRepository extends JpaRepository<SmartMeter, String> {}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterService.java b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterService.java
new file mode 100644
index 0000000000000000000000000000000000000000..984ab5290b6cdbd22342e60d7063587737b4652e
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/smartmeter/SmartMeterService.java
@@ -0,0 +1,17 @@
+package cz.muni.fi.pa165.core.smartmeter;
+
+import cz.muni.fi.pa165.core.common.DomainService;
+import lombok.Getter;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SmartMeterService extends DomainService<SmartMeter> {
+
+  @Getter
+  private final SmartMeterRepository repository;
+
+  public SmartMeterService(SmartMeterRepository smartMeterRepository) {
+    this.repository = smartMeterRepository;
+  }
+
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/User.java b/core/src/main/java/cz/muni/fi/pa165/core/user/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..f27f8c24fcd0705d775c0d8cde768ba35c342b69
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/User.java
@@ -0,0 +1,42 @@
+package cz.muni.fi.pa165.core.user;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.house.House;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_user")
+public class User extends DomainObject {
+
+  private String username;
+
+  @Enumerated(EnumType.STRING)
+  private UserType userType;
+
+  private String password;
+
+  private String email;
+
+  private String firstName;
+
+  private String lastName;
+
+  @OneToMany
+  private List<House> housesList;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/UserController.java b/core/src/main/java/cz/muni/fi/pa165/core/user/UserController.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4b7c25812c8bf0ee7f7206fe7bbabefde9812c9
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/UserController.java
@@ -0,0 +1,172 @@
+package cz.muni.fi.pa165.core.user;
+
+import cz.muni.fi.pa165.model.dto.common.Result;
+import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
+import cz.muni.fi.pa165.model.dto.user.UserDto;
+import cz.muni.fi.pa165.model.dto.user.UserStatisticsCreateDto;
+import cz.muni.fi.pa165.model.dto.user.UserUpdateDto;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/user")
+@Tag(name = "user", description = "User API")
+public class UserController {
+	private final UserFacade userFacade;
+	private final UserService userService; // TODO: this could be done in UserFacade
+
+	@Autowired
+	public UserController(UserFacade userFacade, UserService userService) {
+		this.userFacade = userFacade;
+		this.userService = userService;
+	}
+
+  @Operation(
+      summary = "Find user by ID",
+      description = "Returns a single user",
+      tags = {"user"})
+  @ApiResponses(
+      value = {
+        @ApiResponse(
+            responseCode = "200",
+            description = "User found",
+            content = {
+              @Content(
+                  mediaType = "application/json",
+                  schema = @Schema(implementation = UserDto.class))
+            }),
+        @ApiResponse(responseCode = "404", description = "User not found", content = @Content)
+      })
+  @GetMapping("/{id}")
+  public UserDto findById(
+      @Parameter(description = "ID of user to be searched") @PathVariable String id) {
+    return userFacade.findById(id);
+  }
+
+  @Operation(
+      summary = "Create user",
+      description = "Creates a new user",
+      tags = {"user"})
+  @ApiResponses(
+      value = {
+        @ApiResponse(
+            responseCode = "201",
+            description = "User created",
+            content = {
+              @Content(
+                  mediaType = "application/json",
+                  schema = @Schema(implementation = UserDto.class))
+            }),
+        @ApiResponse(responseCode = "400", description = "Invalid input", content = @Content),
+        @ApiResponse(
+            responseCode = "409",
+            description = "User with the same name already exists",
+            content = @Content)
+      })
+  @PostMapping
+  public UserDto create(
+      @Parameter(description = "User to be created") @RequestBody UserCreateDto userCreateDto) {
+    return userFacade.create(userCreateDto);
+  }
+
+  @Operation(
+      summary = "Get all users",
+      description = "Returns all users",
+      tags = {"user"})
+  @ApiResponses(
+      value = {
+        @ApiResponse(
+            responseCode = "200",
+            description = "Users found",
+            content = {
+              @Content(
+                  mediaType = "application/json",
+                  schema = @Schema(implementation = Result.class))
+            })
+      })
+  @GetMapping
+  public Result<UserDto> findAll(
+      @Parameter(description = "Page number of results to retrieve") @RequestParam int page) {
+    return userFacade.findAll(page);
+  }
+
+	@PutMapping("/{id}")
+	@Operation(summary = "Update a user by ID")
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "200", description = "User updated successfully"),
+			@ApiResponse(responseCode = "400", description = "Invalid input"),
+			@ApiResponse(responseCode = "404", description = "User not found"),
+			@ApiResponse(responseCode = "500", description = "Internal server error")
+	})
+	public UserDto updateById(
+			@Parameter(description = "ID of the user to be updated") @PathVariable String id,
+			@RequestBody @Valid UserUpdateDto userUpdateDto) {
+		return userFacade.updateById(userUpdateDto, id);
+	}
+
+	@DeleteMapping("/{id}")
+	@Operation(summary = "Delete a user by ID")
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "200", description = "User deleted successfully"),
+			@ApiResponse(responseCode = "404", description = "User not found"),
+			@ApiResponse(responseCode = "500", description = "Internal server error")
+	})
+	public UserDto deleteById(
+			@Parameter(description = "ID of the user to be deleted") @PathVariable String id) {
+		return userFacade.deleteById(id);
+	}
+
+	@PostMapping("/statistics")
+	@Operation(summary = "Send a user house with data")
+	@ApiResponses(value = {
+			@ApiResponse(responseCode = "200", description = "Success"),
+			@ApiResponse(responseCode = "404", description = "User not found"),
+	})
+	public List<Double> userHouseStatistics(
+			@RequestBody UserStatisticsCreateDto createStatDto) {
+		return userService.getConsumption(createStatDto.getId(), createStatDto.getHouseId(),
+				createStatDto.getStartTime(), createStatDto.getEndTime());
+	}
+
+	@Operation(
+			summary = "Get all users",
+			description = "Returns all users",
+			tags = {"user"})
+	@ApiResponses(
+			value = {
+					@ApiResponse(
+							responseCode = "200",
+							description = "Users found",
+							content = {
+									@Content(
+											mediaType = "application/json",
+											schema = @Schema(implementation = Result.class))
+							})
+			})
+	@GetMapping("/all")
+	public List<UserDto> findAll() {
+		return userFacade.findAll();
+	}
+
+	/*
+		TODO: get user with roles
+	 */
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/UserFacade.java b/core/src/main/java/cz/muni/fi/pa165/core/user/UserFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..7abd7d802a79d6ec5803110a059667f26db9bed8
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/UserFacade.java
@@ -0,0 +1,26 @@
+package cz.muni.fi.pa165.core.user;
+
+import cz.muni.fi.pa165.core.common.DomainFacade;
+import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
+import cz.muni.fi.pa165.model.dto.user.UserDto;
+import cz.muni.fi.pa165.model.dto.user.UserUpdateDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+
+@Component
+@Transactional
+public class UserFacade extends DomainFacade<User, UserDto, UserCreateDto, UserUpdateDto> {
+
+	private final UserService userService; // For the "UserService" specific methods
+	private final UserMapper userMapper;   // For the "UserMapper" specific methods
+
+	@Autowired
+	public UserFacade(UserService userService, UserMapper userMapper) {
+		super(userService, userMapper);
+		this.userService = userService;
+		this.userMapper = userMapper;
+	}
+
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/UserMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/user/UserMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..50dc58d902b457b285671a6381b6fbcb307f6ab4
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/UserMapper.java
@@ -0,0 +1,18 @@
+package cz.muni.fi.pa165.core.user;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
+import cz.muni.fi.pa165.model.dto.user.UserDto;
+import cz.muni.fi.pa165.model.dto.user.UserStatisticsCreateDto;
+import cz.muni.fi.pa165.model.dto.user.UserUpdateDto;
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface UserMapper extends DomainMapper<
+        User,
+        UserDto,
+        UserCreateDto,
+        UserUpdateDto
+        > {
+  UserStatisticsCreateDto toStatisticsDto(User entity);
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/UserRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/user/UserRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..2526372ec8950faab64cbc8357502337ca407423
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/UserRepository.java
@@ -0,0 +1,31 @@
+package cz.muni.fi.pa165.core.user;
+
+import cz.muni.fi.pa165.core.device.Device;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public interface UserRepository extends JpaRepository<User, String> {
+	@Modifying
+	@Query("UPDATE User u set u.username= :#{#user.username}, u.password= :#{#user.password}, u.lastName= :#{#user.lastName}, u.firstName= :#{#user.firstName}, u.email= :#{#user.email} where u.id = :#{#id}")
+	int update(@Param("user") User user, @Param("id") String id);
+
+
+	@Query("Select m.consumptionKWH " +
+			"From User u " +
+			"INNER JOIN House h " +
+			"INNER JOIN SmartMeter s " +
+			"INNER JOIN Metrics m " +
+			"where u.id = :#{#userId} and h.id = :#{#houseId} and m.timeStamp >= :#{#startTime} and m.timeStamp <= :#{#endTime}")
+	List<Double> getStatisticsData(@Param("userId") String userId,
+							 @Param("houseId") String houseId,
+							 @Param("startTime") LocalDateTime startTime,
+							 @Param("startTime") LocalDateTime endTime);
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/UserService.java b/core/src/main/java/cz/muni/fi/pa165/core/user/UserService.java
new file mode 100644
index 0000000000000000000000000000000000000000..f20afdfd4734929e2dcfae30ded8319560580bae
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/UserService.java
@@ -0,0 +1,40 @@
+package cz.muni.fi.pa165.core.user;
+
+import cz.muni.fi.pa165.core.common.DomainService;
+import jakarta.persistence.EntityNotFoundException;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Service
+public class UserService extends DomainService<User> {
+
+  @Getter private final UserRepository repository;
+
+  @Autowired
+  public UserService(UserRepository repository) {
+    this.repository = repository;
+  }
+
+  @Transactional(readOnly = true)
+  public User update(User user, String id) {
+    int result = repository.update(user, id);
+    if (result != 1) {
+      throw new EntityNotFoundException("User '" + id + "' not found.");
+    }
+    return findById(id);
+  }
+
+  @Transactional(readOnly = true)
+  public List<Double> getConsumption(String userId,
+                                     String houseId,
+                                     LocalDateTime startTime,
+                                     LocalDateTime endTime) {
+      return repository.getStatisticsData(userId, houseId, startTime, endTime);
+  }
+
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/UserType.java b/core/src/main/java/cz/muni/fi/pa165/core/user/UserType.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f4a527576f52885aeed928ce79cd80b5d6701dc
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/UserType.java
@@ -0,0 +1,7 @@
+package cz.muni.fi.pa165.core.user;
+
+public enum UserType {
+  NORMAL,
+  EMPLOYEE,
+  ADMIN
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/AdminRole.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/AdminRole.java
new file mode 100644
index 0000000000000000000000000000000000000000..15c54db36ea07e585c6cbe9aa12a6d8feb4bc634
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/AdminRole.java
@@ -0,0 +1,15 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.*;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@Table(name = "domain_admin")
+public class AdminRole extends Role{
+
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/EmployeeRole.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/EmployeeRole.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc8918aedbf4cf913faa75ff04526f4693afa8df
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/EmployeeRole.java
@@ -0,0 +1,19 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import cz.muni.fi.pa165.core.company.Company;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import lombok.*;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_employee")
+public class EmployeeRole extends Role{
+    @ManyToOne
+    public Company company;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/OwnerRole.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/OwnerRole.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6582e6fe432dadb59eca1418510049cbf019cc2
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/OwnerRole.java
@@ -0,0 +1,19 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import cz.muni.fi.pa165.core.house.House;
+import jakarta.persistence.Entity;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import lombok.*;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_owner")
+public class OwnerRole extends Role{
+    @ManyToOne
+    public House house;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/Role.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/Role.java
new file mode 100644
index 0000000000000000000000000000000000000000..837b99bb677f7da649b30d6b7769c9d381d624d1
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/Role.java
@@ -0,0 +1,31 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.user.User;
+import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
+import cz.muni.fi.pa165.model.dto.user.UserDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Inheritance;
+import jakarta.persistence.InheritanceType;
+import jakarta.persistence.ManyToOne;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+@Getter
+@Setter
+@Entity
+@Inheritance(strategy = InheritanceType.JOINED)
+public abstract class Role extends DomainObject {
+
+    @ManyToOne
+    public User user;
+    private RoleTypeEnum roleType;
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleController.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleController.java
new file mode 100644
index 0000000000000000000000000000000000000000..9be35953c2892a686831d4d553f36587777e7495
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleController.java
@@ -0,0 +1,104 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import cz.muni.fi.pa165.model.dto.common.Result;
+import cz.muni.fi.pa165.model.dto.role.RoleDto;
+import cz.muni.fi.pa165.model.dto.user.UserCreateDto;
+import cz.muni.fi.pa165.model.dto.user.UserDto;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.swing.*;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/role")
+public class RoleController {
+
+    private final RoleService roleService;
+    @Autowired
+    public RoleController(RoleService roleService){
+        this.roleService = roleService;
+    }
+    @Operation(
+            summary = "Create role for user",
+            description = "Creates a new user roles",
+            tags = {"role"})
+    @ApiResponses(
+            value = {
+                    @ApiResponse(
+                            responseCode = "201",
+                            description = "Role created",
+                            content = {
+                                    @Content(
+                                            mediaType = "application/json",
+                                            schema = @Schema(implementation = UserDto.class))
+                            }),
+                    @ApiResponse(responseCode = "400", description = "Invalid input", content = @Content),
+            })
+    @PostMapping
+    public Role create(
+            @Parameter(description = "Role to be created") @RequestBody Role roleDto) {
+        return roleService.create(roleDto);
+    }
+
+    @DeleteMapping("/{id}")
+    @Operation(summary = "Delete a user role")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "Role deleted successfully"),
+            @ApiResponse(responseCode = "404", description = "Role not found"),
+            @ApiResponse(responseCode = "500", description = "Internal server error")
+    })
+    public Role deleteById(
+            @Parameter(description = "ID of the role to be deleted") @PathVariable String id) {
+        return roleService.deleteById(id);
+    }
+
+    @Operation(
+            summary = "Get all user roles",
+            description = "Returns all user roles",
+            tags = {"role"})
+    @ApiResponses(
+            value = {
+                    @ApiResponse(
+                            responseCode = "200",
+                            description = "Roles found",
+                            content = {
+                                    @Content(
+                                            mediaType = "application/json",
+                                            schema = @Schema(implementation = Result.class))
+                            })
+            })
+    @GetMapping
+    public List<Role> findUserRoles(
+            @Parameter(description = "Page number of results to retrieve") @RequestParam String userId) {
+        return roleService.findAllByUser(userId);
+    }
+
+    @Operation(
+            summary = "Get all user roles",
+            description = "Returns all user roles",
+            tags = {"role"})
+    @ApiResponses(
+            value = {
+                    @ApiResponse(
+                            responseCode = "200",
+                            description = "Roles found",
+                            content = {
+                                    @Content(
+                                            mediaType = "application/json",
+                                            schema = @Schema(implementation = Result.class))
+                            })
+            })
+    @GetMapping("/all")
+    public List<Role> findAll(
+            @Parameter(description = "Page number of results to retrieve") @RequestParam String userId) {
+        return roleService.findAll();
+    }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleMapper.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1600f114cd4a228b72cc570f5385ebe755c79f9
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleMapper.java
@@ -0,0 +1,30 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import cz.muni.fi.pa165.core.common.DomainMapper;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import cz.muni.fi.pa165.model.dto.role.RoleDto;
+import cz.muni.fi.pa165.model.dto.role.RoleCreateDto;
+import cz.muni.fi.pa165.model.dto.role.RoleUpdateDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterCreateDto;
+import cz.muni.fi.pa165.model.dto.smartDevice.SmartMeterDto;
+import org.mapstruct.Mapping;
+
+import java.util.List;
+
+public interface RoleMapper extends DomainMapper<Role, RoleDto, RoleCreateDto, RoleUpdateDto> {
+    /*
+    @Mapping(source = "deviceDto", target = "device")
+    SmartMeter fromCreateDto(SmartMeterCreateDto dto);
+
+    //@Mapping(source = "deviceDto", target = "device")
+    //SmartMeter fromUpdateDto(SmartMeterUpdateDto dto);
+
+    @Mapping(source = "roleDto", target = "role")
+    SmartMeter fromDto(SmartMeterDto dto);
+
+    @Mapping(source = "device", target = "deviceDto")
+    SmartMeterDto toDto(SmartMeter entity);
+
+    /*@Mapping(source = "device", target = "deviceDto")
+    List<SmartMeterDto> toDtoList(List<SmartMeter> entities);*/
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleRepository.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..048ca18b6f6bf5da5d95421bcfb4b0a52bd174dd
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleRepository.java
@@ -0,0 +1,13 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import cz.muni.fi.pa165.core.user.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface RoleRepository extends JpaRepository<Role, String> {
+
+    public List<Role> findAllByUser(String userId);
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleService.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleService.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd6bc3b49853bb8f4d4f12fde80da25d9f2bc479
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleService.java
@@ -0,0 +1,33 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+import cz.muni.fi.pa165.core.common.DomainObject;
+import cz.muni.fi.pa165.core.common.DomainService;
+import cz.muni.fi.pa165.model.dto.role.RoleDto;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Getter
+@Setter
+@Service
+public class RoleService extends DomainService<Role> {
+
+    @Getter
+    private final RoleRepository repository;
+
+    @Autowired
+    public RoleService(RoleRepository repository){
+        this.repository = repository;
+    }
+
+    @Transactional
+    public List<Role> findAllByUser(String id){
+        return repository.findAllByUser(id);
+    }
+}
diff --git a/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleTypeEnum.java b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleTypeEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..8fbc793338c1abb37e27097d348f45a00300a0e1
--- /dev/null
+++ b/core/src/main/java/cz/muni/fi/pa165/core/user/roles/RoleTypeEnum.java
@@ -0,0 +1,7 @@
+package cz.muni.fi.pa165.core.user.roles;
+
+public enum RoleTypeEnum {
+    Admin,
+    Employee,
+    Owner
+}
diff --git a/src/main/java/fi/muni/pa165/smartenergymanagementsystem/api/.gitkeep b/core/src/main/resources/application.properties
similarity index 100%
rename from src/main/java/fi/muni/pa165/smartenergymanagementsystem/api/.gitkeep
rename to core/src/main/resources/application.properties
diff --git a/core/src/main/resources/application.yml b/core/src/main/resources/application.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f062a9f94775452e30c68582e659bd880312bd91
--- /dev/null
+++ b/core/src/main/resources/application.yml
@@ -0,0 +1,24 @@
+# see https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html
+server:
+  error:
+    include-message: always
+logging:
+  level:
+    root: warn
+    cz:
+      muni: debug
+    org:
+      springframework:
+        web: info
+spring:
+  mvc:
+    log-request-details: true
+
+springdoc:
+  # https://springdoc.org/properties.html#_springdoc_openapi_core_properties
+  api-docs:
+    path: /openapi
+  # https://springdoc.org/properties.html#_swagger_ui_properties
+  swagger-ui:
+    path: /swagger-ui.html
+    tryItOutEnabled: true
diff --git a/core/src/main/resources/banner.txt b/core/src/main/resources/banner.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d84cd59ef17c5191b842157dfb0eefb0775ab8da
--- /dev/null
+++ b/core/src/main/resources/banner.txt
@@ -0,0 +1,6 @@
+,------.                                     ,--.   ,--.                                                         ,--.    ,---.                 ,--.
+|  .---',--,--, ,---. ,--.--. ,---.,--. ,--. |   `.'   | ,--,--.,--,--,  ,--,--. ,---. ,--,--,--.,---. ,--,--, ,-'  '-. '   .-',--. ,--.,---.,-'  '-. ,---. ,--,--,--.
+|  `--, |      \ .-. :|  .--'| .-. |\  '  /  |  |'.'|  |' ,-.  ||      \' ,-.  || .-. ||        | .-. :|      \'-.  .-' `.  `-. \  '  /(  .-''-.  .-'| .-. :|        |
+|  `---.|  ||  \   --.|  |   ' '-' ' \   '   |  |   |  |\ '-'  ||  ||  |\ '-'  |' '-' '|  |  |  \   --.|  ||  |  |  |   .-'    | \   ' .-'  `) |  |  \   --.|  |  |  |
+`------'`--''--'`----'`--'   .`-  /.-'  /    `--'   `--' `--`--'`--''--' `--`--'.`-  / `--`--`--'`----'`--''--'  `--'   `-----'.-'  /  `----'  `--'   `----'`--`--`--'
+                             `---' `---'                                        `---'                                          `---'
\ No newline at end of file
diff --git a/src/test/java/fi/muni/pa165/smartenergymanagementsystem/AppTest.java b/core/src/test/java/cz/muni/fi/pa165/core/CoreApplicationTest.java
similarity index 53%
rename from src/test/java/fi/muni/pa165/smartenergymanagementsystem/AppTest.java
rename to core/src/test/java/cz/muni/fi/pa165/core/CoreApplicationTest.java
index 33bace476db1aaedc35fe8506c72b982f75f2d46..4a5948aaf1349e50bdfa1d2eb23ba440f5c190ba 100644
--- a/src/test/java/fi/muni/pa165/smartenergymanagementsystem/AppTest.java
+++ b/core/src/test/java/cz/muni/fi/pa165/core/CoreApplicationTest.java
@@ -1,13 +1,11 @@
-package fi.muni.pa165.smartenergymanagementsystem;
+package cz.muni.fi.pa165.core;
 
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 
 @SpringBootTest
-class AppTest {
-
-	@Test
-	void contextLoads() {
-	}
+class CoreApplicationTest {
 
+  /*@Test
+  void contextLoads() {}*/
 }
diff --git a/core/src/test/java/cz/muni/fi/pa165/core/company/UnitTestCompanyJPA.java b/core/src/test/java/cz/muni/fi/pa165/core/company/UnitTestCompanyJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..247af80a49110f0d675304482527a640f9384d38
--- /dev/null
+++ b/core/src/test/java/cz/muni/fi/pa165/core/company/UnitTestCompanyJPA.java
@@ -0,0 +1,134 @@
+package cz.muni.fi.pa165.core.company;
+
+import cz.muni.fi.pa165.core.house.HouseRepository;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeterRepository;
+import cz.muni.fi.pa165.core.user.UserRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.regex.Pattern;
+
+import static org.assertj.core.api.Assertions.assertThat;
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestCompanyJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private CompanyRepository companyRepository;
+    @Autowired
+    private HouseRepository houseRepository;
+    @Autowired
+    private SmartMeterRepository smartMeterRepository;
+    @Autowired
+    private UserRepository userRepository;
+
+    @Test
+    public void createCompanyTesting() throws Exception {
+        String company = this.entityManager.persistAndGetId(new Company()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(company).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoneIfRepositoryIsEmpty() {
+        Iterable<Company> companies = companyRepository.findAll();
+        assertThat(companies).isEmpty();
+    }
+
+    private Company helperRegister() {
+        return companyRepository.save(new Company("Tesla"));
+    }
+
+    @Test
+    public void shouldStore() {
+        Company company = helperRegister();
+
+        assertThat(company).hasFieldOrPropertyWithValue("name", "Tesla");
+    }
+
+    @Test
+    public void shouldFindAll() {
+        Company company = new Company();
+        entityManager.persist(company);
+
+        Company company1 = new Company();
+        entityManager.persist(company1);
+
+        Company company2 = new Company();
+        entityManager.persist(company2);
+
+        assertThat(companyRepository.findAll()).hasSize(3).contains(company, company1, company2);
+    }
+
+    @Test
+    public void shouldFindById() {
+        Company company = new Company();
+        entityManager.persist(company);
+
+        Company company1 = new Company();
+        entityManager.persist(company1);
+
+        Company company2 = new Company();
+        entityManager.persist(company2);
+
+        Company found = companyRepository.findById(company2.getId()).get();
+
+        assertThat(found).isEqualTo(company2);
+
+        found = companyRepository.findById(company1.getId()).get();
+
+        assertThat(found).isEqualTo(company1);
+    }
+
+    @Test
+    public void shouldUpdateById() {
+        Company company = new Company();
+        entityManager.persist(company);
+
+        Company company1 = new Company();
+        entityManager.persist(company1);
+
+        Company updateCompany = companyRepository.findById(company1.getId()).get();
+        updateCompany.setName("Gorenje");
+        companyRepository.save(updateCompany);
+
+        Company check = companyRepository.findById(company1.getId()).get();
+
+        assertThat(check.getId()).isEqualTo(company1.getId());
+        assertThat(check.getName()).isEqualTo(company1.getName());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        Company company = new Company();
+        entityManager.persist(company);
+
+        Company company1 = helperRegister();
+        entityManager.persist(company1);
+
+        companyRepository.deleteById(company1.getId());
+
+        assertThat(companyRepository.findAll()).hasSize(1).contains(company);
+        assertThat(companyRepository.findAll()).hasSize(1).doesNotContain(company1);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(helperRegister());
+        entityManager.persist(helperRegister());
+
+        companyRepository.deleteAll();
+
+        assertThat(companyRepository.findAll()).isEmpty();
+    }
+}
diff --git a/core/src/test/java/cz/muni/fi/pa165/core/device/UnitTestDeviceJPA.java b/core/src/test/java/cz/muni/fi/pa165/core/device/UnitTestDeviceJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..e935bc2bb02e15bed870fdad34849f200e243c30
--- /dev/null
+++ b/core/src/test/java/cz/muni/fi/pa165/core/device/UnitTestDeviceJPA.java
@@ -0,0 +1,149 @@
+package cz.muni.fi.pa165.core.device;
+
+import cz.muni.fi.pa165.core.house.HouseRepository;
+import cz.muni.fi.pa165.core.manufacturer.Manufacturer;
+import cz.muni.fi.pa165.core.manufacturer.ManufacturerRepository;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeterRepository;
+import cz.muni.fi.pa165.core.user.UserRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestDeviceJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private HouseRepository houseRepository;
+    @Autowired
+    private SmartMeterRepository smartMeterRepository;
+    @Autowired
+    private DeviceRepository deviceRepository;
+    @Autowired
+    private ManufacturerRepository manufacturerRepository;
+    @Autowired
+    private UserRepository userRepository;
+
+    @Test
+    public void createDeviceTesting() throws Exception {
+        String device = this.entityManager.persistAndGetId(new Device()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(device).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoDevicesIfRepositoryIsEmpty() {
+        Iterable<Device> devices = deviceRepository.findAll();
+        assertThat(devices).isEmpty();
+    }
+
+    private Device helperRegisterDevice() {
+        Iterable<SmartMeter> smartMeterIterable;
+        smartMeterIterable = smartMeterRepository.saveAll(List.of(new SmartMeter(), new SmartMeter(), new SmartMeter()));
+        List<SmartMeter> list = StreamSupport.stream(smartMeterIterable.spliterator(), false)
+                .collect(Collectors.toList());
+        //need to save a user to the database first to asign him to the new device
+        Manufacturer manufacturer = manufacturerRepository.save(new Manufacturer());
+        return deviceRepository.save(new Device("Tesla Smart Meter A134", list, manufacturer));
+    }
+
+    @Test
+    public void shouldStoreADevice() {
+        Device device = helperRegisterDevice();
+
+        assertThat(device).hasFieldOrPropertyWithValue("name", "Tesla Smart Meter A134");
+    }
+
+    @Test
+    public void shouldFindAllDevices() {
+        Device device1 = new Device();
+        entityManager.persist(device1);
+
+        Device device2 = new Device();
+        entityManager.persist(device2);
+
+        assertThat(deviceRepository.findAll()).hasSize(2).contains(device1, device2);
+    }
+
+    @Test
+    public void shouldFindDeviceById() {
+        Device device1 = new Device();
+        entityManager.persist(device1);
+
+        Device device2 = new Device();
+        entityManager.persist(device2);
+
+        Device foundDevice = deviceRepository.findById(device2.getId()).get();
+
+        assertThat(foundDevice).isEqualTo(device2);
+
+        foundDevice = deviceRepository.findById(device1.getId()).get();
+
+        assertThat(foundDevice).isEqualTo(device1);
+    }
+
+    @Test
+    public void shouldUpdateDeviceById() {
+        Device device1 = new Device();
+        entityManager.persist(device1);
+
+        Device device2 = new Device();
+        entityManager.persist(device2);
+
+
+
+        Device updatedDevice = deviceRepository.findById(device2.getId()).get();
+        updatedDevice.setName("Smart Meter Gorenje V245");
+        deviceRepository.save(updatedDevice);
+
+        Device checkDevice = deviceRepository.findById(device2.getId()).get();
+
+        assertThat(checkDevice.getId()).isEqualTo(device2.getId());
+        assertThat(checkDevice.getName()).isEqualTo(device2.getName());
+        assertThat(checkDevice.getManufacturer()).isEqualTo(device2.getManufacturer());
+        assertThat(checkDevice.getCreatedDateTime()).isEqualTo(device2.getCreatedDateTime());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        Device device1 = new Device();
+        entityManager.persist(device1);
+
+        Device device2 = new Device();
+        entityManager.persist(device2);
+
+        Device device = helperRegisterDevice();
+        entityManager.persist(device);
+
+        deviceRepository.deleteById(device.getId());
+
+        assertThat(deviceRepository.findAll()).hasSize(2).doesNotContain(device);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(helperRegisterDevice());
+        entityManager.persist(helperRegisterDevice());
+
+        houseRepository.deleteAll();
+
+        assertThat(houseRepository.findAll()).isEmpty();
+    }
+}
\ No newline at end of file
diff --git a/core/src/test/java/cz/muni/fi/pa165/core/house/UnitTestHouseJPA.java b/core/src/test/java/cz/muni/fi/pa165/core/house/UnitTestHouseJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2af8041acf75a57735a47393bf2c6cc1988ade5
--- /dev/null
+++ b/core/src/test/java/cz/muni/fi/pa165/core/house/UnitTestHouseJPA.java
@@ -0,0 +1,151 @@
+package cz.muni.fi.pa165.core.house;
+
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeterRepository;
+import cz.muni.fi.pa165.core.user.User;
+import cz.muni.fi.pa165.core.user.UserRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestHouseJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private HouseRepository houseRepository;
+    @Autowired
+    private SmartMeterRepository smartMeterRepository;
+    @Autowired
+    private UserRepository userRepository;
+
+    @Test
+    public void createHouseTesting() throws Exception {
+        String house = this.entityManager.persistAndGetId(new House()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(house).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoHousesIfRepositoryIsEmpty() {
+        Iterable<House> houses = houseRepository.findAll();
+        assertThat(houses).isEmpty();
+    }
+
+    private House helperRegisterHouse() {
+        //need to register a house first
+        Iterable<SmartMeter> smartMeterIterable;
+        smartMeterIterable = smartMeterRepository.saveAll(List.of(new SmartMeter(), new SmartMeter(), new SmartMeter()));
+        List<SmartMeter> list = StreamSupport.stream(smartMeterIterable.spliterator(), false)
+                .collect(Collectors.toList());
+        //need to save a user to the database first to asign him to the new house
+        User user = userRepository.save(new User());
+        return houseRepository.save(new House("Titova 6", "Sarajevo", "Bosnia and Herzegovina", "71000", list, user));
+    }
+
+    @Test
+    public void shouldStoreAHouse() {
+        House house = helperRegisterHouse();
+
+        assertThat(house).hasFieldOrPropertyWithValue("address", "Titova 6");
+        assertThat(house).hasFieldOrPropertyWithValue("city", "Sarajevo");
+        assertThat(house).hasFieldOrPropertyWithValue("state", "Bosnia and Herzegovina");
+        assertThat(house).hasFieldOrPropertyWithValue("zipcode", "71000");
+    }
+
+    @Test
+    public void shouldFindAllHouses() {
+        House house1 = new House();
+        entityManager.persist(house1);
+
+        House house2 = new House();
+        entityManager.persist(house2);
+
+        House house3 = new House();
+        entityManager.persist(house3);
+
+        Iterable houses = houseRepository.findAll();
+
+        assertThat(houses).hasSize(3).contains(house1, house2, house3);
+    }
+
+    @Test
+    public void shouldFindHouseById() {
+        House house1 = new House();
+        entityManager.persist(house1);
+        House house2 = new House();
+        entityManager.persist(house2);
+
+        House foundHouse = houseRepository.findById(house2.getId()).get();
+
+        assertThat(foundHouse).isEqualTo(house2);
+
+        foundHouse = houseRepository.findById(house1.getId()).get();
+
+        assertThat(foundHouse).isEqualTo(house1);
+    }
+
+    @Test
+    public void shouldUpdateHouseById() {
+        House house = new House();
+        entityManager.persist(house);
+
+        House house2 = new House();
+        entityManager.persist(house2);
+
+
+
+        House updatedHouse = houseRepository.findById(house2.getId()).get();
+        updatedHouse.setAddress("Botanicka");
+        updatedHouse.setCity("Brno");
+        updatedHouse.setState("Czech Republic");
+        updatedHouse.setZipcode("61600");
+        houseRepository.save(updatedHouse);
+
+        House checkHouse = houseRepository.findById(house2.getId()).get();
+
+        assertThat(checkHouse.getId()).isEqualTo(house2.getId());
+        assertThat(checkHouse.getAddress()).isEqualTo(house2.getAddress());
+        assertThat(checkHouse.getUser()).isEqualTo(house2.getUser());
+        assertThat(checkHouse.getCity()).isEqualTo(house2.getCity());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        House house = new House();
+        entityManager.persist(house);
+
+        House house1 = helperRegisterHouse();
+        entityManager.persist(house1);
+
+        houseRepository.deleteById(house1.getId());
+
+        assertThat(houseRepository.findAll()).hasSize(1).contains(house);
+        assertThat(houseRepository.findAll()).hasSize(1).doesNotContain(house1);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(helperRegisterHouse());
+        entityManager.persist(helperRegisterHouse());
+
+        houseRepository.deleteAll();
+
+        assertThat(houseRepository.findAll()).isEmpty();
+    }
+}
\ No newline at end of file
diff --git a/core/src/test/java/cz/muni/fi/pa165/core/manufacturer/UnitTestManufacturerJPA.java b/core/src/test/java/cz/muni/fi/pa165/core/manufacturer/UnitTestManufacturerJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..bec00b99af94dda933f75f5c5bc497f7941f429f
--- /dev/null
+++ b/core/src/test/java/cz/muni/fi/pa165/core/manufacturer/UnitTestManufacturerJPA.java
@@ -0,0 +1,149 @@
+package cz.muni.fi.pa165.core.manufacturer;
+
+import cz.muni.fi.pa165.core.device.Device;
+import cz.muni.fi.pa165.core.device.DeviceRepository;
+import cz.muni.fi.pa165.core.house.HouseRepository;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeterRepository;
+import cz.muni.fi.pa165.core.user.UserRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestManufacturerJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private HouseRepository houseRepository;
+    @Autowired
+    private SmartMeterRepository smartMeterRepository;
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private ManufacturerRepository manufacturerRepository;
+
+    @Autowired
+    private DeviceRepository deviceRepository;
+
+    @Test
+    public void createTesting() throws Exception {
+        String manufacturer = this.entityManager.persistAndGetId(new Manufacturer()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(manufacturer).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoneIfRepositoryIsEmpty() {
+        Iterable<Manufacturer> manufacturers = manufacturerRepository.findAll();
+        assertThat(manufacturers).isEmpty();
+    }
+
+    private Manufacturer helperRegister() {
+        Iterable<Device> deviceIterable;
+        deviceIterable = deviceRepository.saveAll(List.of(new Device(), new Device(), new Device()));
+        List<Device> list = StreamSupport.stream(deviceIterable.spliterator(), false)
+                .collect(Collectors.toList());
+        return manufacturerRepository.save(new Manufacturer("Manufacturer1", list));
+    }
+
+    @Test
+    public void shouldStore() {
+        Manufacturer manufacturer = helperRegister();
+
+        assertThat(manufacturer).hasFieldOrPropertyWithValue("name", "Manufacturer1");
+    }
+
+    @Test
+    public void shouldFindAll() {
+        Manufacturer m = new Manufacturer();
+        entityManager.persist(m);
+
+        Manufacturer m1 = new Manufacturer();
+        entityManager.persist(m1);
+
+        Manufacturer m2 = new Manufacturer();
+        entityManager.persist(m2);
+
+        assertThat(manufacturerRepository.findAll()).hasSize(3).contains(m, m1, m2);
+    }
+
+    @Test
+    public void shouldFindById() {
+        Manufacturer m = new Manufacturer();
+        entityManager.persist(m);
+
+        Manufacturer m1 = new Manufacturer();
+        entityManager.persist(m1);
+
+        Manufacturer m2 = new Manufacturer();
+        entityManager.persist(m2);
+
+        Manufacturer found = manufacturerRepository.findById(m.getId()).get();
+
+        assertThat(found).isEqualTo(m);
+
+        found = manufacturerRepository.findById(m.getId()).get();
+
+        assertThat(found).isEqualTo(m);
+    }
+
+    @Test
+    public void shouldUpdateById() {
+        Manufacturer m = new Manufacturer();
+        entityManager.persist(m);
+
+        Manufacturer m1 = new Manufacturer();
+        entityManager.persist(m1);
+
+        Manufacturer update = manufacturerRepository.findById(m.getId()).get();
+        update.setName("New name");
+        manufacturerRepository.save(update);
+
+        Manufacturer check = manufacturerRepository.findById(m.getId()).get();
+
+        assertThat(check.getId()).isEqualTo(m.getId());
+        assertThat(check.getName()).isEqualTo(m.getName());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        Manufacturer m = new Manufacturer();
+        entityManager.persist(m);
+
+        Manufacturer m1 = new Manufacturer();
+        entityManager.persist(m1);
+
+        manufacturerRepository.deleteById(m.getId());
+
+        assertThat(manufacturerRepository.findAll()).hasSize(1).contains(m1);
+        assertThat(manufacturerRepository.findAll()).hasSize(1).doesNotContain(m);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(helperRegister());
+        entityManager.persist(helperRegister());
+
+        manufacturerRepository.deleteAll();
+
+        assertThat(manufacturerRepository.findAll()).isEmpty();
+    }
+}
+
diff --git a/core/src/test/java/cz/muni/fi/pa165/core/metrics/UnitTestMetricsJPA.java b/core/src/test/java/cz/muni/fi/pa165/core/metrics/UnitTestMetricsJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..0117b153b88f5f7bfa141da1200dbf1f8b560800
--- /dev/null
+++ b/core/src/test/java/cz/muni/fi/pa165/core/metrics/UnitTestMetricsJPA.java
@@ -0,0 +1,140 @@
+package cz.muni.fi.pa165.core.metrics;
+
+import cz.muni.fi.pa165.core.house.HouseRepository;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
+import cz.muni.fi.pa165.core.smartmeter.SmartMeterRepository;
+import cz.muni.fi.pa165.core.user.UserRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+import java.time.LocalDateTime;
+import java.util.regex.Pattern;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestMetricsJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private HouseRepository houseRepository;
+    @Autowired
+    private SmartMeterRepository smartMeterRepository;
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private MetricsRepository metricsRepository;
+
+    @Test
+    public void createTesting() throws Exception {
+        String metrics = this.entityManager.persistAndGetId(new Metrics()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(metrics).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoneIfRepositoryIsEmpty() {
+        Iterable<Metrics> metrics = metricsRepository.findAll();
+        assertThat(metrics).isEmpty();
+    }
+
+    private Metrics helperRegister() {
+        SmartMeter m = new SmartMeter();
+        smartMeterRepository.save(m);
+        return metricsRepository.save(new Metrics(LocalDateTime.now(), 123.0, m));
+    }
+
+    @Test
+    public void shouldStore() {
+        Metrics metrics = helperRegister();
+
+        assertThat(metrics).hasFieldOrPropertyWithValue("consumptionKWH", 123.0);
+    }
+
+    @Test
+    public void shouldFindAll() {
+        Metrics metrics = new Metrics();
+        entityManager.persist(metrics);
+
+        Metrics metrics1 = new Metrics();
+        entityManager.persist(metrics1);
+
+        Metrics metrics2 = new Metrics();
+        entityManager.persist(metrics2);
+
+        assertThat(metricsRepository.findAll()).hasSize(3).contains(metrics, metrics1, metrics2);
+    }
+
+    @Test
+    public void shouldFindById() {
+        Metrics metrics = new Metrics();
+        entityManager.persist(metrics);
+
+        Metrics metrics1 = new Metrics();
+        entityManager.persist(metrics1);
+
+        Metrics metrics2 = new Metrics();
+        entityManager.persist(metrics2);
+
+        Metrics found = metricsRepository.findById(metrics1.getId()).get();
+
+        assertThat(found).isEqualTo(metrics1);
+
+        found = metricsRepository.findById(metrics.getId()).get();
+
+        assertThat(found).isEqualTo(metrics);
+    }
+
+    @Test
+    public void shouldUpdateById() {
+        Metrics metrics = new Metrics();
+        entityManager.persist(metrics);
+
+        Metrics metrics1 = new Metrics();
+        entityManager.persist(metrics1);
+
+        Metrics update = metricsRepository.findById(metrics.getId()).get();
+        update.setConsumptionKWH(1133.0);
+        metricsRepository.save(update);
+
+        Metrics check = metricsRepository.findById(metrics.getId()).get();
+
+        assertThat(check.getId()).isEqualTo(metrics.getId());
+        assertThat(check.getConsumptionKWH()).isEqualTo(metrics.getConsumptionKWH());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        Metrics metrics = new Metrics();
+        entityManager.persist(metrics);
+
+        Metrics metrics1 = helperRegister();
+        entityManager.persist(metrics1);
+
+        metricsRepository.deleteById(metrics1.getId());
+
+        assertThat(metricsRepository.findAll()).hasSize(1).contains(metrics);
+        assertThat(metricsRepository.findAll()).hasSize(1).doesNotContain(metrics1);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(helperRegister());
+        entityManager.persist(helperRegister());
+
+        metricsRepository.deleteAll();
+
+        assertThat(metricsRepository.findAll()).isEmpty();
+    }
+}
+
diff --git a/core/src/test/java/cz/muni/fi/pa165/core/smartmeter/UnitTestSmartMeterJPA.java b/core/src/test/java/cz/muni/fi/pa165/core/smartmeter/UnitTestSmartMeterJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..fff444c493efde0d2816f70508d465699e674b94
--- /dev/null
+++ b/core/src/test/java/cz/muni/fi/pa165/core/smartmeter/UnitTestSmartMeterJPA.java
@@ -0,0 +1,153 @@
+package cz.muni.fi.pa165.core.smartmeter;
+
+import cz.muni.fi.pa165.core.device.Device;
+import cz.muni.fi.pa165.core.device.DeviceRepository;
+import cz.muni.fi.pa165.core.house.House;
+import cz.muni.fi.pa165.core.house.HouseRepository;
+import cz.muni.fi.pa165.core.metrics.Metrics;
+import cz.muni.fi.pa165.core.metrics.MetricsRepository;
+import cz.muni.fi.pa165.core.user.UserRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestSmartMeterJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private HouseRepository houseRepository;
+    @Autowired
+    private SmartMeterRepository smartMeterRepository;
+    @Autowired
+    private UserRepository userRepository;
+
+    @Autowired
+    private DeviceRepository deviceRepository;
+    @Autowired
+    private MetricsRepository metricsRepository;
+
+    @Test
+    public void createTesting() throws Exception {
+        String m = this.entityManager.persistAndGetId(new SmartMeter()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(m).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoneIfRepositoryIsEmpty() {
+        Iterable<SmartMeter> m = smartMeterRepository.findAll();
+        assertThat(m).isEmpty();
+    }
+
+    private SmartMeter helperRegister() {
+        Iterable<Metrics> metrics;
+        metrics = metricsRepository.saveAll(List.of(new Metrics(), new Metrics(), new Metrics()));
+        List<Metrics> list = StreamSupport.stream(metrics.spliterator(), false)
+                .collect(Collectors.toList());
+        Device device = deviceRepository.save(new Device());
+        House house = houseRepository.save(new House());
+        return smartMeterRepository.save(new SmartMeter("OneT Tesla 1232", device, house, list));
+    }
+
+    @Test
+    public void shouldStore() {
+        SmartMeter smartMeter = helperRegister();
+
+        assertThat(smartMeter).hasFieldOrPropertyWithValue("name", "OneT Tesla 1232");
+    }
+
+    @Test
+    public void shouldFindAll() {
+        SmartMeter m = new SmartMeter();
+        entityManager.persist(m);
+
+        SmartMeter m1 = new SmartMeter();
+        entityManager.persist(m1);
+
+        SmartMeter m2 = new SmartMeter();
+        entityManager.persist(m2);
+
+        assertThat(smartMeterRepository.findAll()).hasSize(3).contains(m, m1, m2);
+    }
+
+    @Test
+    public void shouldFindById() {
+        SmartMeter m = new SmartMeter();
+        entityManager.persist(m);
+
+        SmartMeter m1 = new SmartMeter();
+        entityManager.persist(m1);
+
+        SmartMeter m2 = new SmartMeter();
+        entityManager.persist(m2);
+
+        SmartMeter found = smartMeterRepository.findById(m.getId()).get();
+
+        assertThat(found).isEqualTo(m);
+
+        found = smartMeterRepository.findById(m.getId()).get();
+
+        assertThat(found).isEqualTo(m);
+    }
+
+    @Test
+    public void shouldUpdateById() {
+        SmartMeter m = new SmartMeter();
+        entityManager.persist(m);
+
+        SmartMeter m1 = new SmartMeter();
+        entityManager.persist(m1);
+
+        SmartMeter update = smartMeterRepository.findById(m.getId()).get();
+        update.setName("New name");
+        smartMeterRepository.save(update);
+
+        SmartMeter check = smartMeterRepository.findById(m.getId()).get();
+
+        assertThat(check.getId()).isEqualTo(m.getId());
+        assertThat(check.getName()).isEqualTo(m.getName());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        SmartMeter m = new SmartMeter();
+        entityManager.persist(m);
+
+        SmartMeter m1 = new SmartMeter();
+        entityManager.persist(m1);
+
+        smartMeterRepository.deleteById(m.getId());
+
+        assertThat(smartMeterRepository.findAll()).hasSize(1).contains(m1);
+        assertThat(smartMeterRepository.findAll()).hasSize(1).doesNotContain(m);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(helperRegister());
+        entityManager.persist(helperRegister());
+
+        smartMeterRepository.deleteAll();
+
+        assertThat(smartMeterRepository.findAll()).isEmpty();
+    }
+}
+
+
diff --git a/core/src/test/java/cz/muni/fi/pa165/core/user/UnitTestUserJPA.java b/core/src/test/java/cz/muni/fi/pa165/core/user/UnitTestUserJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..34f587c9c3d6ffa8596bcf68c80c7adf3dbdf018
--- /dev/null
+++ b/core/src/test/java/cz/muni/fi/pa165/core/user/UnitTestUserJPA.java
@@ -0,0 +1,125 @@
+package cz.muni.fi.pa165.core.user;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.regex.Pattern;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestUserJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private UserRepository userRepository;
+
+
+    @Test
+    public void createTesting() throws Exception {
+        String user = this.entityManager.persistAndGetId(new User()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(user).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoneIfRepositoryIsEmpty() {
+        Iterable<User> users = userRepository.findAll();
+        assertThat(users).isEmpty();
+    }
+
+    private User helperRegister() {
+        User m = new User();
+        userRepository.save(m);
+        return userRepository.save(new User("xuser1", UserType.NORMAL, "password", "abc@gmail.com", "Anesa", "Fazlagic", null));
+    }
+
+    @Test
+    public void shouldStore() {
+        User user = helperRegister();
+
+        assertThat(user).hasFieldOrPropertyWithValue("username", "xuser1");
+    }
+
+    @Test
+    public void shouldFindAll() {
+        User user = new User();
+        entityManager.persist(user);
+
+        User user1 = new User();
+        entityManager.persist(user1);
+
+        assertThat(userRepository.findAll()).hasSize(2).contains(user, user1);
+    }
+
+    @Test
+    public void shouldFindById() {
+        User user = new User();
+        entityManager.persist(user);
+
+        User user1 = new User();
+        entityManager.persist(user1);
+
+        User found = userRepository.findById(user.getId()).get();
+
+        assertThat(found).isEqualTo(user);
+
+        found = userRepository.findById(user1.getId()).get();
+
+        assertThat(found).isEqualTo(user1);
+    }
+
+    @Test
+    public void shouldUpdateById() {
+        User user = new User();
+        entityManager.persist(user);
+
+        User user1 = new User();
+        entityManager.persist(user1);
+
+        User update = userRepository.findById(user.getId()).get();
+        update.setUsername("xfazlag");
+        userRepository.save(update);
+
+        User check = userRepository.findById(user.getId()).get();
+
+        assertThat(check.getId()).isEqualTo(user.getId());
+        assertThat(check.getUsername()).isEqualTo(user.getUsername());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        User user = new User();
+        entityManager.persist(user);
+
+        User user1 = new User();
+        entityManager.persist(user1);
+
+        userRepository.deleteById(user1.getId());
+
+        assertThat(userRepository.findAll()).hasSize(1).contains(user);
+        assertThat(userRepository.findAll()).hasSize(1).doesNotContain(user1);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(helperRegister());
+        entityManager.persist(helperRegister());
+
+        userRepository.deleteAll();
+
+        assertThat(userRepository.findAll()).isEmpty();
+    }
+}
+
+
diff --git a/emailmicroservice/emailmicroserviceopenapi.yaml b/emailmicroservice/emailmicroserviceopenapi.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..88408e7035083db3688237626847a60b35d144cb
--- /dev/null
+++ b/emailmicroservice/emailmicroserviceopenapi.yaml
@@ -0,0 +1,36 @@
+openapi: "3.0.3"
+info:
+  title: "smart_energy_management_system API"
+  description: "smart_energy_management_system API"
+  version: "1.0.0"
+servers:
+  - url: "https://smart_energy_management_system"
+paths:
+  /api/email/sendemail:
+    post:
+      summary: "POST api/email/sendemail"
+      operationId: "sendEmail"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/EmailTemplate"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/EmailTemplate"
+components:
+  schemas:
+    EmailTemplate:
+      type: "object"
+      properties:
+        sendTo:
+          type: "string"
+        subject:
+          type: "string"
+        body:
+          type: "string"
\ No newline at end of file
diff --git a/emailmicroservice/mvnw b/emailmicroservice/mvnw
new file mode 100644
index 0000000000000000000000000000000000000000..8a8fb2282df5b8f7263470a5a2dc0e196f35f35f
--- /dev/null
+++ b/emailmicroservice/mvnw
@@ -0,0 +1,316 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /usr/local/etc/mavenrc ] ; then
+    . /usr/local/etc/mavenrc
+  fi
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="`\\unset -f command; \\command -v java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  $MAVEN_DEBUG_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" \
+  "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/emailmicroservice/mvnw.cmd b/emailmicroservice/mvnw.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..1d8ab018eaf11d9b3a4a90e7818ace373dfbb380
--- /dev/null
+++ b/emailmicroservice/mvnw.cmd
@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+  %JVM_CONFIG_MAVEN_PROPS% ^
+  %MAVEN_OPTS% ^
+  %MAVEN_DEBUG_OPTS% ^
+  -classpath %WRAPPER_JAR% ^
+  "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/emailmicroservice/pom.xml b/emailmicroservice/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..990589d4d884940d8a9423a064205512a244f653
--- /dev/null
+++ b/emailmicroservice/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>smart-energy-management-system</artifactId>
+        <groupId>cz.muni.fi.pa165</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>emailmicroservice</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/src/main/java/fi/muni/pa165/smartenergymanagementsystem/App.java b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/App.java
similarity index 54%
rename from src/main/java/fi/muni/pa165/smartenergymanagementsystem/App.java
rename to emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/App.java
index 52d23decdd81a8246a990f1015363ec46d3c9734..94bbd84d9203368d8c23c875195b3063fe14a18c 100644
--- a/src/main/java/fi/muni/pa165/smartenergymanagementsystem/App.java
+++ b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/App.java
@@ -1,4 +1,4 @@
-package fi.muni.pa165.smartenergymanagementsystem;
+package cz.muni.fi.pa165.microservice3;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -6,8 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 @SpringBootApplication
 public class App {
 
-	public static void main(String[] args) {
-		SpringApplication.run(App.class, args);
-	}
-
+  public static void main(String[] args) {
+    SpringApplication.run(App.class, args);
+  }
 }
diff --git a/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailController.java b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailController.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8243d2a5adbfdbbb5031245440d48cbc459dfcf
--- /dev/null
+++ b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailController.java
@@ -0,0 +1,54 @@
+package cz.muni.fi.pa165.microservice3.email;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.mail.MailAuthenticationException;
+import org.springframework.mail.MailException;
+import org.springframework.mail.MailSendException;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ResponseStatusException;
+
+@RestController
+@RequestMapping("/api/email")
+@Tag(name = "Email", description = "Email API")
+public class EmailController {
+
+	private final EmailService emailService;
+
+	@Autowired
+	public EmailController(EmailService emailService) {
+		this.emailService = emailService;
+	}
+
+	@Operation(
+			summary = "Send email to given email address with given subject and body",
+			description = "If email address is valid mail will be send to given address with given subject and body.")
+	@PostMapping(value = "/sendemail", consumes = "application/json", produces = "application/json")
+	@ResponseStatus(HttpStatus.OK)
+	public EmailTemplate sendEmail(@RequestBody EmailTemplate emailTemplate) {
+
+		var emailAddress = emailTemplate.getSendTo();
+		if (!EmailUtils.isValidEmail(emailAddress))
+			throw new ResponseStatusException(
+					HttpStatus.BAD_REQUEST, "Failed to send email. Error: " + emailAddress + " is not valid email address.");
+
+		try {
+			emailService.sendTextEmail(emailTemplate);
+			return emailTemplate;
+		} catch (MailAuthenticationException e) {
+			throw new ResponseStatusException(
+					HttpStatus.BAD_REQUEST, "Authentication failed. Error: " + e);
+		} catch (MailSendException e) {
+			throw new ResponseStatusException(
+					HttpStatus.BAD_REQUEST, "Mail sending error:" + e);
+		} catch (MailException e) {
+			throw new ResponseStatusException(
+					HttpStatus.BAD_REQUEST, "Failed to send email. Error: " + e);
+		}
+
+
+	}
+
+}
diff --git a/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailService.java b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailService.java
new file mode 100644
index 0000000000000000000000000000000000000000..89c99444e76a9fdddb0bfba03f7bb2a8573d49fd
--- /dev/null
+++ b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailService.java
@@ -0,0 +1,28 @@
+package cz.muni.fi.pa165.microservice3.email;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+
+@Service
+public class EmailService {
+
+	private final JavaMailSender javaMailSender;
+
+	@Autowired
+	public EmailService(JavaMailSender javaMailSender) {
+		this.javaMailSender = javaMailSender;
+	}
+
+
+	public void sendTextEmail(EmailTemplate emailTemplate) {
+
+		SimpleMailMessage msg = new SimpleMailMessage();
+		msg.setTo(emailTemplate.getSendTo());
+		msg.setSubject(emailTemplate.getSubject());
+		msg.setText(emailTemplate.getBody());
+		//TODO Setting username and password in application.yaml is needed
+		//javaMailSender.send(msg);
+	}
+}
diff --git a/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailTemplate.java b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailTemplate.java
new file mode 100644
index 0000000000000000000000000000000000000000..f648eb0b9de00e3025a17fad204988542e80fa06
--- /dev/null
+++ b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailTemplate.java
@@ -0,0 +1,18 @@
+package cz.muni.fi.pa165.microservice3.email;
+
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.Max;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class EmailTemplate {
+	@Email
+	private String sendTo;
+
+	@Max(value = 100)
+	private String subject;
+
+	private String body;
+}
diff --git a/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailUtils.java b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e333ba5d0aa801dee3894a4dedbce03df42c24a
--- /dev/null
+++ b/emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailUtils.java
@@ -0,0 +1,14 @@
+package cz.muni.fi.pa165.microservice3.email;
+
+import java.util.regex.Pattern;
+
+public class EmailUtils {
+
+	private static final Pattern EMAIL_PATTERN = Pattern.compile(
+			"^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$"
+	);
+
+	public static boolean isValidEmail(String email) {
+		return EMAIL_PATTERN.matcher(email).matches();
+	}
+}
diff --git a/emailmicroservice/src/main/resources/application.yaml b/emailmicroservice/src/main/resources/application.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..870a877b9e60e274aedf8fb10dd7824f53120f37
--- /dev/null
+++ b/emailmicroservice/src/main/resources/application.yaml
@@ -0,0 +1,15 @@
+spring:
+  mail:
+    password: #TODO
+    username: #TODO
+    host: smtp.gmail.com
+    port: 587
+    protocol: smtp
+    properties:
+      mail:
+        smtp:
+          auth: true
+          starttls:
+            enable: true
+          ssl:
+            trust: smtp.gmail.com
\ No newline at end of file
diff --git a/emailmicroservice/src/test/java/cz/muni/fi/pa165/microservice3/AppTest.java b/emailmicroservice/src/test/java/cz/muni/fi/pa165/microservice3/AppTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..53dd3bcc1a0d1c65978a26756013effdba9199ea
--- /dev/null
+++ b/emailmicroservice/src/test/java/cz/muni/fi/pa165/microservice3/AppTest.java
@@ -0,0 +1,10 @@
+package cz.muni.fi.pa165.microservice3;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class AppTest {
+  @Test
+  void contextLoads() {}
+}
diff --git a/emailmicroservice/src/test/java/cz/muni/fi/pa165/microservice3/email/EmailControllerTest.java b/emailmicroservice/src/test/java/cz/muni/fi/pa165/microservice3/email/EmailControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..91b06ae6734b1cba27e072911a924ae0c43920b5
--- /dev/null
+++ b/emailmicroservice/src/test/java/cz/muni/fi/pa165/microservice3/email/EmailControllerTest.java
@@ -0,0 +1,50 @@
+package cz.muni.fi.pa165.microservice3.email;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class EmailControllerTest {
+
+	@Autowired
+	private MockMvc mockMvc;
+
+	// injected mapper for converting classes into JSON strings
+	@Autowired private ObjectMapper objectMapper;
+
+	@Test
+	void badRequestWithInvalidAddress() throws Exception {
+		EmailTemplate emailTemplate = new EmailTemplate();
+		emailTemplate.setSendTo("email");
+		emailTemplate.setSubject("Test");
+		emailTemplate.setBody("Hello");
+		mockMvc
+				.perform(post("/api/email/sendemail")
+						.contentType(MediaType.APPLICATION_JSON)
+						.content(objectMapper.writeValueAsString(emailTemplate)))
+				.andExpect(status().isBadRequest());
+	}
+
+	@Test
+	void sendEmailToValidAddress() throws Exception {
+		EmailTemplate emailTemplate = new EmailTemplate();
+		emailTemplate.setSendTo("email@gmail.com");
+		emailTemplate.setSubject("Test");
+		emailTemplate.setBody("Hello");
+		mockMvc
+				.perform(post("/api/email/sendemail")
+						.contentType(MediaType.APPLICATION_JSON)
+						.content(objectMapper.writeValueAsString(emailTemplate)))
+				.andExpect(status().isOk());
+	}
+
+}
\ No newline at end of file
diff --git a/images/ClassDiagram.jpg b/images/ClassDiagram.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ed14516d33771f1025488f4b1a96cf4c10409e17
Binary files /dev/null and b/images/ClassDiagram.jpg differ
diff --git a/images/UseCase.jpg b/images/UseCase.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..22c9886aea7969388669be862e1fb9d180b81be3
Binary files /dev/null and b/images/UseCase.jpg differ
diff --git a/microservice4/mvnw b/microservice4/mvnw
new file mode 100644
index 0000000000000000000000000000000000000000..8a8fb2282df5b8f7263470a5a2dc0e196f35f35f
--- /dev/null
+++ b/microservice4/mvnw
@@ -0,0 +1,316 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /usr/local/etc/mavenrc ] ; then
+    . /usr/local/etc/mavenrc
+  fi
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="`\\unset -f command; \\command -v java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  $MAVEN_DEBUG_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" \
+  "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microservice4/mvnw.cmd b/microservice4/mvnw.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..1d8ab018eaf11d9b3a4a90e7818ace373dfbb380
--- /dev/null
+++ b/microservice4/mvnw.cmd
@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+  %JVM_CONFIG_MAVEN_PROPS% ^
+  %MAVEN_OPTS% ^
+  %MAVEN_DEBUG_OPTS% ^
+  -classpath %WRAPPER_JAR% ^
+  "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/microservice4/pom.xml b/microservice4/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c19a999ae57634152b5a6a4e3c554245e3e38114
--- /dev/null
+++ b/microservice4/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>smart-energy-management-system</artifactId>
+        <groupId>cz.muni.fi.pa165</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
+    </dependencies>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>microservice4</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.springdoc</groupId>
+                <artifactId>springdoc-openapi-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>integration-test</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <apiDocsUrl>http://localhost:8088/openapi.yaml</apiDocsUrl>
+                    <outputFileName>openapi.yaml</outputFileName>
+                    <outputDir>..</outputDir>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/App.java b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..06f278a0070bd88449210bdf5738307e2da2e1b5
--- /dev/null
+++ b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/App.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.microservice4;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App {
+  public static void main(String[] args) {
+    SpringApplication.run(App.class, args);
+  }
+}
diff --git a/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPrice.java b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPrice.java
new file mode 100644
index 0000000000000000000000000000000000000000..dcea788ef4a15284cfe229a2065411e2bda67c95
--- /dev/null
+++ b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPrice.java
@@ -0,0 +1,13 @@
+package cz.muni.fi.pa165.microservice4.electricityprices;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class ElectricityPrice {
+  private String id;
+  private String companyId;
+  private double priceHighTariff;
+  private double priceLowTariff;
+}
diff --git a/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceController.java b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3aae6fbd2aba4b36298330d0557f107f3fb703a
--- /dev/null
+++ b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceController.java
@@ -0,0 +1,139 @@
+package cz.muni.fi.pa165.microservice4.electricityprices;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/api/v1/electricity", produces = MediaType.APPLICATION_JSON_VALUE)
+public class ElectricityPriceController {
+  private final ElectricityPriceServiceImpl electricityPriceService;
+
+  @Autowired
+  public ElectricityPriceController(ElectricityPriceServiceImpl electricityPriceService) {
+    this.electricityPriceService = electricityPriceService;
+  }
+
+  @ControllerAdvice
+  static class GlobalControllerExceptionHandler {
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    @ExceptionHandler(NoElectricityPriceForCompanyException.class)
+    public void handleBadRequest() {
+      // Nothing to do
+    }
+  }
+
+  @Operation(
+          summary = "Get all electricity prices for all companies",
+          description = "Returns a list of all exsisting electricity price objects from the database." +
+                  "In case there are none, it returns an empty list.",
+          tags = "{electricity price}")
+  @ApiResponses(
+          value = {
+                  @ApiResponse(
+                          responseCode = "200",
+                          description = "Found all electricity prices",
+                          content = {
+                                  @Content(
+                                          mediaType = "application/json",
+                                          schema = @Schema(implementation = ElectricityPrice.class))
+                          })
+          })
+  @GetMapping(path = "/electricityprices")
+  public List<ElectricityPrice> getAllElectricityPrice() {
+    return electricityPriceService.getAllElectricityPrice();
+  }
+
+  @Operation(
+          summary = "Get electricity price for the company",
+          description = "Searches an electricity price by provided company id in URL." +
+                  "Returns a CZK/kWh price of electricity price object from the database if found." +
+                  "Price returned dependents of the time of the day (peek or non-peek hours) and weekday/weekend" +
+                  "Otherwise if company is not found, an exception is thrown.",
+          tags = "{electricity price}")
+  @ApiResponses(
+          value = {
+                  @ApiResponse(
+                          responseCode = "200",
+                          description = "Found the electricity price",
+                          content = {
+                                  @Content(
+                                          mediaType = "application/json",
+                                          schema = @Schema(implementation = ElectricityPrice.class))
+                          }),
+                  @ApiResponse(
+                          responseCode = "400",
+                          description = "Invalid or non-exsisting company id supplied",
+                          content = @Content)
+          })
+  @GetMapping(value = "/electricityprices/{companyId}")
+  public double getElectricityPrice(@PathVariable("companyId") String companyId) {
+    return electricityPriceService.getElectricityPrice(companyId);
+  }
+
+  @Operation(
+          summary = "Set electricity price for the company",
+          description = "Changes an electricity price for the provided company id in URL." +
+                  "Returns an electricity price object from the database after commiting the change." +
+                  "In case company id not being found, new electricity price object is entered in the database." +
+                  "Returns an electricity price for the newly created object.",
+          tags = "{electricity price}")
+  @ApiResponses(
+          value = {
+                  @ApiResponse(
+                          responseCode = "200",
+                          description = "Updated electricity price of a company",
+                          content = {
+                                  @Content(mediaType = "application/json",
+                                          schema = @Schema(implementation = ElectricityPrice.class))
+                          })
+          })
+  @PostMapping(path = "/electricityprices")
+  public ElectricityPrice setElectricityPrice(@RequestBody ElectricityPriceSetRequest req) {
+    log.info("new price adding {}", req);
+    return electricityPriceService.setElectricityPrice(req);
+  }
+
+  @Operation(
+          summary = "Delete electricity price for the company",
+          description = "Searches an electricity price by provided company id in URL." +
+                  "Deletes an electricity price object from the database if found." +
+                  "Otherwise, throws an exception.",
+          tags = "{electricity price}")
+  @ApiResponses(
+          value = {
+                  @ApiResponse(
+                          responseCode = "200",
+                          description = "Deleted electricity price for a company",
+                          content = {
+                                  @Content(mediaType = "application/json",
+                                          schema = @Schema(implementation = ElectricityPrice.class)) }),
+                  @ApiResponse(
+                          responseCode = "400",
+                          description = "Invalid or non-exsisting company id supplied",
+                          content = @Content)
+          })
+  @DeleteMapping(path = "/electricityprices/{companyId}")
+  public String deleteElectricityPriceForCompany(@PathVariable("companyId") String companyId) {
+    return electricityPriceService.deleteElectricityPriceForCompany(companyId);
+  }
+
+}
diff --git a/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceService.java b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceService.java
new file mode 100644
index 0000000000000000000000000000000000000000..4de2cafc7ae5a61b7c0a7c5f52cc6a125b095cab
--- /dev/null
+++ b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceService.java
@@ -0,0 +1,14 @@
+package cz.muni.fi.pa165.microservice4.electricityprices;
+
+import java.util.List;
+
+public interface ElectricityPriceService {
+
+  public double getElectricityPrice(String companyId); // dependent on time - low or high tariff
+
+  public List<ElectricityPrice> getAllElectricityPrice();
+
+  ElectricityPrice setElectricityPrice(ElectricityPriceSetRequest req);
+
+    String deleteElectricityPriceForCompany(String companyId);
+}
diff --git a/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceServiceImpl.java b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a3b81dc95081afca04eba6d392128f8c58d9d47
--- /dev/null
+++ b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceServiceImpl.java
@@ -0,0 +1,89 @@
+package cz.muni.fi.pa165.microservice4.electricityprices;
+
+import jakarta.annotation.PostConstruct;
+import org.springframework.stereotype.Service;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArrayList;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+@Service
+public class ElectricityPriceServiceImpl implements ElectricityPriceService {
+
+  // to be stored in database in the future
+  private final List<ElectricityPrice> list = new CopyOnWriteArrayList<>();
+
+  @PostConstruct
+  public void init() {
+    list.add(
+        ElectricityPrice.builder()
+            .id("1")
+            .companyId("1")
+            .priceHighTariff(300.0)
+            .priceLowTariff(200.0)
+            .build());
+  }
+
+  @Override
+  @Transactional(readOnly = true)
+  public double getElectricityPrice(String companyId) {
+    return list.stream()
+            .filter(price -> Objects.equals(companyId, price.getCompanyId()))
+            .findFirst()
+            .map(this::getPriceAcordingToDate)
+            .orElseThrow(() -> new NoElectricityPriceForCompanyException("No electricity price information for that company."));
+}
+
+  private double getPriceAcordingToDate(ElectricityPrice price) {
+    LocalTime localTime = LocalTime.now();
+    //weekend prices
+    if(LocalDate.now().getDayOfWeek() == DayOfWeek.SATURDAY || LocalDate.now().getDayOfWeek() == DayOfWeek.SUNDAY)
+      return price.getPriceLowTariff();
+    //peak hours
+    if(localTime.getHour() > 7 && localTime.getHour() < 21)
+      return price.getPriceHighTariff();
+    //off-peak hours
+    return price.getPriceLowTariff();
+  }
+
+  @Override
+  @Transactional(readOnly = true)
+  public List<ElectricityPrice> getAllElectricityPrice() {
+    return list;
+  }
+
+  public ElectricityPrice setElectricityPrice(ElectricityPriceSetRequest req) {
+    for (ElectricityPrice price:
+         list) {
+      if(Objects.equals(price.getCompanyId(), req.getCompanyId())) {
+        price.setPriceLowTariff(req.getPriceLowTariff());
+        price.setPriceHighTariff(req.getPriceHighTariff());
+        return price;
+      }
+    }
+    ElectricityPrice newPrice = new ElectricityPrice(UUID.randomUUID().toString(), req.getCompanyId(), req.getPriceHighTariff(), req.getPriceLowTariff());
+    list.add(newPrice);
+    return newPrice;
+  }
+
+  @Override
+  @ExceptionHandler
+  public String deleteElectricityPriceForCompany(String companyId) {
+    for (ElectricityPrice price:
+            list) {
+      if(Objects.equals(price.getCompanyId(), companyId)) {
+        list.remove(price);
+        return "deleted electricity prices for company with companyId " + companyId;
+      }
+    }
+    throw new NoElectricityPriceForCompanyException("Did not delete the electricity prices - company not found.");
+  }
+
+
+}
diff --git a/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceSetRequest.java b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceSetRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..639c5658fe749be67f37b7822292f0574dd17897
--- /dev/null
+++ b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/ElectricityPriceSetRequest.java
@@ -0,0 +1,16 @@
+package cz.muni.fi.pa165.microservice4.electricityprices;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+@Builder
+@Data
+public class ElectricityPriceSetRequest {
+  private String companyId;
+  private double priceHighTariff;
+  private double priceLowTariff;
+}
diff --git a/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/NoElectricityPriceForCompanyException.java b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/NoElectricityPriceForCompanyException.java
new file mode 100644
index 0000000000000000000000000000000000000000..4029707b0d56e73e07a339a11335465286f7c5bf
--- /dev/null
+++ b/microservice4/src/main/java/cz/muni/fi/pa165/microservice4/electricityprices/NoElectricityPriceForCompanyException.java
@@ -0,0 +1,22 @@
+package cz.muni.fi.pa165.microservice4.electricityprices;
+
+public class NoElectricityPriceForCompanyException extends RuntimeException {
+    public NoElectricityPriceForCompanyException() {
+    }
+
+    public NoElectricityPriceForCompanyException(String message) {
+        super(message);
+    }
+
+    public NoElectricityPriceForCompanyException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public NoElectricityPriceForCompanyException(Throwable cause) {
+        super(cause);
+    }
+
+    public NoElectricityPriceForCompanyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}
diff --git a/microservice4/src/main/resources/application.yml b/microservice4/src/main/resources/application.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4700664e520115224567267e5461cec5ac59642e
--- /dev/null
+++ b/microservice4/src/main/resources/application.yml
@@ -0,0 +1,6 @@
+server:
+  port: 8088
+
+spring:
+  application:
+    name: microservice4
\ No newline at end of file
diff --git a/microservice4/src/main/resources/banner.txt b/microservice4/src/main/resources/banner.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3d086e79839df03a1703fbc997701789e4bafe64
--- /dev/null
+++ b/microservice4/src/main/resources/banner.txt
@@ -0,0 +1,6 @@
+       ,--.              ,--.         ,--.      ,--.  ,--.           ,------.        ,--.              ,---.                         ,--.
+ ,---. |  |,---.  ,---.,-'  '-.,--.--.`--' ,---.`--',-'  '-.,--. ,--.|  .--. ',--.--.`--' ,---. ,---. '   .-' ,---. ,--.--.,--.  ,--.`--' ,---. ,---.
+| .-. :|  | .-. :| .--''-.  .-'|  .--',--.| .--',--.'-.  .-' \  '  / |  '--' ||  .--',--.| .--'| .-. :`.  `-.| .-. :|  .--' \  `'  / ,--.| .--'| .-. :
+\   --.|  \   --.\ `--.  |  |  |  |   |  |\ `--.|  |  |  |    \   '  |  | --' |  |   |  |\ `--.\   --..-'    \   --.|  |     \    /  |  |\ `--.\   --.
+ `----'`--'`----' `---'  `--'  `--'   `--' `---'`--'  `--'  .-'  /   `--'     `--'   `--' `---' `----'`-----' `----'`--'      `--'   `--' `---' `----'
+                                                            `---'
diff --git a/microservice4/src/microservice4docs.yaml b/microservice4/src/microservice4docs.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..39106dfaaf12f176eff37b2772211240cb3a0be0
--- /dev/null
+++ b/microservice4/src/microservice4docs.yaml
@@ -0,0 +1,125 @@
+openapi: 3.0.1
+info:
+  title: OpenAPI definition
+  version: v0
+servers:
+  - url: http://localhost:8088
+    description: Generated server url
+paths:
+  /api/v1/electricity/electricityprices:
+    get:
+      tags:
+        - "{electricity price}"
+      summary: Get all electricity prices for all companies
+      description: "Returns a list of all exsisting electricity price objects from\
+        \ the database.In case there are none, it returns an empty list."
+      operationId: getAllElectricityPrice
+      responses:
+        "400":
+          description: Bad Request
+        "200":
+          description: Found all electricity prices
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ElectricityPrice'
+    post:
+      tags:
+        - "{electricity price}"
+      summary: Set electricity price for the company
+      description: "Changes an electricity price for the provided company id in URL.Returns\
+        \ an electricity price object from the database after commiting the change.In\
+        \ case company id not being found, new electricity price object is entered\
+        \ in the database.Returns an electricity price for the newly created object."
+      operationId: setElectricityPrice
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/ElectricityPriceSetRequest'
+        required: true
+      responses:
+        "400":
+          description: Bad Request
+        "200":
+          description: Updated electricity price of a company
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ElectricityPrice'
+  /api/v1/electricity/electricityprices/{companyId}:
+    get:
+      tags:
+        - "{electricity price}"
+      summary: Get electricity price for the company
+      description: "Searches an electricity price by provided company id in URL.Returns\
+        \ a CZK/kWh price of electricity price object from the database if found.Price\
+        \ returned dependents of the time of the day (peek or non-peek hours) and\
+        \ weekday/weekendOtherwise if company is not found, an exception is thrown."
+      operationId: getElectricityPrice
+      parameters:
+        - name: companyId
+          in: path
+          required: true
+          schema:
+            type: string
+      responses:
+        "400":
+          description: Invalid or non-exsisting company id supplied
+          content: {}
+        "200":
+          description: Found the electricity price
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ElectricityPrice'
+    delete:
+      tags:
+        - "{electricity price}"
+      summary: Delete electricity price for the company
+      description: "Searches an electricity price by provided company id in URL.Deletes\
+        \ an electricity price object from the database if found.Otherwise, throws\
+        \ an exception."
+      operationId: deleteElectricityPriceForCompany
+      parameters:
+        - name: companyId
+          in: path
+          required: true
+          schema:
+            type: string
+      responses:
+        "400":
+          description: Invalid or non-exsisting company id supplied
+          content: {}
+        "200":
+          description: Deleted electricity price for a company
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ElectricityPrice'
+components:
+  schemas:
+    ElectricityPriceSetRequest:
+      type: object
+      properties:
+        companyId:
+          type: string
+        priceHighTariff:
+          type: number
+          format: double
+        priceLowTariff:
+          type: number
+          format: double
+    ElectricityPrice:
+      type: object
+      properties:
+        id:
+          type: string
+        companyId:
+          type: string
+        priceHighTariff:
+          type: number
+          format: double
+        priceLowTariff:
+          type: number
+          format: double
\ No newline at end of file
diff --git a/microservice4/src/test/java/cz/muni/fi/pa165/microservice4/AppTest.java b/microservice4/src/test/java/cz/muni/fi/pa165/microservice4/AppTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6bdf0f159a69df166a2f0477780c0874d46c172e
--- /dev/null
+++ b/microservice4/src/test/java/cz/muni/fi/pa165/microservice4/AppTest.java
@@ -0,0 +1,18 @@
+package cz.muni.fi.pa165.microservice4;
+
+import cz.muni.fi.pa165.microservice4.electricityprices.ElectricityPriceController;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest(classes = App.class)
+public class AppTest {
+    @Autowired
+    ElectricityPriceController electricityPriceController;
+  @Test
+  void contextLoads() {
+    assertThat(electricityPriceController).isNotNull();
+  }
+}
diff --git a/microservice4/src/test/java/cz/muni/fi/pa165/microservice4/ElectricityPriceControllerTest.java b/microservice4/src/test/java/cz/muni/fi/pa165/microservice4/ElectricityPriceControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a4bd9c30d870d232530dea5f43672c0d326e616
--- /dev/null
+++ b/microservice4/src/test/java/cz/muni/fi/pa165/microservice4/ElectricityPriceControllerTest.java
@@ -0,0 +1,93 @@
+package cz.muni.fi.pa165.microservice4;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+@SpringBootTest
+@AutoConfigureMockMvc
+class ElectricityPriceControllerTest {
+
+    @Autowired
+    private MockMvc mockMvc;
+    //dummy data from the list in service class (before using database)
+    private static final String data = "{\"id\":\"1\",\"companyId\":\"1\",\"priceHighTariff\":300.0,\"priceLowTariff\":200.0}";
+
+    @Test
+    public void shouldReturnEntranceData() throws Exception {
+        this.mockMvc.perform(get("/api/v1/electricity/electricityprices"))
+                .andDo(print())
+                .andExpect(status().isOk())
+                .andExpect(content().string(containsString(data)));
+    }
+    @Test
+    void testGetAllElectricityPrice() throws Exception {
+        mockMvc.perform(get("/api/v1/electricity/electricityprices")
+                .contentType(MediaType.APPLICATION_JSON_VALUE)
+                .accept(MediaType.APPLICATION_JSON_VALUE))
+                .andExpect(status().isOk());
+    }
+
+    @Test
+    public void shouldRegisterElectricityPrice() throws Exception {
+        this.mockMvc.perform( MockMvcRequestBuilders
+                        .post("/api/v1/electricity/electricityprices")
+                        .content("{\"companyId\":\"2\",\"priceHighTariff\":700.0,\"priceLowTariff\":400.0}")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .accept(MediaType.APPLICATION_JSON))
+                .andExpect(MockMvcResultMatchers.jsonPath("$.id").exists());
+    }
+
+    @Test
+    public void shouldNotThrowElectricityPriceForCompanyException() throws Exception {
+        this.mockMvc.perform(delete("/api/v1/electricity/electricityprices/2"))
+                .andDo(print())
+                .andExpect(status().is(200))
+                .andExpect(content().string(containsString("deleted electricity prices for company with companyId " + 2)));
+    }
+    @Test
+    public void shouldReturnPriceAccordingToTime() throws Exception {
+        if(LocalDate.now().getDayOfWeek() == DayOfWeek.SATURDAY || LocalDate.now().getDayOfWeek() == DayOfWeek.SUNDAY)
+            this.mockMvc.perform(get("/api/v1/electricity/electricityprices/1"))
+                    .andDo(print())
+                    .andExpect(status().isOk())
+                    .andExpect(content().string(containsString("200.0")));
+        else if(LocalTime.now().getHour() > 7 && LocalTime.now().getHour() < 21)
+            this.mockMvc.perform(get("/api/v1/electricity/electricityprices/1"))
+                    .andDo(print())
+                    .andExpect(status().isOk())
+                    .andExpect(content().string(containsString("300.0")));
+        else
+            this.mockMvc.perform(get("/api/v1/electricity/electricityprices/1"))
+                    .andDo(print())
+                    .andExpect(status().isOk())
+                    .andExpect(content().string(containsString("200.0")));
+    }
+
+    @Test
+    public void shouldThrowElectricityPriceForCompanyException() throws Exception {
+        this.mockMvc.perform(delete("/api/v1/electricity/electricityprices/66"))
+                .andExpect(status().is(400));
+
+    }
+
+    @Test
+    public void shouldThrowExceptionForNoElectricityCompany() throws Exception {
+        this.mockMvc.perform(get("/api/v1/electricity/electricityprices/notanid"))
+                .andExpect(status().is(400));
+    }
+}
diff --git a/model/pom.xml b/model/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f6debeff0017e9cf8b25c571c30739a08b3e5605
--- /dev/null
+++ b/model/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>smart-energy-management-system</artifactId>
+        <groupId>cz.muni.fi.pa165</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>models</artifactId>
+    <name>models</name>
+    <description>Library for smart energy management system with domain model objects</description>
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <spring-boot.repackage.skip>true</spring-boot.repackage.skip>
+    </properties>
+</project>
\ No newline at end of file
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/common/DomainObjectDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/common/DomainObjectDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a33a632ce22e7ce675133a2c4c23db1dabfb4a3
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/common/DomainObjectDto.java
@@ -0,0 +1,10 @@
+package cz.muni.fi.pa165.model.dto.common;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public abstract class DomainObjectDto {
+  private String id;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/common/Result.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/common/Result.java
new file mode 100644
index 0000000000000000000000000000000000000000..9eb9582e9247bb9e193bc5f383b4438c79282f5f
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/common/Result.java
@@ -0,0 +1,16 @@
+package cz.muni.fi.pa165.model.dto.common;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class Result<T extends DomainObjectDto> {
+
+  private long total;
+  private int page;
+  private int pageSize;
+  private List<T> items;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..c84bae95a68838d3fcbe5d0ec9b7d25273071da9
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyCreateDto.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.model.dto.company;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CompanyCreateDto extends DomainObjectDto {
+	private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebda78761e5bc11a40b278511bb55532fbc1d475
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyDto.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.model.dto.company;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CompanyDto extends DomainObjectDto {
+	private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..3659a6ef592454c6b64acdcea1f4432b9cdf82be
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/company/CompanyUpdateDto.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.model.dto.company;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CompanyUpdateDto extends DomainObjectDto {
+	private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8ceeaebd3d54fe50c20f2dd3cd34cc937abf1fc
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceCreateDto.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.model.dto.device;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class DeviceCreateDto extends DomainObjectDto {
+
+  private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..9218a718cc9964014dc36d1e0fc62243cdf946cc
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceDto.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.model.dto.device;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class DeviceDto extends DomainObjectDto {
+
+  private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..976642fba38646762eba51d8c89bd85a386eea3c
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/device/DeviceUpdateDto.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.model.dto.device;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class DeviceUpdateDto extends DomainObjectDto {
+
+  private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b3bc11b99f20fd26d6d610505886cc765d8c02d
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseCreateDto.java
@@ -0,0 +1,15 @@
+package cz.muni.fi.pa165.model.dto.house;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class HouseCreateDto extends DomainObjectDto {
+
+  private String address;
+  private String city;
+  private String state;
+  private String zipcode;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..3697c1eaa2cf46a790443a6e84ea32dc807b2237
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseDto.java
@@ -0,0 +1,14 @@
+package cz.muni.fi.pa165.model.dto.house;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class HouseDto extends DomainObjectDto {
+  private String address;
+  private String city;
+  private String state;
+  private String zipcode;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..e732309b7a7e068a4eafb2c3a9d144087e1eacfa
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/house/HouseUpdateDto.java
@@ -0,0 +1,14 @@
+package cz.muni.fi.pa165.model.dto.house;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class HouseUpdateDto extends DomainObjectDto {
+	private String name;
+	private String city;
+	private String state;
+	private String zipcode;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce6bfc339808ff0a948df3b00e541c6f73e32187
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerCreateDto.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.model.dto.manufacturer;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ManufacturerCreateDto extends DomainObjectDto {
+	private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..cadb73c17dff29ff3c80eab6e748fe242f4bbb91
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerDto.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.model.dto.manufacturer;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+
+@Getter
+@Setter
+public class ManufacturerDto extends DomainObjectDto {
+    private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..5951e5051226815644832ee7d6e91586b9df8212
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/manufacturer/ManufacturerUpdateDto.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.model.dto.manufacturer;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+
+@Getter
+@Setter
+public class ManufacturerUpdateDto extends DomainObjectDto {
+	private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c7fe3d71579c44dafaf4875329e82148f2cbf7c
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsCreateDto.java
@@ -0,0 +1,7 @@
+package cz.muni.fi.pa165.model.dto.metrics;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+
+public class MetricsCreateDto extends DomainObjectDto {
+    private double consumptionKWH;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..20c1ddca95de6060325cfb549b646dfb57c32e08
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsDto.java
@@ -0,0 +1,7 @@
+package cz.muni.fi.pa165.model.dto.metrics;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+
+public class MetricsDto extends DomainObjectDto {
+    private double consumptionKWH;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..99556ef0be0ca3b9acd7301e44f7d9f335e349bd
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/metrics/MetricsUpdateDto.java
@@ -0,0 +1,7 @@
+package cz.muni.fi.pa165.model.dto.metrics;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+
+public class MetricsUpdateDto extends DomainObjectDto {
+    private double consumptionKWH;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/role/EmployeeRoleDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/EmployeeRoleDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..e76b691a1c31ecb4d221796561d51e94074fa9f3
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/EmployeeRoleDto.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.model.dto.role;
+
+public class EmployeeRoleDto extends RoleDto{
+    /*
+            private CompanyDto company; / companyId
+
+     */
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/role/OwnerRoleDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/OwnerRoleDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a57a918c03d18f198fa19ae72d407e2906dfdc3
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/OwnerRoleDto.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.model.dto.role;
+
+import cz.muni.fi.pa165.model.dto.house.HouseDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class OwnerRoleDto extends RoleDto{
+    private HouseDto houseDto;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..60decb28c6051556d05d0c90bb8038594e838e19
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleCreateDto.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.model.dto.role;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+
+public class RoleCreateDto extends DomainObjectDto {
+    RoleTypeEnum roleType;
+    String userId;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..423636a005204ac8e17808252729bdb76f2cbf7a
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleDto.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.model.dto.role;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+
+public class RoleDto extends DomainObjectDto {
+    RoleTypeEnum roleType;
+    String userId;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleTypeEnum.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleTypeEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..678d1c29b77cf5a877bd31ed4e1600b7aa57da10
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleTypeEnum.java
@@ -0,0 +1,7 @@
+package cz.muni.fi.pa165.model.dto.role;
+
+public enum RoleTypeEnum {
+    Admin,
+    Employee,
+    User
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1a434ebe181cd2a25d1344e2b5e3a67ac1a04d3
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/role/RoleUpdateDto.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.model.dto.role;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+
+public class RoleUpdateDto extends DomainObjectDto {
+    RoleTypeEnum roleType;
+    String userId;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d3007de99e61fad394513a435d225bc6759b630
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterCreateDto.java
@@ -0,0 +1,13 @@
+package cz.muni.fi.pa165.model.dto.smartDevice;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceDto;
+import lombok.Getter;
+import lombok.Setter;
+
+
+@Getter
+@Setter
+public class SmartMeterCreateDto extends DomainObjectDto {
+  private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..09d1050c944ca9dfd8f7e6e09aeeaa6acdde7f8d
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterDto.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.model.dto.smartDevice;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class SmartMeterDto extends DomainObjectDto {
+  private String name;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..93148468e1010d70ce6bfd4f9ae3a4abdffc9432
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/smartDevice/SmartMeterUpdateDto.java
@@ -0,0 +1,9 @@
+package cz.muni.fi.pa165.model.dto.smartDevice;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import cz.muni.fi.pa165.model.dto.device.DeviceDto;
+
+public class SmartMeterUpdateDto  extends DomainObjectDto {
+	private String name;
+}
+
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..94b70d5efde15f9ef5001f0cebef03b9858781a1
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserCreateDto.java
@@ -0,0 +1,20 @@
+package cz.muni.fi.pa165.model.dto.user;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class UserCreateDto extends DomainObjectDto {
+
+  private String username;
+
+  private String password;
+
+  private String email;
+
+  private String firstName;
+
+  private String lastName;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6e5ac7bc94c81d05a7d7424e305f0e09e2a7b46
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserDto.java
@@ -0,0 +1,18 @@
+package cz.muni.fi.pa165.model.dto.user;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class UserDto extends DomainObjectDto {
+
+  private String username;
+
+  private String email;
+
+  private String firstName;
+
+  private String lastName;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserStatisticsCreateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserStatisticsCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..098d93430030af610250b3d621d98cb2fa806569
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserStatisticsCreateDto.java
@@ -0,0 +1,16 @@
+package cz.muni.fi.pa165.model.dto.user;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+@Getter
+@Setter
+public class UserStatisticsCreateDto {
+
+    private String id;
+    private String houseId;
+    private LocalDateTime startTime;
+    private LocalDateTime endTime;
+}
diff --git a/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserUpdateDto.java b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserUpdateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..41e68c07b8761de37280b1c24ab2c3a27586fa60
--- /dev/null
+++ b/model/src/main/java/cz/muni/fi/pa165/model/dto/user/UserUpdateDto.java
@@ -0,0 +1,19 @@
+package cz.muni.fi.pa165.model.dto.user;
+
+import cz.muni.fi.pa165.model.dto.common.DomainObjectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class UserUpdateDto extends DomainObjectDto {
+	private String username;
+
+	private String password;
+
+	private String email;
+
+	private String firstName;
+
+	private String lastName;
+}
diff --git a/pom.xml b/pom.xml
index b602c5dc3e0dd6184845740c53b3affdb8503b37..361e1d0059f1eac9f3c7d87b4140ce31da53e0b8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,19 +2,32 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
-	<parent>
+    <packaging>pom</packaging>
+    <modules>
+        <module>core</module>
+		<module>statistics</module>
+		<module>emailmicroservice</module>
+		<module>microservice4</module>
+		<module>model</module>
+	</modules>
+    <parent>
 		<groupId>org.springframework.boot</groupId>
 		<artifactId>spring-boot-starter-parent</artifactId>
 		<version>3.0.4</version>
 		<relativePath/> <!-- lookup parent from repository -->
 	</parent>
-	<groupId>fi.muni.pa165</groupId>
+	<groupId>cz.muni.fi.pa165</groupId>
 	<artifactId>smart-energy-management-system</artifactId>
 	<version>0.0.1-SNAPSHOT</version>
 	<name>smart-energy-management-system</name>
 	<description>Demo project for Spring Boot</description>
 	<properties>
 		<java.version>17</java.version>
+		<maven.compiler.source>17</maven.compiler.source>
+		<maven.compiler.target>17</maven.compiler.target>
+		<lombok.version>1.18.26</lombok.version>
+		<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
+		<example.version>0.0.1-SNAPSHOT</example.version>
 	</properties>
 	<dependencies>
 		<dependency>
@@ -27,15 +40,83 @@
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<version>${lombok.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.openapitools</groupId>
+			<artifactId>jackson-databind-nullable</artifactId>
+			<version>0.2.6</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springdoc</groupId>
+			<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+			<version>2.0.2</version>
+		</dependency>
+
 	</dependencies>
 
 	<build>
 		<plugins>
 			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.1</version>
+				<configuration>
+					<source>17</source> <!-- depending on your project -->
+					<target>17</target> <!-- depending on your project -->
+					<annotationProcessorPaths>
+						<!-- Order is IMPORTANT! Lombok needs to go first -->
+						<path>
+							<groupId>org.projectlombok</groupId>
+							<artifactId>lombok</artifactId>
+							<version>${lombok.version}</version>
+						</path>
+						<path>
+							<groupId>org.mapstruct</groupId>
+							<artifactId>mapstruct-processor</artifactId>
+							<version>${org.mapstruct.version}</version>
+						</path>
+						<!-- other annotation processors -->
+					</annotationProcessorPaths>
+					<compilerArgs>
+						<compilerArg>
+							-Amapstruct.defaultComponentModel=spring
+						</compilerArg>
+					</compilerArgs>
+				</configuration>
 			</plugin>
 		</plugins>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.springframework.boot</groupId>
+					<artifactId>spring-boot-maven-plugin</artifactId>
+					<configuration>
+						<excludes>
+							<exclude>
+								<groupId>org.projectlombok</groupId>
+								<artifactId>lombok</artifactId>
+							</exclude>
+						</excludes>
+					</configuration>
+				</plugin>
+				<plugin>
+					<groupId>org.openapitools</groupId>
+					<artifactId>openapi-generator-maven-plugin</artifactId>
+					<version>6.4.0</version>
+				</plugin>
+				<plugin>
+					<groupId>org.springdoc</groupId>
+					<artifactId>springdoc-openapi-maven-plugin</artifactId>
+					<version>1.4</version>
+				</plugin>
+			</plugins>
+		</pluginManagement>
 	</build>
-
 </project>
diff --git a/src/main/java/fi/muni/pa165/smartenergymanagementsystem/data/.gitkeep b/src/main/java/fi/muni/pa165/smartenergymanagementsystem/data/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/main/java/fi/muni/pa165/smartenergymanagementsystem/facade/.gitkeep b/src/main/java/fi/muni/pa165/smartenergymanagementsystem/facade/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/main/java/fi/muni/pa165/smartenergymanagementsystem/rest/.gitkeep b/src/main/java/fi/muni/pa165/smartenergymanagementsystem/rest/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/main/java/fi/muni/pa165/smartenergymanagementsystem/service/.gitkeep b/src/main/java/fi/muni/pa165/smartenergymanagementsystem/service/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
deleted file mode 100644
index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000
--- a/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/statistics/mvnw b/statistics/mvnw
new file mode 100644
index 0000000000000000000000000000000000000000..8a8fb2282df5b8f7263470a5a2dc0e196f35f35f
--- /dev/null
+++ b/statistics/mvnw
@@ -0,0 +1,316 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /usr/local/etc/mavenrc ] ; then
+    . /usr/local/etc/mavenrc
+  fi
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="`\\unset -f command; \\command -v java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  $MAVEN_DEBUG_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" \
+  "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/statistics/mvnw.cmd b/statistics/mvnw.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..1d8ab018eaf11d9b3a4a90e7818ace373dfbb380
--- /dev/null
+++ b/statistics/mvnw.cmd
@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+  %JVM_CONFIG_MAVEN_PROPS% ^
+  %MAVEN_OPTS% ^
+  %MAVEN_DEBUG_OPTS% ^
+  -classpath %WRAPPER_JAR% ^
+  "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/statistics/pom.xml b/statistics/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..22106e989ce3a8cda9dc63ec3e1cefead28ce569
--- /dev/null
+++ b/statistics/pom.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>smart-energy-management-system</artifactId>
+        <groupId>cz.muni.fi.pa165</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+            <version>1.5.3.Final</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>statistics</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.springdoc</groupId>
+                <artifactId>springdoc-openapi-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>integration-test</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <apiDocsUrl>http://localhost:8090/openapi.yaml</apiDocsUrl>
+                    <outputFileName>openapi.yaml</outputFileName>
+                    <outputDir>..</outputDir>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/statistics/src/main/java/cz/muni/fi/pa165/statistics/StatisticsApplication.java b/statistics/src/main/java/cz/muni/fi/pa165/statistics/StatisticsApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e7ca053e8aa1876e78da3e8e5db8c7626953296
--- /dev/null
+++ b/statistics/src/main/java/cz/muni/fi/pa165/statistics/StatisticsApplication.java
@@ -0,0 +1,12 @@
+package cz.muni.fi.pa165.statistics;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class StatisticsApplication {
+
+  public static void main(String[] args) {
+    SpringApplication.run(StatisticsApplication.class, args);
+  }
+}
diff --git a/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticCreateDto.java b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticCreateDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..484ed505f017f884deed133b368a42495f8405cb
--- /dev/null
+++ b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticCreateDto.java
@@ -0,0 +1,33 @@
+package cz.muni.fi.pa165.statistics.statistics;
+
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.Max;
+import jakarta.validation.constraints.Min;
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.Year;
+import java.util.Date;
+
+@Setter
+@Getter
+@Builder
+@Data
+public class StatisticCreateDto {
+    private String id;
+    private String userId;
+    @Email
+    private String userEmail;
+    private String houseId;
+    @Min(1)
+    @Max(12)
+    private int monthNum;
+    @Min(2000)
+    // TODO: replace with current year
+    @Max(2030)
+    private int yearNum;
+}
diff --git a/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticRepository.java b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..f8c79bbb8d07da26e5a23bf945b2c7aeb7cbf39d
--- /dev/null
+++ b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticRepository.java
@@ -0,0 +1,22 @@
+package cz.muni.fi.pa165.statistics.statistics;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface StatisticRepository extends JpaRepository<UserStatistic, String> {
+
+    @Query("select name, userId, monthNum, yearNum, monthlyConsumption  from UserStatistic where userId = :#{#userId}")
+    List<UserStatistic> findAllByUser(@Param("userId") String userId);
+
+    @Query("select id, name, userId, monthNum, yearNum, monthlyConsumption  from UserStatistic where userId = :#{#userId} and houseId = :#{#houseId}")
+    List<UserStatistic> findAllByUserAndHouse(@Param("userId") String userId, @Param("houseId") String houseId);
+
+    @Query("select id, name, userId, monthNum, yearNum, monthlyConsumption  from UserStatistic where userId = :#{#userId} and houseId = :#{#houseId} and monthNum = :#{#month} and yearNum = :#{#year}")
+    UserStatistic findUserHouseDateStatistics(@Param("userId") String userId, @Param("houseId") String houseId, @Param("month") int month, @Param("year") int year);
+}
diff --git a/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticService.java b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticService.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca349d7c01d79deade0bdf0cb23d3316a5ae1b50
--- /dev/null
+++ b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/StatisticService.java
@@ -0,0 +1,93 @@
+package cz.muni.fi.pa165.statistics.statistics;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.URL;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.http.entity.StringEntity;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class StatisticService {
+
+    private final StatisticRepository repository;
+
+    @Autowired
+    public StatisticService(StatisticRepository repository){
+        this.repository = repository;
+    }
+
+    @Transactional
+    public UserStatistic CreateStatistic(UserStatistic userStatistic) throws IOException {
+        UserStatistic statistic = repository.findUserHouseDateStatistics(userStatistic.getUserId(), userStatistic.getHouseId(), userStatistic.getMonthNum(), userStatistic.getYearNum());
+
+        if (statistic == null){
+            userStatistic.setId(UUID.randomUUID().toString());
+            userStatistic.setMonthlyConsumption(GenerateStatistic(userStatistic));
+            repository.save(userStatistic);
+            return userStatistic;
+        }
+
+        return statistic;
+    }
+
+    @Transactional
+    public List<UserStatistic> findAllUserStatistics(String userId)
+    {
+        return repository.findAllByUser(userId);
+    }
+
+    @Transactional
+    public List<UserStatistic> findAllUserStatisticsByHouse(String userId, String houseId)
+    {
+        return repository.findAllByUserAndHouse(userId, houseId);
+    }
+
+    private double GenerateStatistic(UserStatistic userStatistic) throws IOException {
+        // TODO: get first and last day of month
+        LocalDateTime startDateTime = LocalDateTime.of(2023,3,1,0,0,0,1);
+        LocalDateTime lastDateTime = LocalDateTime.of(2023,3,30,0,0,0,1);
+
+        String payload = String.format("""
+                {
+                    "id": "%s",
+                    "houseId": "%s",
+                    "startTime": "%s"
+                    "endTime": "%s"
+                }
+                """, userStatistic.getId(),
+                userStatistic.getHouseId(),
+                startDateTime,
+                lastDateTime);
+        StringEntity entity = new StringEntity(payload,
+                ContentType.APPLICATION_FORM_URLENCODED);
+
+        HttpClient httpClient = HttpClientBuilder.create().build();
+        HttpPost request = new HttpPost("http://localhost:8080/api/user/statistics");
+        request.setEntity(entity);
+        request.setHeader("Content-Type", "application/json");
+        request.setHeader("accept:", "*/*");
+
+        HttpResponse response = httpClient.execute(request);
+        System.out.println(response.getStatusLine().getStatusCode());
+        HttpEntity content = response.getEntity();
+        //System.out.println(content.);
+        return 0;
+    }
+}
diff --git a/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatistic.java b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatistic.java
new file mode 100644
index 0000000000000000000000000000000000000000..abdab02467ec5ee5377e14e07bf299529857e1a2
--- /dev/null
+++ b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatistic.java
@@ -0,0 +1,31 @@
+package cz.muni.fi.pa165.statistics.statistics;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import lombok.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.UUID;
+
+@Getter
+@Setter
+@Entity
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "domain_userStatistics")
+public class UserStatistic {
+    @Id
+    private String id = UUID.randomUUID().toString();
+    private String userId;
+    private String userEmail;
+    private String houseId;
+    private int monthNum;
+    private int yearNum;
+    private Double monthlyConsumption;
+    private String name = String.format("User%s_house%s_%d/%d.", userEmail, houseId, monthNum, yearNum);
+}
diff --git a/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatisticsController.java b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatisticsController.java
new file mode 100644
index 0000000000000000000000000000000000000000..f626f0e7258243125e0c17bf26a99f5f65f755dd
--- /dev/null
+++ b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatisticsController.java
@@ -0,0 +1,58 @@
+package cz.muni.fi.pa165.statistics.statistics;
+
+import io.swagger.v3.oas.annotations.Operation;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/user-statistics")
+public class UserStatisticsController {
+
+    private final StatisticService statisticService;
+    private final UserStatisticsMapper mapper;
+
+    @Autowired
+    public UserStatisticsController(StatisticService statisticService, UserStatisticsMapper mapper)
+    {
+        this.statisticService = statisticService;
+        this.mapper = mapper;
+    }
+
+    @Operation(
+            summary = "Create statistics",
+            description = "Creates a new statistics.")
+    @PostMapping
+    public ResponseEntity create(@RequestBody @Valid StatisticCreateDto createDto) throws IOException {
+        /*try
+        {*/
+            statisticService.CreateStatistic(mapper.fromDto(createDto));
+            return ResponseEntity.ok().build();
+        /*}
+        catch (Exception e)
+        {*/
+           // return ResponseEntity.internalServerError(e.getMessage()).build();
+        //}
+    }
+
+    @Operation(
+            summary = "Get user statistics",
+            description = "Get user statistics.")
+    @GetMapping("/all")
+    public List<UserStatistic> findAllByUser(@RequestParam @Valid String userId) {
+        return statisticService.findAllUserStatistics(userId);
+    }
+
+    @Operation(
+            summary = "Get user statistics for house",
+            description = "Get user statistics for house.")
+    @GetMapping("/user")
+    public List<UserStatistic> findHouseStatisticsByUser(@RequestParam @Valid String userId,
+                                                         @RequestParam @Valid String houseId) {
+        return statisticService.findAllUserStatistics(userId);
+    }
+}
diff --git a/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatisticsMapper.java b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatisticsMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..670a02b8223259ede9b97b1d6d1b54e7e03da4ec
--- /dev/null
+++ b/statistics/src/main/java/cz/muni/fi/pa165/statistics/statistics/UserStatisticsMapper.java
@@ -0,0 +1,8 @@
+package cz.muni.fi.pa165.statistics.statistics;
+
+import org.mapstruct.Mapper;
+
+@Mapper
+public interface UserStatisticsMapper{
+    UserStatistic fromDto(StatisticCreateDto entity);
+}
diff --git a/statistics/src/main/resources/application.yml b/statistics/src/main/resources/application.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b44726526c24f386d92ffbe0ea41739c778c5366
--- /dev/null
+++ b/statistics/src/main/resources/application.yml
@@ -0,0 +1,24 @@
+server:
+  port: 8090
+logging:
+  level:
+    root: warn
+    cz:
+      muni: debug
+    org:
+      springframework:
+        web: info
+spring:
+  mvc:
+    log-request-details: true
+  application:
+    name: statistic
+
+springdoc:
+  # https://springdoc.org/properties.html#_springdoc_openapi_core_properties
+  api-docs:
+    path: /openapi
+  # https://springdoc.org/properties.html#_swagger_ui_properties
+  swagger-ui:
+    path: /swagger-ui.html
+    tryItOutEnabled: true
\ No newline at end of file
diff --git a/statistics/src/main/resources/banner.txt b/statistics/src/main/resources/banner.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3d086e79839df03a1703fbc997701789e4bafe64
--- /dev/null
+++ b/statistics/src/main/resources/banner.txt
@@ -0,0 +1,6 @@
+       ,--.              ,--.         ,--.      ,--.  ,--.           ,------.        ,--.              ,---.                         ,--.
+ ,---. |  |,---.  ,---.,-'  '-.,--.--.`--' ,---.`--',-'  '-.,--. ,--.|  .--. ',--.--.`--' ,---. ,---. '   .-' ,---. ,--.--.,--.  ,--.`--' ,---. ,---.
+| .-. :|  | .-. :| .--''-.  .-'|  .--',--.| .--',--.'-.  .-' \  '  / |  '--' ||  .--',--.| .--'| .-. :`.  `-.| .-. :|  .--' \  `'  / ,--.| .--'| .-. :
+\   --.|  \   --.\ `--.  |  |  |  |   |  |\ `--.|  |  |  |    \   '  |  | --' |  |   |  |\ `--.\   --..-'    \   --.|  |     \    /  |  |\ `--.\   --.
+ `----'`--'`----' `---'  `--'  `--'   `--' `---'`--'  `--'  .-'  /   `--'     `--'   `--' `---' `----'`-----' `----'`--'      `--'   `--' `---' `----'
+                                                            `---'
diff --git a/statistics/src/test/java/cz/muni/fi/pa165/statistics/StatisticsApplicationTest.java b/statistics/src/test/java/cz/muni/fi/pa165/statistics/StatisticsApplicationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..487c42cf377d32e53ca3eb5f87a3689c5a1d917f
--- /dev/null
+++ b/statistics/src/test/java/cz/muni/fi/pa165/statistics/StatisticsApplicationTest.java
@@ -0,0 +1,11 @@
+package cz.muni.fi.pa165.statistics;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class StatisticsApplicationTest {
+
+  /*@Test
+  void contextLoads() {}
+*/}
diff --git a/statistics/src/test/java/cz/muni/fi/pa165/statistics/UnitTestUserStatisticsJPA.java b/statistics/src/test/java/cz/muni/fi/pa165/statistics/UnitTestUserStatisticsJPA.java
new file mode 100644
index 0000000000000000000000000000000000000000..461c0fd0ff991b6e9b1f092d70f01d70b32705d7
--- /dev/null
+++ b/statistics/src/test/java/cz/muni/fi/pa165/statistics/UnitTestUserStatisticsJPA.java
@@ -0,0 +1,102 @@
+package cz.muni.fi.pa165.statistics;
+
+import cz.muni.fi.pa165.statistics.statistics.StatisticRepository;
+import cz.muni.fi.pa165.statistics.statistics.UserStatistic;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.regex.Pattern;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+public class UnitTestUserStatisticsJPA {
+    @Autowired
+    private TestEntityManager entityManager;
+    @Autowired
+    private StatisticRepository statisticRepository;
+
+    @Test
+    public void createTesting() throws Exception {
+        String userStatistics = this.entityManager.persistAndGetId(new UserStatistic()).toString();
+        // Regular expression to match UUID format
+        Pattern uuidPattern = Pattern.compile(
+                "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+                Pattern.CASE_INSENSITIVE);
+        // Check if the string matches the UUID format
+        boolean isUUID = uuidPattern.matcher(userStatistics).matches();
+        assertThat(isUUID).isTrue();
+    }
+
+    @Test
+    public void shouldFindNoneIfRepositoryIsEmpty() {
+        Iterable<UserStatistic> userStatistics = statisticRepository.findAll();
+        assertThat(userStatistics).isEmpty();
+    }
+
+    @Test
+    public void shouldStore() {
+        assertThat(new UserStatistic()).hasFieldOrProperty("id");
+    }
+
+    @Test
+    public void shouldFindAll() {
+        UserStatistic m = new UserStatistic();
+        entityManager.persist(m);
+
+        UserStatistic m1 = new UserStatistic();
+        entityManager.persist(m1);
+
+        UserStatistic m2 = new UserStatistic();
+        entityManager.persist(m2);
+
+        assertThat(statisticRepository.findAll()).hasSize(3).contains(m, m1, m2);
+    }
+
+    @Test
+    public void shouldUpdateById() {
+        UserStatistic m = new UserStatistic();
+        entityManager.persist(m);
+
+        UserStatistic m1 = new UserStatistic();
+        entityManager.persist(m1);
+
+        UserStatistic update = statisticRepository.findById(m.getId()).get();
+        update.setName("New name");
+        statisticRepository.save(update);
+
+        UserStatistic check = statisticRepository.findById(m.getId()).get();
+
+        assertThat(check.getId()).isEqualTo(m.getId());
+        assertThat(check.getName()).isEqualTo(m.getName());
+    }
+
+    @Test
+    public void shouldDeleteById() {
+        UserStatistic m = new UserStatistic();
+        entityManager.persist(m);
+
+        UserStatistic m1 = new UserStatistic();
+        entityManager.persist(m1);
+
+        statisticRepository.deleteById(m.getId());
+
+        assertThat(statisticRepository.findAll()).hasSize(1).contains(m1);
+        assertThat(statisticRepository.findAll()).hasSize(1).doesNotContain(m);
+    }
+
+    @Test
+    public void shouldDeleteAll() {
+        entityManager.persist(new UserStatistic());
+        entityManager.persist(new UserStatistic());
+
+        statisticRepository.deleteAll();
+
+        assertThat(statisticRepository.findAll()).isEmpty();
+    }
+}
diff --git a/statistics/statisticsopenapi.yaml b/statistics/statisticsopenapi.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f4712434a4a9f4f05212504f85365d36f92c243c
--- /dev/null
+++ b/statistics/statisticsopenapi.yaml
@@ -0,0 +1,216 @@
+openapi: "3.0.3"
+info:
+  title: "smart_energy_management_system API"
+  description: "smart_energy_management_system API"
+  version: "1.0.0"
+servers:
+  - url: "https://smart_energy_management_system"
+paths:
+  /api/user-statistics:
+    post:
+      summary: "POST api/user-statistics"
+      operationId: "create"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/StatisticCreateDto"
+        required: true
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+  /api/user-statistics/all:
+    get:
+      summary: "GET api/user-statistics/all"
+      operationId: "findAllByUser"
+      parameters:
+        - name: "userId"
+          in: "query"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/UserStatistic"
+  /api/user-statistics/user:
+    get:
+      summary: "GET api/user-statistics/user"
+      operationId: "findHouseStatisticsByUser"
+      parameters:
+        - name: "userId"
+          in: "query"
+          required: true
+          schema:
+            type: "string"
+        - name: "houseId"
+          in: "query"
+          required: true
+          schema:
+            type: "string"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                type: "array"
+                items:
+                  $ref: "#/components/schemas/UserStatistic"
+  /<unknown>:
+    get:
+      summary: "GET ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    put:
+      summary: "PUT ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    post:
+      summary: "POST ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    delete:
+      summary: "DELETE ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    options:
+      summary: "OPTIONS ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    head:
+      summary: "HEAD ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    patch:
+      summary: "PATCH ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+    trace:
+      summary: "TRACE ${..}"
+      operationId: "error"
+      responses:
+        "200":
+          description: "OK"
+          content:
+            '*/*':
+              schema:
+                $ref: "#/components/schemas/ResponseEntity"
+components:
+  schemas:
+    StatisticCreateDto:
+      type: "object"
+      properties:
+        id:
+          type: "string"
+        userId:
+          type: "string"
+        userEmail:
+          type: "string"
+        houseId:
+          type: "string"
+        monthNum:
+          type: "integer"
+          format: "int32"
+        yearNum:
+          type: "integer"
+          format: "int32"
+    HttpHeaders:
+      type: "object"
+      properties: { }
+    ResponseEntity:
+      type: "object"
+      properties:
+        headers:
+          $ref: "#/components/schemas/HttpHeaders"
+    UserStatistic:
+      type: "object"
+      properties:
+        id:
+          type: "string"
+        userId:
+          type: "string"
+        userEmail:
+          type: "string"
+        houseId:
+          type: "string"
+        monthNum:
+          type: "integer"
+          format: "int32"
+        yearNum:
+          type: "integer"
+          format: "int32"
+        monthlyConsumption:
+          type: "number"
+          format: "double"
+        name:
+          type: "string"
+    Object:
+      type: "object"
+      properties: { }
+    ModelMap:
+      type: "object"
+      properties: { }
+    HttpStatusCode:
+      type: "object"
+      properties: { }
+    ModelAndView:
+      type: "object"
+      properties:
+        view:
+          $ref: "#/components/schemas/Object"
+        model:
+          $ref: "#/components/schemas/ModelMap"
+        status:
+          $ref: "#/components/schemas/HttpStatusCode"
\ No newline at end of file