feat(project): lock task mutation context

This commit is contained in:
sechmachine
2026-08-15 01:03:51 +07:00
parent 2f2573159c
commit 19a3518f74
4 changed files with 85 additions and 5 deletions
@@ -97,7 +97,12 @@ public class ProjectQueryService {
@Transactional(readOnly = true)
public ProjectTaskContext taskContext(long actorUserId, long projectId) {
var project = visibleProject(actorUserId, projectId);
var project = projects.findById(projectId).orElseThrow(ProjectAccessDeniedException::new);
return taskContext(actorUserId, project);
}
ProjectTaskContext taskContext(long actorUserId, ProjectEntity project) {
requireVisibleProject(actorUserId, project);
var activeMembers = project.memberships().stream()
.filter(membership -> membership.isCurrent() && isEligibleIntern(membership.internUserId()))
.map(membership -> new ProjectTaskMemberView(
@@ -142,15 +147,19 @@ public class ProjectQueryService {
}
private ProjectEntity visibleProject(long actorUserId, long projectId) {
var actor = activeActor(actorUserId);
var project = projects.findById(projectId).orElseThrow(ProjectAccessDeniedException::new);
requireVisibleProject(actorUserId, project);
return project;
}
private void requireVisibleProject(long actorUserId, ProjectEntity project) {
var actor = activeActor(actorUserId);
var visible = "ADMIN".equals(actor.role().name())
|| ("MENTOR".equals(actor.role().name()) && project.mentorUserId() == actorUserId)
|| ("INTERN".equals(actor.role().name()) && project.hasEverHadMember(actorUserId));
if (!visible) {
throw new ProjectAccessDeniedException();
}
return project;
}
private List<ProjectEntity> visibleProjects(AccountIdentity actor, long actorUserId) {
@@ -4,6 +4,7 @@ import com.lab.labtimesheet.feature.project.exception.ProjectAccessDeniedExcepti
import com.lab.labtimesheet.feature.account.service.AccountService;
import com.lab.labtimesheet.feature.project.model.ProjectInternEligibility;
import com.lab.labtimesheet.feature.project.model.dto.ProjectCreateCommand;
import com.lab.labtimesheet.feature.project.model.dto.ProjectTaskContext;
import com.lab.labtimesheet.feature.project.model.entity.ProjectEntity;
import com.lab.labtimesheet.feature.project.repository.ProjectRepository;
import java.time.Clock;
@@ -15,14 +16,17 @@ public class ProjectService {
private final ProjectRepository projects;
private final AccountService accounts;
private final ProjectQueryService queries;
private final Clock clock;
public ProjectService(
ProjectRepository projects,
AccountService accounts,
ProjectQueryService queries,
Clock clock) {
this.projects = projects;
this.accounts = accounts;
this.queries = queries;
this.clock = clock;
}
@@ -61,6 +65,11 @@ public class ProjectService {
projects.flush();
}
@Transactional
public ProjectTaskContext taskMutationContext(long actorUserId, long projectId) {
return queries.taskContext(actorUserId, lockedProject(projectId));
}
private ProjectEntity lockedProject(long projectId) {
return projects.findLockedById(projectId).orElseThrow(ProjectAccessDeniedException::new);
}