using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace MarketAlly.AIPlugin.ClaudeCode.Controllers;
///
/// API controller providing Claude Code integration endpoints
///
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class ClaudeCodeLearningController : ControllerBase
{
private readonly IClaudeCodeService _claudeCodeService;
private readonly IChatService _chatService;
private readonly IContextClaudeService _contextService;
private readonly ILogger _logger;
public ClaudeCodeLearningController(
IClaudeCodeService claudeCodeService,
IChatService chatService,
IContextClaudeService contextService,
ILogger logger)
{
_claudeCodeService = claudeCodeService;
_chatService = chatService;
_contextService = contextService;
_logger = logger;
}
///
/// Send a chat message to Claude Code
///
/// Chat request
/// Cancellation token
/// Claude's response
[HttpPost("chat")]
public async Task SendChatMessage([FromBody] ChatRequest request, CancellationToken cancellationToken = default)
{
try
{
var response = await _claudeCodeService.SendChatMessageAsync(request, cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in SendChatMessage");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// Analyze code or a file
///
/// Analysis request
/// Cancellation token
/// Analysis results
[HttpPost("analyze")]
public async Task AnalyzeCode([FromBody] AnalysisRequest request, CancellationToken cancellationToken = default)
{
try
{
var response = await _claudeCodeService.AnalyzeCodeAsync(request, cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in AnalyzeCode");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// Get current rate limit status
///
/// Cancellation token
/// Rate limit information
[HttpGet("rate-limit/status")]
public async Task GetRateLimitStatus(CancellationToken cancellationToken = default)
{
try
{
var response = await _claudeCodeService.GetRateLimitStatusAsync(cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in GetRateLimitStatus");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// Search project context
///
/// Search query
/// Optional project path
/// Cancellation token
/// Search results
[HttpGet("context/search")]
public async Task SearchContext(
[FromQuery] string query,
[FromQuery] string? projectPath = null,
CancellationToken cancellationToken = default)
{
try
{
if (string.IsNullOrWhiteSpace(query))
{
return BadRequest(new { success = false, error = "Query parameter is required" });
}
var response = await _claudeCodeService.SearchContextAsync(query, projectPath, cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in SearchContext");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// Store a decision or insight
///
/// Decision storage request
/// Cancellation token
/// Success response
[HttpPost("context/store-decision")]
public async Task StoreDecision([FromBody] StoreDecisionRequest request, CancellationToken cancellationToken = default)
{
try
{
var response = await _claudeCodeService.StoreDecisionAsync(request, cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in StoreDecision");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// Start a new chat session
///
/// Session start request
/// Cancellation token
/// New session information
[HttpPost("sessions/start")]
public async Task StartSession([FromBody] StartSessionRequest request, CancellationToken cancellationToken = default)
{
try
{
var response = await _chatService.StartSessionAsync(request, cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in StartSession");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// Get active chat sessions
///
/// Cancellation token
/// List of active sessions
[HttpGet("sessions")]
public async Task GetActiveSessions(CancellationToken cancellationToken = default)
{
try
{
var response = await _chatService.GetActiveSessionsAsync(cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in GetActiveSessions");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// Get session history
///
/// Session identifier
/// Maximum messages to return
/// Cancellation token
/// Session message history
[HttpGet("sessions/{sessionId}/history")]
public async Task GetSessionHistory(
string sessionId,
[FromQuery] int maxMessages = 50,
CancellationToken cancellationToken = default)
{
try
{
var response = await _chatService.GetSessionHistoryAsync(sessionId, maxMessages, cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in GetSessionHistory");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
///
/// End a chat session
///
/// Session identifier
/// Cancellation token
/// Success response
[HttpPost("sessions/{sessionId}/end")]
public async Task EndSession(string sessionId, CancellationToken cancellationToken = default)
{
try
{
var response = await _chatService.EndSessionAsync(sessionId, cancellationToken);
if (response.Success)
{
return Ok(new
{
success = true,
data = response.Data,
rateLimitInfo = response.RateLimitInfo
});
}
return BadRequest(new
{
success = false,
error = response.Error,
errorCode = response.ErrorCode,
rateLimitInfo = response.RateLimitInfo
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in EndSession");
return StatusCode(500, new { success = false, error = "Internal server error" });
}
}
}