@@ -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