diff --git a/fems-api/src/controllers/admin/apiKey/apiKey.controller.js b/fems-api/src/controllers/admin/apiKey/apiKey.controller.js
index f1a8faa..a9d9d89 100644
--- a/fems-api/src/controllers/admin/apiKey/apiKey.controller.js
+++ b/fems-api/src/controllers/admin/apiKey/apiKey.controller.js
@@ -10,7 +10,7 @@ router.use(authMiddleware);
// 지점별 API 키 생성
router.post(
- "/branches/:branchId/api-keys",
+ "/:branchId/api-keys",
roleCheck(["super_admin", "company_admin"]),
async (req, res, next) => {
try {
@@ -36,15 +36,15 @@ router.post(
// 지점별 API 키 목록 조회
router.get(
- "/branches/:branchId/api-keys",
+ "/:branchId/api-keys",
roleCheck(["super_admin", "company_admin"]),
async (req, res, next) => {
try {
- const apiKeys = await apiKeyService.listApiKeys(
+ const apiKey = await apiKeyService.listApiKey(
req.user.companyId,
req.params.branchId
);
- res.json(apiKeys);
+ res.json(apiKey);
} catch (error) {
next(error);
}
@@ -53,7 +53,7 @@ router.get(
// API 키 삭제
router.delete(
- "/api-keys/:apiKeyId",
+ "/:apiKeyId",
roleCheck(["super_admin", "company_admin"]),
async (req, res, next) => {
try {
@@ -67,7 +67,7 @@ router.delete(
// API 키 활성화/비활성화
router.patch(
- "/api-keys/:apiKeyId/status",
+ "/:apiKeyId/status",
roleCheck(["super_admin", "company_admin"]),
async (req, res, next) => {
try {
@@ -89,7 +89,7 @@ router.patch(
// API 키 권한 업데이트
router.put(
- "/api-keys/:apiKeyId/permissions",
+ "/:apiKeyId/permissions",
roleCheck(["super_admin", "company_admin"]),
async (req, res, next) => {
try {
diff --git a/fems-api/src/controllers/admin/companies/companies.controller.js b/fems-api/src/controllers/admin/companies/companies.controller.js
index 5375904..28f8124 100644
--- a/fems-api/src/controllers/admin/companies/companies.controller.js
+++ b/fems-api/src/controllers/admin/companies/companies.controller.js
@@ -40,7 +40,27 @@ router.get(
if (!company) {
return res.status(404).json({ message: "회사를 찾을 수 없습니다" });
}
- res.json(company);
+
+ // API 응답 데이터 구조화
+ const response = {
+ ...company.toJSON(),
+ Branches: company.Branches?.map((branch) => ({
+ ...branch.toJSON(),
+ ApiKey: branch.ApiKey?.map((apiKey) => ({
+ id: apiKey.id,
+ keyName: apiKey.keyName,
+ apiKey: apiKey.apiKey,
+ permissions: apiKey.permissions,
+ description: apiKey.description,
+ isActive: apiKey.isActive,
+ lastUsedAt: apiKey.lastUsedAt,
+ createdAt: apiKey.createdAt,
+ updatedAt: apiKey.updatedAt,
+ })),
+ })),
+ };
+
+ res.json(response);
} catch (error) {
next(error);
}
diff --git a/fems-api/src/models/Company.js b/fems-api/src/models/Company.js
index e6b97e6..0918f6e 100644
--- a/fems-api/src/models/Company.js
+++ b/fems-api/src/models/Company.js
@@ -66,6 +66,7 @@ class Company extends Model {
this.hasMany(models.User, { foreignKey: "companyId" });
this.hasMany(models.Equipment, { foreignKey: "companyId" });
this.hasMany(models.MaintenanceLog, { foreignKey: "companyId" });
+ this.hasMany(models.ApiKey, { foreignKey: "companyId" });
}
}
diff --git a/fems-api/src/services/apiKey.service.js b/fems-api/src/services/apiKey.service.js
index e7caab7..f0b2d57 100644
--- a/fems-api/src/services/apiKey.service.js
+++ b/fems-api/src/services/apiKey.service.js
@@ -32,7 +32,7 @@ class ApiKeyService {
/**
* API 키 목록 조회
*/
- async listApiKeys(companyId, branchId = null) {
+ async listApiKey(companyId, branchId = null) {
const where = { companyId };
if (branchId) {
where.branchId = branchId;
diff --git a/fems-api/src/services/companies.service.js b/fems-api/src/services/companies.service.js
index ef2e5e0..f775062 100644
--- a/fems-api/src/services/companies.service.js
+++ b/fems-api/src/services/companies.service.js
@@ -1,5 +1,5 @@
// src/services/companies.service.js
-const { Company, Branch, User, sequelize } = require("../models");
+const { Company, Branch, User, ApiKey, sequelize } = require("../models");
const apiKeyService = require("./apiKey.service");
const alertService = require("./alert.service");
const axios = require("axios");
@@ -82,6 +82,12 @@ class CompanyService {
model: Branch,
where: { isActive: true },
required: false,
+ include: [
+ {
+ model: ApiKey,
+ required: false,
+ },
+ ],
},
{
model: User,
diff --git a/fems-app/src/app/(admin)/company/branches/components/ApiKeyDialog.tsx b/fems-app/src/app/(admin)/company/branches/components/ApiKeyDialog.tsx
index 59f2ab6..030b752 100644
--- a/fems-app/src/app/(admin)/company/branches/components/ApiKeyDialog.tsx
+++ b/fems-app/src/app/(admin)/company/branches/components/ApiKeyDialog.tsx
@@ -55,7 +55,7 @@ export function ApiKeyDialog({ branch, isOpen, onClose }: ApiKeyDialogProps) {
const createApiKeyMutation = useMutation({
mutationFn: async (data: ApiKeyFormData) => {
const response = await api.post(
- `/api/v1/admin/branches/${branch.id}/api-keys`,
+ `/api/v1/admin/api-keys/${branch.id}/api-keys`,
data
);
return response.data;
diff --git a/fems-app/src/app/(admin)/company/branches/components/ApiKeySection.tsx b/fems-app/src/app/(admin)/company/branches/components/ApiKeySection.tsx
index 20a1b77..8e57e61 100644
--- a/fems-app/src/app/(admin)/company/branches/components/ApiKeySection.tsx
+++ b/fems-app/src/app/(admin)/company/branches/components/ApiKeySection.tsx
@@ -1,4 +1,4 @@
-// src/(admin)/company/branches/components/ApiKeySection.tsx
+// src/(admin)/company/branches/components/ApiKeyection.tsx
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { useToast } from "@/hooks/use-toast";
@@ -26,7 +26,7 @@ export function ApiKeySection({
const queryClient = useQueryClient();
// API 키 상태 토글 mutation
- const toggleApiKeyStatusMutation = useMutation({
+ const toggleApiKeytatusMutation = useMutation({
mutationFn: async ({
apiKeyId,
isActive,
@@ -70,9 +70,9 @@ export function ApiKeySection({
- {branch.ApiKeys && branch.ApiKeys.length > 0 ? (
+ {branch.ApiKey && branch.ApiKey.length > 0 ? (
- {branch.ApiKeys.map((apiKey) => (
+ {branch.ApiKey.map((apiKey) => (
- toggleApiKeyStatusMutation.mutate({
+ toggleApiKeytatusMutation.mutate({
apiKeyId: apiKey.id,
isActive: !apiKey.isActive,
})
diff --git a/fems-app/src/app/(admin)/company/branches/hooks/useApiKeyMutations.ts b/fems-app/src/app/(admin)/company/branches/hooks/useApiKeyMutations.ts
index 1515d5e..915f7b8 100644
--- a/fems-app/src/app/(admin)/company/branches/hooks/useApiKeyMutations.ts
+++ b/fems-app/src/app/(admin)/company/branches/hooks/useApiKeyMutations.ts
@@ -25,7 +25,7 @@ export function useApiKeyMutations(branchId: string) {
const create = useMutation({
mutationFn: async (data: ApiKeyFormData) => {
const response = await api.post(
- `/api/v1/admin/branches/${branchId}/api-keys`,
+ `/api/v1/admin/api-keys/${branchId}/api-keys`,
data
);
return response.data;
diff --git a/fems-app/src/app/(admin)/company/branches/hooks/useBranchMutations.ts b/fems-app/src/app/(admin)/company/branches/hooks/useBranchMutations.ts
index 5f39eb6..b203e03 100644
--- a/fems-app/src/app/(admin)/company/branches/hooks/useBranchMutations.ts
+++ b/fems-app/src/app/(admin)/company/branches/hooks/useBranchMutations.ts
@@ -5,6 +5,7 @@ import { api } from "@/lib/api";
import { useToast } from "@/hooks/use-toast";
import type { Branch } from "@/types/company";
import { handleApiError } from "../utils/api-helpers";
+import type { AxiosError } from "axios";
export function useBranchMutations() {
const { user } = useAuthStore();
@@ -26,10 +27,13 @@ export function useBranchMutations() {
description: "지점이 생성되었습니다.",
});
},
- onError: (error: any) => {
+ onError: (error: unknown) => {
toast({
title: "오류",
- description: handleApiError(error, "지점 생성에 실패했습니다."),
+ description: handleApiError(
+ error as AxiosError,
+ "지점 생성에 실패했습니다."
+ ),
variant: "destructive",
});
},
@@ -47,10 +51,13 @@ export function useBranchMutations() {
description: "지점이 수정되었습니다.",
});
},
- onError: (error: any) => {
+ onError: (error: unknown) => {
toast({
title: "오류",
- description: handleApiError(error, "지점 수정에 실패했습니다."),
+ description: handleApiError(
+ error as AxiosError,
+ "지점 수정에 실패했습니다."
+ ),
variant: "destructive",
});
},
@@ -67,10 +74,13 @@ export function useBranchMutations() {
description: "지점이 삭제되었습니다.",
});
},
- onError: (error: any) => {
+ onError: (error: unknown) => {
toast({
title: "오류",
- description: handleApiError(error, "지점 삭제에 실패했습니다."),
+ description: handleApiError(
+ error as AxiosError,
+ "지점 삭제에 실패했습니다."
+ ),
variant: "destructive",
});
},
diff --git a/fems-app/src/app/(admin)/company/branches/page.tsx b/fems-app/src/app/(admin)/company/branches/page.tsx
index 7879968..b6de11e 100644
--- a/fems-app/src/app/(admin)/company/branches/page.tsx
+++ b/fems-app/src/app/(admin)/company/branches/page.tsx
@@ -28,8 +28,9 @@ export default function CompanyBranchesPage() {
queryKey: ["company", user?.companyId],
queryFn: async () => {
const { data } = await api.get(
- `/api/v1/admin/companies/${user?.companyId}?include=branches.apiKeys`
+ `/api/v1/admin/companies/${user?.companyId}?include=branches.apiKey`
);
+ console.log(data);
return data;
},
enabled: !!token && !!user?.companyId,
diff --git a/fems-app/src/app/(admin)/company/branches/utils/clipboard.ts b/fems-app/src/app/(admin)/company/branches/utils/clipboard.ts
index b3ba94c..9bb0cf9 100644
--- a/fems-app/src/app/(admin)/company/branches/utils/clipboard.ts
+++ b/fems-app/src/app/(admin)/company/branches/utils/clipboard.ts
@@ -14,7 +14,7 @@ export function useClipboard() {
title: "복사 완료",
description: message,
});
- } catch (error) {
+ } catch {
toast({
title: "오류",
description: "복사에 실패했습니다.",
diff --git a/fems-app/src/app/(admin)/company/branches/utils/validators.ts b/fems-app/src/app/(admin)/company/branches/utils/validators.ts
index 6febb66..ca0bb9a 100644
--- a/fems-app/src/app/(admin)/company/branches/utils/validators.ts
+++ b/fems-app/src/app/(admin)/company/branches/utils/validators.ts
@@ -1,41 +1,41 @@
// src/(admin)/company/branches/utils/validators.ts
export function validateBranchForm(data: {
- name?: string;
- address?: string;
- tel?: string;
- }) {
- const errors: { [key: string]: string } = {};
-
- if (!data.name?.trim()) {
- errors.name = "지점명을 입력해주세요.";
- }
-
- if (!data.address?.trim()) {
- errors.address = "주소를 입력해주세요.";
- }
-
- if (!data.tel?.trim()) {
- errors.tel = "연락처를 입력해주세요.";
- } else if (!/^[0-9-]{9,20}$/.test(data.tel)) {
- errors.tel = "올바른 연락처 형식이 아닙니다.";
- }
-
- return errors;
+ name?: string;
+ address?: string;
+ tel?: string;
+}) {
+ const errors: { [key: string]: string } = {};
+
+ if (!data.name?.trim()) {
+ errors.name = "지점명을 입력해주세요.";
}
-
- export function validateApiKeyForm(data: {
- keyName?: string;
- permissions?: { [key: string]: boolean };
- }) {
- const errors: { [key: string]: string } = {};
-
- if (!data.keyName?.trim()) {
- errors.keyName = "API 키 이름을 입력해주세요.";
- }
-
- if (!data.permissions || Object.values(data.permissions).every((v) => !v)) {
- errors.permissions = "최소 하나 이상의 권한을 선택해주세요.";
- }
-
- return errors;
- }
\ No newline at end of file
+
+ if (!data.address?.trim()) {
+ errors.address = "주소를 입력해주세요.";
+ }
+
+ if (!data.tel?.trim()) {
+ errors.tel = "연락처를 입력해주세요.";
+ } else if (!/^[0-9-]{9,20}$/.test(data.tel)) {
+ errors.tel = "올바른 연락처 형식이 아닙니다.";
+ }
+
+ return errors;
+}
+
+export function validateApiKeyForm(data: {
+ keyName?: string;
+ permissions?: { [key: string]: boolean };
+}) {
+ const errors: { [key: string]: string } = {};
+
+ if (!data.keyName?.trim()) {
+ errors.keyName = "API 키 이름을 입력해주세요.";
+ }
+
+ if (!data.permissions || Object.values(data.permissions).every((v) => !v)) {
+ errors.permissions = "최소 하나 이상의 권한을 선택해주세요.";
+ }
+
+ return errors;
+}
diff --git a/fems-app/src/lib/api.ts b/fems-app/src/lib/api.ts
index e61359b..d232af3 100644
--- a/fems-app/src/lib/api.ts
+++ b/fems-app/src/lib/api.ts
@@ -27,7 +27,7 @@ api.interceptors.request.use((config) => {
url: config.url,
method: config.method,
headers: config.headers,
- data: config.data instanceof FormData ? "FormData" : config.data,
+ data: config.data,
});
return config;
diff --git a/fems-app/src/types/company.ts b/fems-app/src/types/company.ts
index 1a16b1a..0324ac0 100644
--- a/fems-app/src/types/company.ts
+++ b/fems-app/src/types/company.ts
@@ -25,7 +25,7 @@ export interface Branch {
companyId: string;
createdAt: string;
updatedAt: string;
- ApiKeys?: ApiKey[];
+ ApiKey?: ApiKey[];
}
export interface User {
diff --git a/fems-mqtt/data/mosquitto.db b/fems-mqtt/data/mosquitto.db
index e28bad3..145174a 100644
Binary files a/fems-mqtt/data/mosquitto.db and b/fems-mqtt/data/mosquitto.db differ
diff --git a/fems-mqtt/data/passwd b/fems-mqtt/data/passwd
index 62e9482..c08f4ca 100644
--- a/fems-mqtt/data/passwd
+++ b/fems-mqtt/data/passwd
@@ -1,2 +1,2 @@
-fems:$7$101$igIGTBy6ri+x9pFB$n42BZ6/wfGtyGCsb2VCrx6zYpZeN+klA0tVeEiDVXW5u3hcaHtP3oMdE2GXjrHF99Mi1TLOkE3PhEAu4Z7ZcvQ==
-nodered_user:$7$101$j41FU4YP2jvNUkmv$VznirNHKb5xT5Ybzt5lMvYK2LAHK2ditXvvLD9NhQdxznlP0DtoDr1tCp0QQ8rgbN8T03TSH0pUfUCwj8Ukntw==
+fems:$7$101$q3QFZ5evPd43ePCI$Zx3ns8us3mWVa7mu1AcnjdQwNWW4ervIvYGxBOWvqLruISS0fw/1F6Pul1HxMXzlJuIVSpxAcyUTNBw5BXidOw==
+nodered_user:$7$101$EKpRnHrJAJ+ZZhZ7$KAYnbifvvlJgL6mEYbZs0bCoK/PJR9jb3bhRxF6KOkeIeCYddJ1UikV7tEu7PqbPQVJ215BCEg9DfRxFN7QhbA==
diff --git a/fems-mqtt/log/mosquitto.log b/fems-mqtt/log/mosquitto.log
index 8beaa63..ea909f9 100755
--- a/fems-mqtt/log/mosquitto.log
+++ b/fems-mqtt/log/mosquitto.log
@@ -19896,3 +19896,199 @@ To fix this, use `chmod 0700 /mosquitto/config/passwd`.
1732629045: New connection from ::1:44966 on port 1883.
1732629045: New client connected from ::1:44966 as auto-9427648E-3FDC-FDE5-9CA5-CEBCF3D1901C (p2, c1, k60, u'fems').
1732629045: Client auto-9427648E-3FDC-FDE5-9CA5-CEBCF3D1901C closed its connection.
+1732629075: New connection from ::1:45386 on port 1883.
+1732629075: New client connected from ::1:45386 as auto-FD78FF64-FC64-DED7-AEE9-2E58F0274F45 (p2, c1, k60, u'fems').
+1732629075: Client auto-FD78FF64-FC64-DED7-AEE9-2E58F0274F45 closed its connection.
+1732629105: New connection from ::1:34944 on port 1883.
+1732629105: New client connected from ::1:34944 as auto-A74F1B36-3F6D-37FB-C0D0-1E3E9B83F7E6 (p2, c1, k60, u'fems').
+1732629105: Client auto-A74F1B36-3F6D-37FB-C0D0-1E3E9B83F7E6 closed its connection.
+1732629112: mosquitto version 2.0.20 terminating
+1732629112: Saving in-memory database to /mosquitto/data//mosquitto.db.
+1732629322: mosquitto version 2.0.20 starting
+1732629322: Config loaded from /mosquitto/config/mosquitto.conf.
+1732629322: Opening ipv4 listen socket on port 1883.
+1732629322: Opening ipv6 listen socket on port 1883.
+1732629322: mosquitto version 2.0.20 running
+1732629327: New connection from 172.19.0.9:40020 on port 1883.
+1732629327: New client connected from 172.19.0.9:40020 as fems_realtime_39 (p2, c1, k60, u'fems').
+1732629352: New connection from ::1:60884 on port 1883.
+1732629352: New client connected from ::1:60884 as auto-3F2DE70B-1533-30BA-AA8C-6E9EE8C86668 (p2, c1, k60, u'fems').
+1732629352: Client auto-3F2DE70B-1533-30BA-AA8C-6E9EE8C86668 closed its connection.
+1732629382: New connection from ::1:55750 on port 1883.
+1732629382: New client connected from ::1:55750 as auto-E3A9DB40-9B3C-CB4F-184B-3C3AFC7DDD89 (p2, c1, k60, u'fems').
+1732629382: Client auto-E3A9DB40-9B3C-CB4F-184B-3C3AFC7DDD89 closed its connection.
+1732629413: New connection from ::1:33680 on port 1883.
+1732629413: New client connected from ::1:33680 as auto-6EFD7C0C-F802-CC60-127A-A289C940FDB5 (p2, c1, k60, u'fems').
+1732629413: Client auto-6EFD7C0C-F802-CC60-127A-A289C940FDB5 closed its connection.
+1732629443: New connection from ::1:50492 on port 1883.
+1732629443: New client connected from ::1:50492 as auto-D822C594-9F70-A219-133F-F2D9C68E23C6 (p2, c1, k60, u'fems').
+1732629443: Client auto-D822C594-9F70-A219-133F-F2D9C68E23C6 closed its connection.
+1732629473: New connection from ::1:39702 on port 1883.
+1732629473: New client connected from ::1:39702 as auto-C5FFEBEB-5432-D449-135C-2B5061E15E08 (p2, c1, k60, u'fems').
+1732629473: Client auto-C5FFEBEB-5432-D449-135C-2B5061E15E08 closed its connection.
+1732629503: New connection from ::1:52172 on port 1883.
+1732629503: New client connected from ::1:52172 as auto-A701CE3D-33A1-053D-4B26-D5C0C24087EC (p2, c1, k60, u'fems').
+1732629503: Client auto-A701CE3D-33A1-053D-4B26-D5C0C24087EC closed its connection.
+1732629533: New connection from ::1:58534 on port 1883.
+1732629533: New client connected from ::1:58534 as auto-AB71DAD5-FB91-D966-C048-16B85310503F (p2, c1, k60, u'fems').
+1732629533: Client auto-AB71DAD5-FB91-D966-C048-16B85310503F closed its connection.
+1732629563: New connection from ::1:35944 on port 1883.
+1732629563: New client connected from ::1:35944 as auto-CF5F8388-EBC3-FE29-F00B-E85B15AA4A33 (p2, c1, k60, u'fems').
+1732629563: Client auto-CF5F8388-EBC3-FE29-F00B-E85B15AA4A33 closed its connection.
+1732629593: New connection from ::1:51218 on port 1883.
+1732629593: New client connected from ::1:51218 as auto-EB22736F-B737-A07C-9A6D-1946D2DE846E (p2, c1, k60, u'fems').
+1732629593: Client auto-EB22736F-B737-A07C-9A6D-1946D2DE846E closed its connection.
+1732629623: New connection from ::1:56498 on port 1883.
+1732629623: New client connected from ::1:56498 as auto-C8E65BF4-E65E-1F3D-55F7-B29BF4ABA11A (p2, c1, k60, u'fems').
+1732629623: Client auto-C8E65BF4-E65E-1F3D-55F7-B29BF4ABA11A closed its connection.
+1732629653: New connection from ::1:37804 on port 1883.
+1732629653: New client connected from ::1:37804 as auto-F1493DBB-C292-4E5F-50A6-D2EAAD493C61 (p2, c1, k60, u'fems').
+1732629654: Client auto-F1493DBB-C292-4E5F-50A6-D2EAAD493C61 closed its connection.
+1732629684: New connection from ::1:42448 on port 1883.
+1732629684: New client connected from ::1:42448 as auto-98D0F406-DE1A-B777-2612-B62FC852061E (p2, c1, k60, u'fems').
+1732629684: Client auto-98D0F406-DE1A-B777-2612-B62FC852061E closed its connection.
+1732629714: New connection from ::1:36744 on port 1883.
+1732629714: New client connected from ::1:36744 as auto-7F1550C5-7A6B-F10C-D13B-C290273B3DFB (p2, c1, k60, u'fems').
+1732629714: Client auto-7F1550C5-7A6B-F10C-D13B-C290273B3DFB closed its connection.
+1732629744: New connection from ::1:56548 on port 1883.
+1732629744: New client connected from ::1:56548 as auto-07F075A4-017F-9A2B-817D-E753CE8325B8 (p2, c1, k60, u'fems').
+1732629744: Client auto-07F075A4-017F-9A2B-817D-E753CE8325B8 closed its connection.
+1732629774: New connection from ::1:56728 on port 1883.
+1732629774: New client connected from ::1:56728 as auto-427784B7-3CB8-9C1C-409F-EFB9C54C3F56 (p2, c1, k60, u'fems').
+1732629774: Client auto-427784B7-3CB8-9C1C-409F-EFB9C54C3F56 closed its connection.
+1732629804: New connection from ::1:48638 on port 1883.
+1732629804: New client connected from ::1:48638 as auto-CE7649D7-1BAB-B92A-4F94-F6C4C86D5C56 (p2, c1, k60, u'fems').
+1732629804: Client auto-CE7649D7-1BAB-B92A-4F94-F6C4C86D5C56 closed its connection.
+1732629834: New connection from ::1:60850 on port 1883.
+1732629834: New client connected from ::1:60850 as auto-CFFC9ECF-69AE-0F0F-7D16-5304D2978635 (p2, c1, k60, u'fems').
+1732629834: Client auto-CFFC9ECF-69AE-0F0F-7D16-5304D2978635 closed its connection.
+1732629864: New connection from ::1:49864 on port 1883.
+1732629864: New client connected from ::1:49864 as auto-83C0C19D-73C0-6655-CB17-587A8313314E (p2, c1, k60, u'fems').
+1732629864: Client auto-83C0C19D-73C0-6655-CB17-587A8313314E closed its connection.
+1732629894: New connection from ::1:57872 on port 1883.
+1732629894: New client connected from ::1:57872 as auto-A1A4BB7E-9B22-9003-C0EA-34C1036DC2D4 (p2, c1, k60, u'fems').
+1732629894: Client auto-A1A4BB7E-9B22-9003-C0EA-34C1036DC2D4 closed its connection.
+1732629924: New connection from ::1:38200 on port 1883.
+1732629924: New client connected from ::1:38200 as auto-EA101EBA-F2D2-0BF6-9FFF-EDA43E8AA3CC (p2, c1, k60, u'fems').
+1732629924: Client auto-EA101EBA-F2D2-0BF6-9FFF-EDA43E8AA3CC closed its connection.
+1732629954: New connection from ::1:53360 on port 1883.
+1732629954: New client connected from ::1:53360 as auto-F9BFE067-122B-F6DB-FBF7-C2C3992E3E60 (p2, c1, k60, u'fems').
+1732629954: Client auto-F9BFE067-122B-F6DB-FBF7-C2C3992E3E60 closed its connection.
+1732629984: New connection from ::1:55324 on port 1883.
+1732629984: New client connected from ::1:55324 as auto-BF24765A-AB22-F6C6-CFB6-0628328EBBCE (p2, c1, k60, u'fems').
+1732629984: Client auto-BF24765A-AB22-F6C6-CFB6-0628328EBBCE closed its connection.
+1732630015: New connection from ::1:56400 on port 1883.
+1732630015: New client connected from ::1:56400 as auto-9299CA5E-AEA3-EC88-1449-6E9EECB157B9 (p2, c1, k60, u'fems').
+1732630015: Client auto-9299CA5E-AEA3-EC88-1449-6E9EECB157B9 closed its connection.
+1732630045: New connection from ::1:59764 on port 1883.
+1732630045: New client connected from ::1:59764 as auto-11788700-024D-F7D4-0E4B-94B56796B52E (p2, c1, k60, u'fems').
+1732630045: Client auto-11788700-024D-F7D4-0E4B-94B56796B52E closed its connection.
+1732630075: New connection from ::1:52552 on port 1883.
+1732630075: New client connected from ::1:52552 as auto-7330B15D-7D61-495B-E89B-6D5846D0A11B (p2, c1, k60, u'fems').
+1732630075: Client auto-7330B15D-7D61-495B-E89B-6D5846D0A11B closed its connection.
+1732630105: New connection from ::1:58806 on port 1883.
+1732630105: New client connected from ::1:58806 as auto-DC0E6C19-4069-FC85-75F3-467FB7EC87F7 (p2, c1, k60, u'fems').
+1732630105: Client auto-DC0E6C19-4069-FC85-75F3-467FB7EC87F7 closed its connection.
+1732630135: New connection from ::1:42120 on port 1883.
+1732630135: New client connected from ::1:42120 as auto-8F731C90-1EF0-DC87-0C97-C0D717F6BA1C (p2, c1, k60, u'fems').
+1732630135: Client auto-8F731C90-1EF0-DC87-0C97-C0D717F6BA1C closed its connection.
+1732630165: New connection from ::1:51042 on port 1883.
+1732630165: New client connected from ::1:51042 as auto-894A940C-B290-093E-E459-4929730E77B8 (p2, c1, k60, u'fems').
+1732630165: Client auto-894A940C-B290-093E-E459-4929730E77B8 closed its connection.
+1732630195: New connection from ::1:47002 on port 1883.
+1732630195: New client connected from ::1:47002 as auto-CA7C0103-2526-EE8B-945A-C76102F26C45 (p2, c1, k60, u'fems').
+1732630195: Client auto-CA7C0103-2526-EE8B-945A-C76102F26C45 closed its connection.
+1732630225: New connection from ::1:38018 on port 1883.
+1732630225: New client connected from ::1:38018 as auto-BB69E25B-EAF3-3521-A55F-E12D13B6B892 (p2, c1, k60, u'fems').
+1732630225: Client auto-BB69E25B-EAF3-3521-A55F-E12D13B6B892 closed its connection.
+1732630255: New connection from ::1:37828 on port 1883.
+1732630255: New client connected from ::1:37828 as auto-CF725643-925B-4744-9509-E058C1D4F27F (p2, c1, k60, u'fems').
+1732630255: Client auto-CF725643-925B-4744-9509-E058C1D4F27F closed its connection.
+1732630285: New connection from ::1:47102 on port 1883.
+1732630285: New client connected from ::1:47102 as auto-418F7408-AAC9-89B9-2C52-4531E31CB507 (p2, c1, k60, u'fems').
+1732630285: Client auto-418F7408-AAC9-89B9-2C52-4531E31CB507 closed its connection.
+1732630316: New connection from ::1:37320 on port 1883.
+1732630316: New client connected from ::1:37320 as auto-16AC7439-97D4-6779-D051-AE3AD1A76729 (p2, c1, k60, u'fems').
+1732630316: Client auto-16AC7439-97D4-6779-D051-AE3AD1A76729 closed its connection.
+1732630346: New connection from ::1:49948 on port 1883.
+1732630346: New client connected from ::1:49948 as auto-8056EFBA-8078-BEAD-803D-E27B711588EF (p2, c1, k60, u'fems').
+1732630346: Client auto-8056EFBA-8078-BEAD-803D-E27B711588EF closed its connection.
+1732630376: New connection from ::1:46162 on port 1883.
+1732630376: New client connected from ::1:46162 as auto-A2E2F4F0-D697-2876-D0F1-83B2AA124B7B (p2, c1, k60, u'fems').
+1732630376: Client auto-A2E2F4F0-D697-2876-D0F1-83B2AA124B7B closed its connection.
+1732630406: New connection from ::1:37436 on port 1883.
+1732630406: New client connected from ::1:37436 as auto-FE2C9BC6-0AF5-055C-70B0-E7478F7DB95E (p2, c1, k60, u'fems').
+1732630406: Client auto-FE2C9BC6-0AF5-055C-70B0-E7478F7DB95E closed its connection.
+1732630436: New connection from ::1:44684 on port 1883.
+1732630436: New client connected from ::1:44684 as auto-C4BFA9F3-AA18-557D-92F5-807AA347F5BF (p2, c1, k60, u'fems').
+1732630436: Client auto-C4BFA9F3-AA18-557D-92F5-807AA347F5BF closed its connection.
+1732630466: New connection from ::1:40046 on port 1883.
+1732630466: New client connected from ::1:40046 as auto-8FC6D53D-5DA4-66D2-E268-BAE61A101C88 (p2, c1, k60, u'fems').
+1732630466: Client auto-8FC6D53D-5DA4-66D2-E268-BAE61A101C88 closed its connection.
+1732630496: New connection from ::1:60636 on port 1883.
+1732630496: New client connected from ::1:60636 as auto-6F228534-DDD5-6346-4F44-1DE1471DFE6B (p2, c1, k60, u'fems').
+1732630496: Client auto-6F228534-DDD5-6346-4F44-1DE1471DFE6B closed its connection.
+1732630526: New connection from ::1:57594 on port 1883.
+1732630526: New client connected from ::1:57594 as auto-82CC0D1A-4214-739B-579F-63809CB8EB00 (p2, c1, k60, u'fems').
+1732630526: Client auto-82CC0D1A-4214-739B-579F-63809CB8EB00 closed its connection.
+1732630556: New connection from ::1:36442 on port 1883.
+1732630556: New client connected from ::1:36442 as auto-C4A716AC-D5D8-3A25-F117-86C4EA5F6C58 (p2, c1, k60, u'fems').
+1732630556: Client auto-C4A716AC-D5D8-3A25-F117-86C4EA5F6C58 closed its connection.
+1732630586: New connection from ::1:58244 on port 1883.
+1732630586: New client connected from ::1:58244 as auto-17A1A40F-2A6B-1C1A-F6BC-AD8D2CB0127E (p2, c1, k60, u'fems').
+1732630586: Client auto-17A1A40F-2A6B-1C1A-F6BC-AD8D2CB0127E closed its connection.
+1732630616: New connection from ::1:57282 on port 1883.
+1732630616: New client connected from ::1:57282 as auto-3B7E536C-B2BE-F395-993C-8615E17A8C4C (p2, c1, k60, u'fems').
+1732630616: Client auto-3B7E536C-B2BE-F395-993C-8615E17A8C4C closed its connection.
+1732630647: New connection from ::1:59600 on port 1883.
+1732630647: New client connected from ::1:59600 as auto-CEC19FD0-4AF6-0D5B-5006-22535323439B (p2, c1, k60, u'fems').
+1732630647: Client auto-CEC19FD0-4AF6-0D5B-5006-22535323439B closed its connection.
+1732630677: New connection from ::1:36040 on port 1883.
+1732630677: New client connected from ::1:36040 as auto-5BB5712C-2871-EC23-B36B-37CD15CFAC91 (p2, c1, k60, u'fems').
+1732630677: Client auto-5BB5712C-2871-EC23-B36B-37CD15CFAC91 closed its connection.
+1732630707: New connection from ::1:60820 on port 1883.
+1732630707: New client connected from ::1:60820 as auto-2A2FBB5D-A4F8-223D-D3A5-FF05AF130E19 (p2, c1, k60, u'fems').
+1732630707: Client auto-2A2FBB5D-A4F8-223D-D3A5-FF05AF130E19 closed its connection.
+1732630737: New connection from ::1:34816 on port 1883.
+1732630737: New client connected from ::1:34816 as auto-14788CDF-8C98-8933-DFF6-A65DDF56842F (p2, c1, k60, u'fems').
+1732630737: Client auto-14788CDF-8C98-8933-DFF6-A65DDF56842F closed its connection.
+1732630767: New connection from ::1:44158 on port 1883.
+1732630767: New client connected from ::1:44158 as auto-7901C273-27E7-608C-B8E2-AC8037D03F67 (p2, c1, k60, u'fems').
+1732630767: Client auto-7901C273-27E7-608C-B8E2-AC8037D03F67 closed its connection.
+1732630797: New connection from ::1:49174 on port 1883.
+1732630797: New client connected from ::1:49174 as auto-7B6B4F6F-ECAD-59DA-AD8A-ABF059B50B92 (p2, c1, k60, u'fems').
+1732630797: Client auto-7B6B4F6F-ECAD-59DA-AD8A-ABF059B50B92 closed its connection.
+1732630827: New connection from ::1:38140 on port 1883.
+1732630827: New client connected from ::1:38140 as auto-F7CF1C75-E943-FC23-E901-E8F14E441B43 (p2, c1, k60, u'fems').
+1732630827: Client auto-F7CF1C75-E943-FC23-E901-E8F14E441B43 closed its connection.
+1732630857: New connection from ::1:43010 on port 1883.
+1732630857: New client connected from ::1:43010 as auto-DE1241C8-7B7A-3975-450A-B1296B5BFE0D (p2, c1, k60, u'fems').
+1732630857: Client auto-DE1241C8-7B7A-3975-450A-B1296B5BFE0D closed its connection.
+1732630887: New connection from ::1:58772 on port 1883.
+1732630887: New client connected from ::1:58772 as auto-10FF2A45-6AAD-F7E8-8BF2-31BC72C7CA5C (p2, c1, k60, u'fems').
+1732630887: Client auto-10FF2A45-6AAD-F7E8-8BF2-31BC72C7CA5C closed its connection.
+1732630918: New connection from ::1:48248 on port 1883.
+1732630918: New client connected from ::1:48248 as auto-4C601577-DF62-4FAA-9679-6A316DFEDE3A (p2, c1, k60, u'fems').
+1732630918: Client auto-4C601577-DF62-4FAA-9679-6A316DFEDE3A closed its connection.
+1732630948: New connection from ::1:58850 on port 1883.
+1732630948: New client connected from ::1:58850 as auto-434B9BA2-47B6-6E65-D1E4-F95426C83A38 (p2, c1, k60, u'fems').
+1732630948: Client auto-434B9BA2-47B6-6E65-D1E4-F95426C83A38 closed its connection.
+1732630978: New connection from ::1:54174 on port 1883.
+1732630978: New client connected from ::1:54174 as auto-24E2013D-3112-EB36-58BB-D65A0BA5F3B4 (p2, c1, k60, u'fems').
+1732630978: Client auto-24E2013D-3112-EB36-58BB-D65A0BA5F3B4 closed its connection.
+1732631008: New connection from ::1:45918 on port 1883.
+1732631008: New client connected from ::1:45918 as auto-EB9459A6-29DD-0AEF-07EF-D7FD657446DC (p2, c1, k60, u'fems').
+1732631008: Client auto-EB9459A6-29DD-0AEF-07EF-D7FD657446DC closed its connection.
+1732631038: New connection from ::1:43602 on port 1883.
+1732631038: New client connected from ::1:43602 as auto-ABFF2110-A649-2187-BFF9-0A75C1C4F65E (p2, c1, k60, u'fems').
+1732631038: Client auto-ABFF2110-A649-2187-BFF9-0A75C1C4F65E closed its connection.
+1732631068: New connection from ::1:60504 on port 1883.
+1732631068: New client connected from ::1:60504 as auto-293DE4B3-C9B5-9749-6A37-E35B0AFFA77E (p2, c1, k60, u'fems').
+1732631068: Client auto-293DE4B3-C9B5-9749-6A37-E35B0AFFA77E closed its connection.
+1732631098: New connection from ::1:33252 on port 1883.
+1732631098: New client connected from ::1:33252 as auto-9EE983C1-3E27-1A79-89C4-85D500DAFC5C (p2, c1, k60, u'fems').
+1732631098: Client auto-9EE983C1-3E27-1A79-89C4-85D500DAFC5C closed its connection.
+1732631123: Saving in-memory database to /mosquitto/data//mosquitto.db.
+1732631128: New connection from ::1:52958 on port 1883.
+1732631128: New client connected from ::1:52958 as auto-4D2D363C-D504-BF71-21B3-4E1E43F9C7D1 (p2, c1, k60, u'fems').
+1732631128: Client auto-4D2D363C-D504-BF71-21B3-4E1E43F9C7D1 closed its connection.
diff --git a/fems-realtime-api/logs/info/info-2024-11-26.log b/fems-realtime-api/logs/info/info-2024-11-26.log
index ef7d9e5..c0176b3 100644
--- a/fems-realtime-api/logs/info/info-2024-11-26.log
+++ b/fems-realtime-api/logs/info/info-2024-11-26.log
@@ -153,3 +153,11 @@
{"environment":"development","level":"warn","message":"Reconnecting to MQTT broker (attempt 1)","service":"fems-edge","timestamp":"2024-11-26 21:23:57"}
{"environment":"development","level":"info","message":"Connected to MQTT broker","service":"fems-edge","timestamp":"2024-11-26 21:23:57"}
{"environment":"development","level":"info","message":"Subscribed to data/+/+/+/#","service":"fems-edge","timestamp":"2024-11-26 21:23:57"}
+{"environment":"development","error":"connect ECONNREFUSED 172.19.0.2:5433","level":"warn","message":"Failed to connect to services, attempt 1/30","service":"fems-edge","services":"{\"timescaledb\":false,\"redis\":false}","timestamp":"2024-11-26 22:55:24"}
+{"environment":"development","level":"info","message":"Successfully connected to TimescaleDB","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"environment":"development","level":"info","message":"Successfully connected to Redis","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"environment":"development","level":"info","message":"All services are connected","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"broker":"mqtt://fems-mqtt:1883","clientId":"fems_realtime_39","environment":"development","level":"info","message":"Connecting to MQTT broker...","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"environment":"development","level":"info","message":"Connected to MQTT broker","service":"fems-edge","timestamp":"2024-11-26 22:55:27"}
+{"environment":"development","level":"info","message":"Realtime backend server running on port 3004","service":"fems-edge","timestamp":"2024-11-26 22:55:27"}
+{"environment":"development","level":"info","message":"Subscribed to data/+/+/+/#","service":"fems-edge","timestamp":"2024-11-26 22:55:27"}
diff --git a/fems-realtime-api/logs/system/system-2024-11-26.log b/fems-realtime-api/logs/system/system-2024-11-26.log
index ef7d9e5..c0176b3 100644
--- a/fems-realtime-api/logs/system/system-2024-11-26.log
+++ b/fems-realtime-api/logs/system/system-2024-11-26.log
@@ -153,3 +153,11 @@
{"environment":"development","level":"warn","message":"Reconnecting to MQTT broker (attempt 1)","service":"fems-edge","timestamp":"2024-11-26 21:23:57"}
{"environment":"development","level":"info","message":"Connected to MQTT broker","service":"fems-edge","timestamp":"2024-11-26 21:23:57"}
{"environment":"development","level":"info","message":"Subscribed to data/+/+/+/#","service":"fems-edge","timestamp":"2024-11-26 21:23:57"}
+{"environment":"development","error":"connect ECONNREFUSED 172.19.0.2:5433","level":"warn","message":"Failed to connect to services, attempt 1/30","service":"fems-edge","services":"{\"timescaledb\":false,\"redis\":false}","timestamp":"2024-11-26 22:55:24"}
+{"environment":"development","level":"info","message":"Successfully connected to TimescaleDB","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"environment":"development","level":"info","message":"Successfully connected to Redis","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"environment":"development","level":"info","message":"All services are connected","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"broker":"mqtt://fems-mqtt:1883","clientId":"fems_realtime_39","environment":"development","level":"info","message":"Connecting to MQTT broker...","service":"fems-edge","timestamp":"2024-11-26 22:55:26"}
+{"environment":"development","level":"info","message":"Connected to MQTT broker","service":"fems-edge","timestamp":"2024-11-26 22:55:27"}
+{"environment":"development","level":"info","message":"Realtime backend server running on port 3004","service":"fems-edge","timestamp":"2024-11-26 22:55:27"}
+{"environment":"development","level":"info","message":"Subscribed to data/+/+/+/#","service":"fems-edge","timestamp":"2024-11-26 22:55:27"}