package com.labelsys.backend.service; import com.labelsys.backend.context.LoginUser; import com.labelsys.backend.entity.BizDataRecord; import com.labelsys.backend.enums.UserRole; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor public class DataPermissionService { private final JdbcTemplate jdbcTemplate; public boolean canAccessCreator(LoginUser currentUser, Long creatorId, UserRole creatorRole) { try { return switch (currentUser.role()) { case EMPLOYEE -> currentUser.userId().equals(creatorId); case MANAGER -> creatorRole == UserRole.EMPLOYEE || creatorRole == UserRole.MANAGER; case ENGINEER -> true; }; } catch (Exception e) { log.error("canAccessCreator failed, companyId={}, userId={}, creatorId={}, error={}", currentUser.companyId(), currentUser.userId(), creatorId, e.getMessage(), e); throw e; } } public List filterByRole( LoginUser currentUser, List allRecords, Function roleExtractor, Function ownerIdExtractor) { try { if (allRecords == null || allRecords.isEmpty()) { return List.of(); } UserRole currentRole = currentUser.role(); Long currentUserId = currentUser.userId(); return allRecords.stream() .filter(record -> { UserRole recordRole = roleExtractor.apply(record); Long recordOwnerId = ownerIdExtractor.apply(record); return switch (currentRole) { case EMPLOYEE -> currentUserId.equals(recordOwnerId); case MANAGER -> recordRole == UserRole.EMPLOYEE || recordRole == UserRole.MANAGER; case ENGINEER -> true; }; }) .collect(Collectors.toList()); } catch (Exception e) { log.error("filterByRole failed, companyId={}, userId={}, error={}", currentUser.companyId(), currentUser.userId(), e.getMessage(), e); throw e; } } public List getAllowedRoles(LoginUser currentUser) { try { return switch (currentUser.role()) { case EMPLOYEE -> List.of(); case MANAGER -> List.of("EMPLOYEE", "MANAGER"); case ENGINEER -> List.of("EMPLOYEE", "MANAGER", "ENGINEER"); }; } catch (Exception e) { log.error("getAllowedRoles failed, companyId={}, userId={}, error={}", currentUser.companyId(), currentUser.userId(), e.getMessage(), e); throw e; } } public boolean shouldFilterByUserId(LoginUser currentUser) { try { return currentUser.role() == UserRole.EMPLOYEE; } catch (Exception e) { log.error("shouldFilterByUserId failed, companyId={}, userId={}, error={}", currentUser.companyId(), currentUser.userId(), e.getMessage(), e); throw e; } } public List listVisibleRecords(LoginUser currentUser) { try { List allRecords = jdbcTemplate.query(""" select id, company_id, creator_id, creator_role, record_name, created_at, updated_at from biz_data_record where company_id = ? order by id """, (rs, rowNum) -> BizDataRecord.builder() .id(rs.getLong("id")) .companyId(rs.getLong("company_id")) .creatorId(rs.getLong("creator_id")) .creatorRole(UserRole.valueOf(rs.getString("creator_role"))) .recordName(rs.getString("record_name")) .createdAt(rs.getTimestamp("created_at") == null ? null : rs.getTimestamp("created_at").toLocalDateTime()) .updatedAt(rs.getTimestamp("updated_at") == null ? null : rs.getTimestamp("updated_at").toLocalDateTime()) .build(), currentUser.companyId()); return filterByRole(currentUser, allRecords, BizDataRecord::getCreatorRole, BizDataRecord::getCreatorId); } catch (Exception e) { log.error("listVisibleRecords failed, companyId={}, userId={}, error={}", currentUser.companyId(), currentUser.userId(), e.getMessage(), e); throw e; } } }