Skip to content

Commit a3b6cea

Browse files
committed
fix: dynamic unique camera name
1 parent c799ef7 commit a3b6cea

File tree

1 file changed

+128
-50
lines changed

1 file changed

+128
-50
lines changed

server/src/services/cameras/cameras.service.ts

Lines changed: 128 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ export async function getCameraById(camera_id: number) {
4040
const { rows } = await pool.query(`
4141
SELECT * FROM v_cameras_overview
4242
WHERE camera_id = $1;
43-
`,[
44-
camera_id
45-
]
43+
`, [
44+
camera_id
45+
]
4646
);
4747

4848
return rows;
@@ -82,17 +82,46 @@ export async function summaryCameras() {
8282
* @author Wanasart
8383
* @lastModified 2025-10-25
8484
*/
85-
export async function insertCamera (
86-
camera_name: string,
87-
camera_type: string,
88-
camera_status: boolean,
89-
source_type: string,
90-
source_value: string,
91-
location_id: number,
92-
description: string,
85+
export async function insertCamera(
86+
camera_name: string,
87+
camera_type: string,
88+
camera_status: boolean,
89+
source_type: string,
90+
source_value: string,
91+
location_id: number,
92+
description: string,
9393
creator_id: number
94-
){
95-
const { rows } = await pool.query(`
94+
) {
95+
96+
// 1) normalize + validate ชื่อ
97+
const name = camera_name.trim();
98+
if (!name) {
99+
const err: any = new Error("CAMERA_NAME_REQUIRED");
100+
err.code = "CAMERA_NAME_REQUIRED";
101+
throw err;
102+
}
103+
104+
// 2) เช็กชื่อซ้ำ (เฉพาะกล้องที่ยังใช้งานอยู่)
105+
const dupCheck = await pool.query(
106+
`
107+
SELECT cam_id
108+
FROM cameras
109+
WHERE cam_is_use = TRUE
110+
AND LOWER(cam_name) = LOWER($1)
111+
LIMIT 1;
112+
`,
113+
[name]
114+
);
115+
116+
if (dupCheck.rows.length > 0) {
117+
const err: any = new Error("DUPLICATE_CAMERA_NAME");
118+
err.code = "DUPLICATE_CAMERA_NAME";
119+
throw err;
120+
}
121+
122+
// 3) insert camera
123+
const { rows } = await pool.query(
124+
`
96125
INSERT INTO cameras(
97126
cam_name,
98127
cam_type,
@@ -105,30 +134,42 @@ export async function insertCamera (
105134
)
106135
VALUES($1, $2, $3, $4, $5, $6, $7, $8)
107136
RETURNING *
108-
`,[
109-
camera_name,
110-
camera_type,
111-
camera_status,
112-
source_type,
113-
source_value,
114-
location_id,
115-
description,
116-
creator_id
117-
]);
118-
119-
const log = await pool.query(`
120-
INSERT INTO camera_logs(
121-
clg_usr_id,
122-
clg_cam_id,
123-
clg_action,
124-
clg_created_at
125-
)
126-
VALUES($1, $2, $3, CURRENT_TIMESTAMP);
127-
`,[
128-
creator_id,
129-
rows[0].cam_id,
130-
'CREATE',
131-
]);
137+
`,
138+
[
139+
name,
140+
camera_type,
141+
camera_status,
142+
source_type,
143+
source_value,
144+
location_id,
145+
description,
146+
creator_id,
147+
]
148+
);
149+
150+
if (!rows[0]) {
151+
const err: any = new Error("CAMERA_INSERT_FAILED");
152+
err.code = "CAMERA_INSERT_FAILED";
153+
throw err;
154+
}
155+
156+
// 4) log
157+
await pool.query(
158+
`
159+
INSERT INTO camera_logs(
160+
clg_usr_id,
161+
clg_cam_id,
162+
clg_action,
163+
clg_created_at
164+
)
165+
VALUES($1, $2, $3, CURRENT_TIMESTAMP);
166+
`,
167+
[
168+
creator_id,
169+
rows[0].cam_id,
170+
"CREATE",
171+
]
172+
);
132173

133174
return Mapping.mapCameraToSaveResponse(rows[0]);
134175
}
@@ -152,7 +193,7 @@ export async function insertCamera (
152193
* @author Wanasart
153194
* @lastModified 2025-10-25
154195
*/
155-
export async function updateCamera (
196+
export async function updateCamera(
156197
camera_id: number,
157198
camera_name: string,
158199
camera_type: string,
@@ -164,6 +205,37 @@ export async function updateCamera (
164205
user_id: number
165206
) {
166207

208+
// 1) normalize ชื่อนิดหน่อย
209+
const name = camera_name.trim();
210+
211+
if (!name) {
212+
const err: any = new Error("CAMERA_NAME_REQUIRED");
213+
err.code = "CAMERA_NAME_REQUIRED";
214+
throw err;
215+
}
216+
217+
// 2) เช็กชื่อซ้ำเฉพาะกล้องที่ยังใช้งาน (cam_is_use = TRUE) และไม่ใช่ตัวเอง
218+
const dupCheck = await pool.query(
219+
`
220+
SELECT cam_id
221+
FROM cameras
222+
WHERE cam_is_use = TRUE
223+
AND LOWER(cam_name) = LOWER($1)
224+
AND cam_id <> $2
225+
LIMIT 1;
226+
`,
227+
[name, camera_id]
228+
);
229+
230+
const count = dupCheck.rowCount ?? 0;
231+
232+
if (count > 0) {
233+
const err: any = new Error("DUPLICATE_CAMERA_NAME");
234+
err.code = "DUPLICATE_CAMERA_NAME";
235+
throw err;
236+
}
237+
238+
// 3) อัปเดตกล้อง (จะอัปเดตตัวที่ soft delete แล้วก็ได้หรือไม่ก็แล้วแต่กติกา)
167239
const { rows } = await pool.query(
168240
`
169241
UPDATE cameras
@@ -180,7 +252,7 @@ export async function updateCamera (
180252
RETURNING *;
181253
`,
182254
[
183-
camera_name,
255+
name,
184256
camera_type,
185257
camera_status,
186258
source_type,
@@ -191,19 +263,25 @@ export async function updateCamera (
191263
]
192264
);
193265

194-
const log = await pool.query(`
266+
if (rows.length === 0) {
267+
const err: any = new Error("CAMERA_NOT_FOUND");
268+
err.code = "CAMERA_NOT_FOUND";
269+
throw err;
270+
}
271+
272+
await pool.query(`
195273
INSERT INTO camera_logs(
196274
clg_usr_id,
197275
clg_cam_id,
198276
clg_action,
199277
clg_created_at
200278
)
201279
VALUES($1, $2, $3, CURRENT_TIMESTAMP);
202-
`,[
203-
user_id,
204-
rows[0].cam_id,
205-
'UPDATE',
206-
]);
280+
`, [
281+
user_id,
282+
rows[0].cam_id,
283+
'UPDATE',
284+
]);
207285

208286
return Mapping.mapCameraToSaveResponse(rows[0]);
209287
}
@@ -245,11 +323,11 @@ export async function removeCamera(
245323
clg_created_at
246324
)
247325
VALUES($1, $2, $3, CURRENT_TIMESTAMP);
248-
`,[
249-
user_id,
250-
rows[0].cam_id,
251-
'DELETE',
252-
]);
326+
`, [
327+
user_id,
328+
rows[0].cam_id,
329+
'DELETE',
330+
]);
253331

254332
return Mapping.mapCameraToSaveResponse(rows[0]);
255333
}

0 commit comments

Comments
 (0)