get-projects.handler.ts•4.76 kB
/**
 * Get Projects Handler
 *
 * MCP tool handler for retrieving JIRA projects with filtering and search capabilities
 */
import { BaseToolHandler } from "@core/tools/tool-handler.class";
import {
  JiraApiError,
  JiraNotFoundError,
  JiraPermissionError,
} from "@features/jira/client/errors";
import { ProjectListFormatter } from "@features/jira/projects/formatters/project-list.formatter";
import type { GetProjectsUseCase } from "@features/jira/projects/use-cases";
import type {
  GetProjectsParams,
  ProjectParamsValidator,
} from "@features/jira/projects/validators";
/**
 * Handler for retrieving JIRA projects
 * Provides comprehensive project listing with filtering and search capabilities
 */
export class GetProjectsHandler extends BaseToolHandler<
  GetProjectsParams,
  string
> {
  private readonly formatter: ProjectListFormatter;
  /**
   * Create a new GetProjectsHandler with use case and validator
   *
   * @param getProjectsUseCase - Use case for retrieving projects
   * @param projectParamsValidator - Validator for project parameters
   */
  constructor(
    private readonly getProjectsUseCase: GetProjectsUseCase,
    private readonly projectParamsValidator: ProjectParamsValidator,
  ) {
    super("JIRA", "Get Projects");
    this.formatter = new ProjectListFormatter();
  }
  /**
   * Execute the handler logic
   * Retrieves JIRA projects with optional filtering and formatting
   *
   * @param params - Parameters for project retrieval
   */
  protected async execute(params: GetProjectsParams): Promise<string> {
    try {
      // Step 1: Validate parameters
      const validatedParams =
        this.projectParamsValidator.validateGetProjectsParams(params);
      this.logger.info("Getting JIRA projects");
      // Step 2: Get projects using use case
      this.logger.debug("Retrieving projects with params:", {
        hasSearch: !!validatedParams.searchQuery,
        hasTypeFilter: !!validatedParams.typeKey,
        maxResults: validatedParams.maxResults,
      });
      const projects = await this.getProjectsUseCase.execute(validatedParams);
      // Step 3: Format and return success response
      this.logger.info(`Successfully retrieved ${projects.length} projects`);
      return this.formatter.format(projects);
    } catch (error) {
      this.logger.error(`Failed to get JIRA projects: ${error}`);
      throw this.enhanceError(error, params);
    }
  }
  /**
   * Enhance error messages for better user guidance
   */
  private enhanceError(error: unknown, params?: GetProjectsParams): Error {
    const filterContext = this.getFilterContext(params);
    if (error instanceof JiraNotFoundError) {
      return new Error(
        `❌ **No Projects Found**\n\nNo projects found${filterContext}.\n\n**Solutions:**\n- Check your search query is correct\n- Try removing filters to see all projects\n- Verify you have permission to view projects\n\n**Example:** \`jira_get_projects searchQuery="web"\``,
      );
    }
    if (error instanceof JiraPermissionError) {
      return new Error(
        `❌ **Permission Denied**\n\nYou don't have permission to view projects${filterContext}.\n\n**Solutions:**\n- Check your JIRA permissions\n- Contact your JIRA administrator\n- Verify you're logged in with the correct account\n\n**Required Permissions:** Browse Projects`,
      );
    }
    if (error instanceof JiraApiError) {
      return new Error(
        `❌ **JIRA API Error**\n\n${error.message}\n\n**Solutions:**\n- Check your filter parameters are valid\n- Try removing filters to see all projects\n- Verify your search query syntax\n- Check project type keys are correct\n\n**Example:** \`jira_get_projects searchQuery="web" typeKey="software"\``,
      );
    }
    if (error instanceof Error) {
      return new Error(
        `❌ **Project Retrieval Failed**\n\n${error.message}${filterContext}\n\n**Solutions:**\n- Check your parameters are valid\n- Try a simpler query first\n- Verify your JIRA connection\n\n**Example:** \`jira_get_projects maxResults=10\``,
      );
    }
    return new Error(
      "❌ **Unknown Error**\n\nAn unknown error occurred during project retrieval.\n\nPlease check your parameters and try again.",
    );
  }
  /**
   * Get filter context for error messages
   */
  private getFilterContext(params?: GetProjectsParams): string {
    if (!params) return "";
    const filters = [];
    if (params.searchQuery) filters.push(`search: "${params.searchQuery}"`);
    if (params.typeKey) filters.push(`type: ${params.typeKey}`);
    if (params.categoryId) filters.push(`category: ${params.categoryId}`);
    if (params.recent) filters.push(`recent: ${params.recent}`);
    return filters.length > 0 ? ` with filters (${filters.join(", ")})` : "";
  }
}