class WorkflowDashboardController < ApplicationController before_action :require_login def index @projects = Project.visible.has_module(:issue_tracking).to_a # 전체 워크플로우 통계 @total_stats = { active_workflows: CustomWorkflow.where(active: true).count, issues_in_workflow: IssueWorkflowState.where(completed_at: nil).count, completed_today: IssueWorkflowState.where('completed_at >= ?', Date.today).count } # 프로젝트별 현황 @project_stats = [] @projects.each do |project| workflows = CustomWorkflow.where(project_id: [project.id, nil]).where(active: true) issue_ids = Issue.where(project_id: project.id).pluck(:id) states = IssueWorkflowState.where(issue_id: issue_ids) in_progress = states.where(completed_at: nil).count completed = states.where.not(completed_at: nil).count if in_progress > 0 || completed > 0 @project_stats << { project: project, workflows_count: workflows.count, in_progress: in_progress, completed: completed } end end # 내 담당 이슈 (현재 단계 담당자가 나인 경우) @my_issues = find_my_workflow_issues(User.current) # 지연된 이슈 (기한이 있고 초과된 경우) @overdue_issues = find_overdue_issues end def project @project = Project.find(params[:project_id]) # 해당 프로젝트의 워크플로우들 @workflows = CustomWorkflow.where(project_id: [params[:project_id], nil]).where(active: true) # 프로젝트 이슈들의 워크플로우 상태 issue_ids = Issue.where(project_id: @project.id).pluck(:id) @workflow_states = IssueWorkflowState.includes(:issue, :current_step, :custom_workflow) .where(issue_id: issue_ids) .order(updated_at: :desc) # 단계별 그룹핑 @steps_summary = {} @workflow_states.where(completed_at: nil).each do |state| step_name = state.current_step&.name || '(알 수 없음)' @steps_summary[step_name] ||= [] @steps_summary[step_name] << state end end private def find_my_workflow_issues(user) return [] unless user.logged? states = IssueWorkflowState.includes(:issue, :current_step, :custom_workflow) .where(completed_at: nil) my_states = states.select do |state| state.current_step&.assignee?(user) end my_states.take(20) # 최대 20개 end def find_overdue_issues states = IssueWorkflowState.includes(:issue, :current_step) .where(completed_at: nil) overdue = states.select do |state| next false unless state.current_step&.due_days.present? # 현재 단계에 머문 시간 계산 step_started_at = state.updated_at due_date = step_started_at + state.current_step.due_days.days due_date < Time.current end overdue.take(20) end end