Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
W
WebBack
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
websystem
WebBack
Commits
d28f525a
Commit
d28f525a
authored
7 months ago
by
조대희
Browse files
Options
Downloads
Patches
Plain Diff
refactor: 스케줄 response 변경 및 서비스 로직 수정
parent
b82d73cd
Branches
Branches containing commit
No related tags found
1 merge request
!42
[#25] 배포코드 master브랜치로 이동
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
dtos/ScheduleResponseDTO.js
+19
-8
19 additions, 8 deletions
dtos/ScheduleResponseDTO.js
services/scheduleService.js
+151
-87
151 additions, 87 deletions
services/scheduleService.js
with
170 additions
and
95 deletions
dtos/ScheduleResponseDTO.js
+
19
−
8
View file @
d28f525a
// dtos/ScheduleResponseDTO.js
// dtos/ScheduleResponseDTO.js
class
ScheduleResponseDTO
{
class
ScheduleResponseDTO
{
constructor
(
schedule
)
{
static
groupSchedules
(
schedules
)
{
this
.
id
=
schedule
.
id
;
const
grouped
=
schedules
.
reduce
((
acc
,
schedule
)
=>
{
this
.
user_id
=
schedule
.
user_id
;
const
key
=
`
${
schedule
.
title
}
-
${
schedule
.
is_fixed
}
`
;
this
.
title
=
schedule
.
title
;
if
(
!
acc
[
key
])
{
this
.
time_idx
=
schedule
.
time_idx
;
// 새로운 time_idx 필드 추가
acc
[
key
]
=
{
this
.
is_fixed
=
schedule
.
is_fixed
;
id
:
schedule
.
id
,
this
.
createdAt
=
schedule
.
createdAt
;
user_id
:
schedule
.
user_id
,
this
.
updatedAt
=
schedule
.
updatedAt
;
title
:
schedule
.
title
,
is_fixed
:
schedule
.
is_fixed
,
time_indices
:
[],
createdAt
:
schedule
.
createdAt
,
updatedAt
:
schedule
.
updatedAt
};
}
acc
[
key
].
time_indices
.
push
(
schedule
.
time_idx
);
return
acc
;
},
{});
return
Object
.
values
(
grouped
);
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
services/scheduleService.js
+
151
−
87
View file @
d28f525a
...
@@ -9,158 +9,222 @@ class ScheduleService {
...
@@ -9,158 +9,222 @@ class ScheduleService {
* 스케줄 생성 (벌크)
* 스케줄 생성 (벌크)
* @param {object} [transaction] - Sequelize 트랜잭션 객체 -> 미팅방에서 쓰기위해 트랜잭션을 넘겨받는걸 추가
* @param {object} [transaction] - Sequelize 트랜잭션 객체 -> 미팅방에서 쓰기위해 트랜잭션을 넘겨받는걸 추가
*/
*/
async
createSchedules
({
userId
,
title
,
is_fixed
,
events
},
transaction
=
null
)
{
async
createSchedules
({
userId
,
title
,
is_fixed
,
time_indices
},
transaction
=
null
)
{
const
scheduleDTOs
=
[];
// 중복 검사
for
(
const
time_idx
of
time_indices
)
{
for
(
const
event
of
events
)
{
const
{
time_idx
}
=
event
;
// 중복 스케줄 검사
const
overlap
=
await
this
.
checkScheduleOverlap
(
userId
,
time_idx
,
transaction
);
const
overlap
=
await
this
.
checkScheduleOverlap
(
userId
,
time_idx
,
transaction
);
if
(
overlap
)
{
if
(
overlap
)
{
throw
new
Error
(
`Schedule overlaps with existing schedule at time_idx
${
time_idx
}
`
);
throw
new
Error
(
`Schedule overlaps at time_idx
${
time_idx
}
`
);
}
}
}
const
scheduleData
=
{
const
createdSchedules
=
await
Promise
.
all
(
time_indices
.
map
(
time_idx
=>
Schedule
.
create
({
user_id
:
userId
,
user_id
:
userId
,
title
,
title
,
time_idx
,
time_idx
,
is_fixed
},
{
transaction
})
)
);
return
{
id
:
createdSchedules
[
0
].
id
,
user_id
:
userId
,
title
,
is_fixed
,
is_fixed
,
time_indices
,
createdAt
:
createdSchedules
[
0
].
createdAt
,
updatedAt
:
createdSchedules
[
0
].
updatedAt
};
};
const
schedule
=
await
Schedule
.
create
(
scheduleData
,
{
transaction
});
scheduleDTOs
.
push
(
new
ScheduleResponseDTO
(
schedule
));
}
}
return
scheduleDTOs
;
async
getAllSchedules
(
userId
)
{
try
{
const
schedules
=
await
Schedule
.
findAll
({
where
:
{
user_id
:
userId
},
order
:
[[
'
time_idx
'
,
'
ASC
'
]]
});
return
ScheduleResponseDTO
.
groupSchedules
(
schedules
);
}
catch
(
error
)
{
throw
new
Error
(
`Failed to fetch schedules:
${
error
.
message
}
`
);
}
}
}
/**
* 스케줄 수정 (벌크)
* @param {Array} updates - 수정할 스케줄 배열
*/
async
updateSchedules
(
userId
,
updates
,
transaction
=
null
)
{
async
updateSchedules
(
userId
,
updates
,
transaction
=
null
)
{
const
updatedSchedules
=
[]
;
const
{
originalTitle
,
title
,
is_fixed
,
time_indices
}
=
updates
;
for
(
const
update
of
updates
)
{
// 기존 스케줄 조회
const
{
time_idx
,
title
,
is_fixed
}
=
update
;
const
existingSchedules
=
await
Schedule
.
findAll
({
where
:
{
const
schedule
=
await
Schedule
.
findOne
({
user_id
:
userId
,
where
:
{
user_id
:
userId
,
time_idx
},
title
:
originalTitle
transaction
,
},
transaction
});
});
if
(
!
schedule
)
{
if
(
existingSchedules
.
length
===
0
)
{
throw
new
Error
(
`
Schedule not found
at time_idx
${
time_idx
}
`
);
throw
new
Error
(
'
Schedule not found
'
);
}
}
const
updatedData
=
{};
const
existingTimeIndices
=
existingSchedules
.
map
(
s
=>
s
.
time_idx
);
// 기존 시간대
if
(
title
!==
undefined
)
updatedData
.
title
=
title
;
const
toDelete
=
existingTimeIndices
.
filter
(
idx
=>
!
time_indices
.
includes
(
idx
));
// 삭제할 시간대
if
(
is_fixed
!==
undefined
)
updatedData
.
is_fixed
=
is_fixed
;
const
toAdd
=
time_indices
.
filter
(
idx
=>
!
existingTimeIndices
.
includes
(
idx
));
// 추가할 시간대
const
t
=
transaction
||
await
sequelize
.
transaction
();
const
updatedSchedule
=
await
schedule
.
update
(
updatedData
,
{
transaction
});
try
{
updatedSchedules
.
push
(
new
ScheduleResponseDTO
(
updatedSchedule
));
// 삭제
if
(
toDelete
.
length
>
0
)
{
await
Schedule
.
destroy
({
where
:
{
user_id
:
userId
,
title
:
originalTitle
,
time_idx
:
{
[
Op
.
in
]:
toDelete
}
}
},
return
updatedSchedules
;
transaction
:
t
});
}
}
/**
// 제목, 고정/유동 업데이트
* 스케줄 삭제 (벌크)
await
Schedule
.
update
(
* @param {number} userId - 사용자 ID
{
* @param {Array<number>} time_idxs - 삭제할 스케줄의 time_idx 배열
title
,
* @param {object} [transaction] - Sequelize 트랜잭션 객체
is_fixed
*/
},
async
deleteSchedules
(
userId
,
time_idxs
,
transaction
=
null
)
{
{
const
deleted_time_idxs
=
[];
where
:
{
user_id
:
userId
,
title
:
originalTitle
},
transaction
:
t
}
);
for
(
const
time_idx
of
time_idxs
)
{
// 새로운 time_indices 추가
const
deletedCount
=
await
Schedule
.
destroy
({
if
(
toAdd
.
length
>
0
)
{
where
:
{
user_id
:
userId
,
time_idx
},
await
Promise
.
all
(
transaction
,
toAdd
.
map
(
time_idx
=>
});
Schedule
.
create
({
user_id
:
userId
,
title
,
time_idx
,
is_fixed
},
{
transaction
:
t
})
)
);
}
if
(
deletedCount
===
0
)
{
if
(
!
transaction
)
{
throw
new
Error
(
`Schedule not found at time_idx
${
time_idx
}
`
);
await
t
.
commit
(
);
}
}
deleted_time_idxs
.
push
(
time_idx
);
return
{
id
:
existingSchedules
[
0
].
id
,
user_id
:
userId
,
title
,
is_fixed
,
time_indices
,
createdAt
:
existingSchedules
[
0
].
createdAt
,
updatedAt
:
new
Date
()
};
}
catch
(
error
)
{
if
(
!
transaction
)
{
await
t
.
rollback
();
}
throw
error
;
}
}
}
return
{
deleted_time_idxs
};
async
deleteSchedules
(
userId
,
title
,
transaction
=
null
)
{
const
deletedSchedules
=
await
Schedule
.
destroy
({
where
:
{
user_id
:
userId
,
title
},
transaction
});
return
{
deletedCount
:
deletedSchedules
};
}
}
/**
/**
* 특정 time_idx로 스케줄 조회
* 특정 time_idx로 스케줄 조회
*/
*/
async
getScheduleByTimeIdx
(
userId
,
time_idx
)
{
async
getScheduleByTimeIdx
(
userId
,
time_idx
)
{
// 해당 time_idx의 스케줄 찾기
const
schedule
=
await
Schedule
.
findOne
({
const
schedule
=
await
Schedule
.
findOne
({
where
:
{
user_id
:
userId
,
time_idx
}
,
where
:
{
user_id
:
userId
,
time_idx
}
});
});
if
(
!
schedule
)
{
if
(
!
schedule
)
{
throw
new
Error
(
'
Schedule not found
'
);
throw
new
Error
(
'
Schedule not found
'
);
}
}
return
new
ScheduleResponseDTO
(
schedule
);
// 같은 제목의 모든 스케줄 찾기
const
relatedSchedules
=
await
Schedule
.
findAll
({
where
:
{
user_id
:
userId
,
title
:
schedule
.
title
,
is_fixed
:
schedule
.
is_fixed
},
order
:
[[
'
time_idx
'
,
'
ASC
'
]]
});
return
ScheduleResponseDTO
.
groupSchedules
(
relatedSchedules
)[
0
];
}
}
/**
* 모든 스케줄 조회
*/
async
getAllSchedules
(
userId
)
{
async
getAllSchedules
(
userId
)
{
try
{
try
{
const
schedules
=
await
Schedule
.
findAll
({
const
schedules
=
await
Schedule
.
findAll
({
where
:
{
user_id
:
userId
},
where
:
{
user_id
:
userId
},
order
:
[[
'
time_idx
'
,
'
ASC
'
]]
,
order
:
[[
'
time_idx
'
,
'
ASC
'
]]
});
});
return
s
chedule
s
.
map
((
schedule
)
=>
new
ScheduleResponseDTO
(
schedule
)
);
return
S
chedule
ResponseDTO
.
groupSchedules
(
schedule
s
);
}
catch
(
error
)
{
}
catch
(
error
)
{
throw
new
Error
(
`Failed to fetch schedules:
${
error
.
message
}
`
);
throw
new
Error
(
`Failed to fetch schedules:
${
error
.
message
}
`
);
}
}
}
}
/**
* 중복 스케줄 검사
*/
async
checkScheduleOverlap
(
userId
,
time_idx
,
transaction
=
null
)
{
async
checkScheduleOverlap
(
userId
,
time_idx
,
transaction
=
null
)
{
const
overlappingSchedule
=
await
Schedule
.
findOne
({
const
overlappingSchedule
=
await
Schedule
.
findOne
({
where
:
{
user_id
:
userId
,
time_idx
},
where
:
{
user_id
:
userId
,
time_idx
},
transaction
,
transaction
});
});
return
!!
overlappingSchedule
;
return
!!
overlappingSchedule
;
}
}
async
checkScheduleOverlapByTime
(
userId
,
time_idx_start
,
time_idx_end
,
transaction
=
null
)
{
async
checkScheduleOverlapByTime
(
userId
,
time_idx_start
,
time_idx_end
,
transaction
=
null
)
{
console
.
log
(
const
overlappingSchedules
=
await
Schedule
.
findAll
({
`checkScheduleOverlapByTime 호출: userId=
${
userId
}
, time_idx_start=
${
time_idx_start
}
, time_idx_end=
${
time_idx_end
}
`
);
const
overlappingSchedule
=
await
Schedule
.
findOne
({
where
:
{
where
:
{
user_id
:
userId
,
user_id
:
userId
,
time_idx
:
{
time_idx
:
{
[
Op
.
between
]:
[
time_idx_start
,
time_idx_end
]
[
Op
.
between
]:
[
time_idx_start
,
time_idx_end
]
}
}
},
},
transaction
,
transaction
});
});
console
.
log
(
`중복 스케줄:
${
JSON
.
stringify
(
overlappingSchedule
)}
`
);
const
result
=
!!
overlappingSchedule
;
const
groupedSchedules
=
ScheduleResponseDTO
.
groupSchedules
(
overlappingSchedules
);
const
result
=
groupedSchedules
.
length
>
0
;
console
.
log
(
`checkScheduleOverlapByTime 호출: userId=
${
userId
}
, time_idx_start=
${
time_idx_start
}
, time_idx_end=
${
time_idx_end
}
`
);
console
.
log
(
`중복 스케줄:
${
JSON
.
stringify
(
groupedSchedules
)}
`
);
console
.
log
(
`스케줄 충돌 결과:
${
result
}
`
);
console
.
log
(
`스케줄 충돌 결과:
${
result
}
`
);
return
result
;
return
result
;
}
}
/**
* 만료된 스케줄 삭제
*/
async
cleanExpiredSchedules
()
{
async
cleanExpiredSchedules
()
{
try
{
try
{
const
deletedCount
=
await
Schedule
.
destroy
({
const
deletedCount
=
await
Schedule
.
destroy
({
where
:
{
is_fixed
:
false
}
,
where
:
{
is_fixed
:
false
}
});
});
//console.log(`Deleted ${deletedCount} flexible schedules.`)
;
return
{
deletedCount
}
;
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'
Failed to clean expired schedules:
'
,
error
);
console
.
error
(
'
Failed to clean expired schedules:
'
,
error
);
throw
error
;
throw
error
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment