Skip to content

Commit dc9b544

Browse files
authored
Merge pull request #2 from byerlikaya/feature/document-improvements
feat: Complete document service refactoring and logging migration ## Extended Description This PR introduces comprehensive improvements to the SmartRAG system: ### �� Core Architecture - Complete refactoring of DocumentService into focused, SOLID-compliant services - Separation of concerns: DocumentService (CRUD) vs DocumentSearchService (AI/Search) - Professional structured logging with ILogger throughout the codebase - Migration from Console.WriteLine to structured logging ### 🚀 New Features - Multi-document upload capability with parallel processing - Smart query intent detection (general conversation vs document search) - Enhanced embedding generation with fallback mechanisms - Batch processing support for VoyageAI embeddings ### 📊 Performance & Reliability - Intelligent rate limiting for AI providers - Fallback strategies for embedding generation failures - Optimized batch processing for large documents - Enhanced error handling and retry mechanisms ### 🛡️ Security & Quality - SanitizeForLog helper to prevent log forging security issues - Centralized logging with ServiceLogMessages - Comprehensive XML documentation for all interfaces - SOLID and DRY principles implementation ### 🧪 Testing & Validation - Unit tests pass successfully - Integration tests completed - Manual testing verified - 0 errors, 0 warnings, 0 messages achieved This refactoring establishes a solid foundation for future SmartRAG enhancements while maintaining backward compatibility.
2 parents e0e80b6 + 1bb56ab commit dc9b544

27 files changed

+1639
-2112
lines changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -547,11 +547,7 @@ We welcome contributions!
547547

548548
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
549549

550-
## 🌟 Star History
551550

552-
[![Star History Chart](https://api.star-history.com/svg?repos=byerlikaya/SmartRAG&type=Date)](https://star-history.com/#byerlikaya/SmartRAG&Date)
553-
554-
---
555551

556552
**Built with ❤️ by Barış Yerlikaya**
557553

SmartRAG.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ VisualStudioVersion = 17.0.31903.59
44
MinimumVisualStudioVersion = 10.0.40219.1
55
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartRAG", "src\SmartRAG\SmartRAG.csproj", "{DECA885F-8815-4A0F-A12C-30563827C255}"
66
EndProject
7-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartRAG.API", "src\SmartRAG.API\SmartRAG.API.csproj", "{E7606EAF-F26D-441F-B5A4-34A72A70DD6C}"
7+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartRAG.API", "examples\WebAPI\SmartRAG.API.csproj", "{E7606EAF-F26D-441F-B5A4-34A72A70DD6C}"
88
EndProject
99
Global
1010
GlobalSection(SolutionConfigurationPlatforms) = preSolution

examples/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# SmartRAG Examples
2+
3+
This directory contains example projects demonstrating how to use SmartRAG in different scenarios.
4+
5+
## 📁 Available Examples
6+
7+
### **WebAPI** - ASP.NET Core Web API Example
8+
- **Location**: `WebAPI/`
9+
- **Description**: Complete web API implementation showing document upload, search, and RAG operations
10+
- **Features**:
11+
- Multi-document upload
12+
- AI-powered question answering
13+
- Smart query intent detection
14+
- Multiple storage providers
15+
- Comprehensive API documentation
16+
17+
## 🚀 Running Examples
18+
19+
### WebAPI Example
20+
```bash
21+
cd examples/WebAPI
22+
dotnet restore
23+
dotnet run
24+
```
25+
26+
Browse to `https://localhost:5001/scalar/v1` for interactive API documentation.
27+
28+
## 🔧 Configuration
29+
30+
Each example includes its own configuration files. Copy and modify the template files as needed:
31+
32+
```bash
33+
# Copy development configuration template
34+
cp appsettings.Development.template.json appsettings.Development.json
35+
36+
# Edit with your API keys and configuration
37+
```
38+
39+
## 📚 Documentation
40+
41+
- **Main Documentation**: [SmartRAG README](../../README.md)
42+
- **API Reference**: [API Documentation](../../docs/api-reference.md)
43+
- **Configuration Guide**: [Configuration Guide](../../docs/configuration.md)
44+
45+
## 🤝 Contributing
46+
47+
Want to add more examples? Create a new directory and submit a pull request!
48+
49+
### Example Types to Consider:
50+
- **Console Application** - Command-line interface
51+
- **Blazor WebAssembly** - Client-side web app
52+
- **WPF Application** - Desktop application
53+
- **Azure Functions** - Serverless implementation
54+
- **Minimal API** - Lightweight web API

src/SmartRAG.API/Controllers/DocumentsController.cs renamed to examples/WebAPI/Controllers/DocumentsController.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ namespace SmartRAG.API.Controllers;
1313
[Route("api/[controller]")]
1414
[Produces("application/json")]
1515
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
16-
public class DocumentsController(IDocumentService documentService, IDocumentParserService documentParser) : ControllerBase
16+
public class DocumentsController(
17+
IDocumentService documentService,
18+
IDocumentParserService documentParser) : ControllerBase
1719
{
1820
/// <summary>
1921
/// Gets supported file types and content types
@@ -58,6 +60,37 @@ public IActionResult GetSupportedTypes()
5860
}
5961
}
6062

63+
/// <summary>
64+
/// Upload multiple documents to the system
65+
/// </summary>
66+
[HttpPost("upload-multiple")]
67+
[Consumes("multipart/form-data")]
68+
[RequestSizeLimit(100 * 1024 * 1024)] // 100 MB
69+
[RequestFormLimits(MultipartBodyLengthLimit = 100 * 1024 * 1024)]
70+
public async Task<ActionResult<List<Entities.Document>>> UploadDocuments([FromForm] List<IFormFile> files)
71+
{
72+
if (files == null || files.Count == 0)
73+
return BadRequest("No files provided");
74+
75+
try
76+
{
77+
var fileStreams = files.Select(f => f.OpenReadStream());
78+
var fileNames = files.Select(f => f.FileName);
79+
var contentTypes = files.Select(f => f.ContentType);
80+
81+
var documents = await documentService.UploadDocumentsAsync(
82+
fileStreams,
83+
fileNames,
84+
contentTypes,
85+
"system");
86+
87+
return CreatedAtAction(nameof(GetAllDocuments), documents);
88+
}
89+
catch (Exception ex)
90+
{
91+
return StatusCode(500, $"Internal server error: {ex.Message}");
92+
}
93+
}
6194
/// <summary>
6295
/// Get a document by ID
6396
/// </summary>
@@ -83,7 +116,6 @@ public IActionResult GetSupportedTypes()
83116
return Ok(documents);
84117
}
85118

86-
87119
/// <summary>
88120
/// Delete a document
89121
/// </summary>

src/SmartRAG.API/Controllers/SearchController.cs renamed to examples/WebAPI/Controllers/SearchController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace SmartRAG.API.Controllers;
1010
[Route("api/[controller]")]
1111
[Produces("application/json")]
1212
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
13-
public class SearchController(IDocumentService documentService) : ControllerBase
13+
public class SearchController(IDocumentSearchService documentSearchService) : ControllerBase
1414
{
1515
/// <summary>
1616
/// Search documents using RAG (Retrieval-Augmented Generation)
@@ -28,7 +28,7 @@ public async Task<ActionResult<object>> Search([FromBody] Contracts.SearchReques
2828

2929
try
3030
{
31-
var response = await documentService.GenerateRagAnswerAsync(query, maxResults);
31+
var response = await documentSearchService.GenerateRagAnswerAsync(query, maxResults);
3232
return Ok(response);
3333
}
3434
catch (Exception ex)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using Microsoft.OpenApi.Models;
2+
using Swashbuckle.AspNetCore.SwaggerGen;
3+
4+
namespace SmartRAG.API.Filters;
5+
6+
public class MultipartFileUploadFilter : IOperationFilter
7+
{
8+
public void Apply(OpenApiOperation operation, OperationFilterContext context)
9+
{
10+
// Check if this is the upload-multiple endpoint
11+
if (context.MethodInfo.Name == "UploadDocuments" &&
12+
context.MethodInfo.DeclaringType?.Name == "DocumentsController")
13+
{
14+
// Remove any existing request body
15+
operation.RequestBody = null;
16+
17+
// Add the multipart form data request body with multiple files
18+
operation.RequestBody = new OpenApiRequestBody
19+
{
20+
Content = new Dictionary<string, OpenApiMediaType>
21+
{
22+
["multipart/form-data"] = new OpenApiMediaType
23+
{
24+
Schema = new OpenApiSchema
25+
{
26+
Type = "object",
27+
Properties = new Dictionary<string, OpenApiSchema>
28+
{
29+
["files"] = new OpenApiSchema
30+
{
31+
Type = "array",
32+
Items = new OpenApiSchema
33+
{
34+
Type = "string",
35+
Format = "binary"
36+
}
37+
}
38+
},
39+
Required = new HashSet<string> { "files" }
40+
}
41+
}
42+
}
43+
};
44+
45+
// Add external documentation link for simple upload page
46+
if (operation.ExternalDocs == null)
47+
operation.ExternalDocs = new OpenApiExternalDocs();
48+
49+
operation.ExternalDocs.Description = "Simple multiple file upload page";
50+
operation.ExternalDocs.Url = new Uri("/upload.html", UriKind.Relative);
51+
}
52+
}
53+
}

examples/WebAPI/Program.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using Scalar.AspNetCore;
2+
using SmartRAG.Enums;
3+
using SmartRAG.Extensions;
4+
using Microsoft.OpenApi.Models;
5+
using SmartRAG.API.Filters;
6+
7+
var builder = WebApplication.CreateBuilder(args);
8+
9+
// Configure Kestrel server options for file uploads
10+
builder.WebHost.UseKestrel(options =>
11+
{
12+
options.Limits.MaxRequestBodySize = 100 * 1024 * 1024; // 100 MB
13+
});
14+
15+
RegisterServices(builder.Services, builder.Configuration);
16+
17+
var app = builder.Build();
18+
ConfigureMiddleware(app, builder.Environment);
19+
20+
app.Run();
21+
22+
static void RegisterServices(IServiceCollection services, IConfiguration configuration)
23+
{
24+
// Configure logging
25+
services.AddLogging(builder =>
26+
{
27+
builder.ClearProviders();
28+
builder.AddConsole();
29+
builder.AddDebug();
30+
builder.SetMinimumLevel(LogLevel.Debug);
31+
});
32+
33+
services.AddControllers();
34+
services.AddEndpointsApiExplorer();
35+
services.AddOpenApi();
36+
services.AddSwaggerGen(c =>
37+
{
38+
c.SwaggerDoc("v1", new OpenApiInfo { Title = "SmartRAG API", Version = "v1" });
39+
40+
// Configure multipart file upload for multiple files
41+
c.OperationFilter<MultipartFileUploadFilter>();
42+
});
43+
44+
// Configure form options for file uploads
45+
services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options =>
46+
{
47+
options.MultipartBodyLengthLimit = 100 * 1024 * 1024; // 100 MB
48+
options.ValueLengthLimit = int.MaxValue;
49+
options.ValueCountLimit = int.MaxValue;
50+
options.KeyLengthLimit = int.MaxValue;
51+
});
52+
53+
// Add SmartRag services with minimal configuration
54+
services.UseSmartRag(configuration,
55+
storageProvider: StorageProvider.InMemory, // Default: InMemory
56+
aiProvider: AIProvider.Gemini // Use OpenAI provider
57+
);
58+
59+
services.AddCors(options =>
60+
{
61+
options.AddPolicy("AllowAll", policy =>
62+
{
63+
policy.AllowAnyOrigin()
64+
.AllowAnyMethod()
65+
.AllowAnyHeader();
66+
});
67+
});
68+
}
69+
70+
static void ConfigureMiddleware(WebApplication app, IWebHostEnvironment environment)
71+
{
72+
73+
if (environment.IsDevelopment())
74+
{
75+
app.MapOpenApi();
76+
app.MapSwagger();
77+
app.UseSwaggerUI();
78+
}
79+
80+
// Serve static files for simple upload page
81+
app.UseStaticFiles();
82+
83+
app.UseHttpsRedirection();
84+
app.UseCors("AllowAll");
85+
app.UseAuthorization();
86+
app.MapControllers();
87+
}

0 commit comments

Comments
 (0)