Skip to content

Commit 3355bc2

Browse files
ANcpLuaclaude
andcommitted
feat: add CreatedAt to OcrCommand, update Gemini to 2.5-flash
## OcrCommand Enhancement - Add optional `CreatedAt` parameter for document timestamp tracking - Fully backward compatible - defaults to null - New tests for serialization and backward compatibility ## Gemini Model Update - Update default model from gemini-2.0-flash → gemini-2.5-flash - Update docs and test fixtures Bumps to v2.2.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 6fd3144 commit 3355bc2

File tree

8 files changed

+61
-10
lines changed

8 files changed

+61
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ await _publisher.PublishGenAICommandAsync(genAiCommand);
123123
{
124124
"Gemini": {
125125
"ApiKey": "your-api-key",
126-
"Model": "gemini-2.0-flash",
126+
"Model": "gemini-2.5-flash",
127127
"TimeoutSeconds": 30
128128
}
129129
}

SWEN3.Paperless.RabbitMq.Tests/Unit/GeminiServiceTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class GeminiServiceTests
1212
private readonly GeminiOptions _options = new()
1313
{
1414
ApiKey = "test-key",
15-
Model = "gemini-2.0-flash",
15+
Model = "gemini-2.5-flash",
1616
TimeoutSeconds = 5
1717
};
1818

SWEN3.Paperless.RabbitMq.Tests/Unit/GenAIExtensionsTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public void AddPaperlessGenAI_RegistersServices()
1313
.AddInMemoryCollection(new Dictionary<string, string?>
1414
{
1515
["Gemini:ApiKey"] = "test-key",
16-
["Gemini:Model"] = "gemini-2.0-flash",
16+
["Gemini:Model"] = "gemini-2.5-flash",
1717
["Gemini:TimeoutSeconds"] = "15"
1818
})
1919
.Build();
@@ -29,7 +29,7 @@ public void AddPaperlessGenAI_RegistersServices()
2929

3030
var options = provider.GetRequiredService<IOptions<GeminiOptions>>().Value;
3131
options.ApiKey.Should().Be("test-key");
32-
options.Model.Should().Be("gemini-2.0-flash");
32+
options.Model.Should().Be("gemini-2.5-flash");
3333
options.TimeoutSeconds.Should().Be(15);
3434

3535
var summarizer = provider.GetRequiredService<ITextSummarizer>();

SWEN3.Paperless.RabbitMq.Tests/Unit/PublishingExtensionsTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,53 @@ public async Task PublishOcrCommandAsync_ShouldPublishWithCorrectRoutingKey()
1414
_publisherMock.Verify(p => p.PublishAsync(RabbitMqSchema.OcrCommandRouting, command), Times.Once);
1515
}
1616

17+
[Fact]
18+
public async Task PublishOcrCommandAsync_WithCreatedAt_ShouldPublishWithTimestamp()
19+
{
20+
var createdAt = DateTimeOffset.UtcNow.AddHours(-1);
21+
var command = new OcrCommand(Guid.NewGuid(), "document.pdf", "/path/to/document.pdf", createdAt);
22+
23+
await _publisherMock.Object.PublishOcrCommandAsync(command);
24+
25+
_publisherMock.Verify(p => p.PublishAsync(
26+
RabbitMqSchema.OcrCommandRouting,
27+
It.Is<OcrCommand>(c => c.CreatedAt == createdAt)), Times.Once);
28+
}
29+
30+
[Fact]
31+
public void OcrCommand_WithoutCreatedAt_ShouldDefaultToNull()
32+
{
33+
var command = new OcrCommand(Guid.NewGuid(), "document.pdf", "/path/to/document.pdf");
34+
35+
command.CreatedAt.Should().BeNull();
36+
}
37+
38+
[Fact]
39+
public void OcrCommand_SerializesAndDeserializesCreatedAt()
40+
{
41+
var createdAt = DateTimeOffset.UtcNow.AddDays(-1);
42+
var original = new OcrCommand(Guid.NewGuid(), "test.pdf", "/test.pdf", createdAt);
43+
44+
var json = JsonSerializer.Serialize(original);
45+
var deserialized = JsonSerializer.Deserialize<OcrCommand>(json);
46+
47+
deserialized.Should().NotBeNull();
48+
deserialized!.CreatedAt.Should().BeCloseTo(createdAt, TimeSpan.FromMilliseconds(1));
49+
}
50+
51+
[Fact]
52+
public void OcrCommand_DeserializesWithoutCreatedAt_BackwardCompatibility()
53+
{
54+
// Simulate old JSON without CreatedAt field
55+
var json = """{"JobId":"550e8400-e29b-41d4-a716-446655440000","FileName":"old.pdf","FilePath":"/old.pdf"}""";
56+
57+
var deserialized = JsonSerializer.Deserialize<OcrCommand>(json);
58+
59+
deserialized.Should().NotBeNull();
60+
deserialized!.CreatedAt.Should().BeNull();
61+
deserialized.FileName.Should().Be("old.pdf");
62+
}
63+
1764
[Fact]
1865
public async Task PublishOcrEventAsync_ShouldPublishWithCorrectRoutingKey()
1966
{

SWEN3.Paperless.RabbitMq/GenAI/GeminiOptions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ public sealed class GeminiOptions
3030
/// Gets or initializes the Gemini model identifier to use for text generation.
3131
/// </summary>
3232
/// <value>
33-
/// The model name. Defaults to "gemini-2.0-flash" for optimal balance of speed and quality.
33+
/// The model name. Defaults to "gemini-2.5-flash" for optimal balance of speed and quality.
3434
/// </value>
3535
/// <remarks>
36-
/// Available models include "gemini-2.0-flash", "gemini-1.5-pro", and "gemini-1.5-flash".
36+
/// Available models include "gemini-2.5-flash", "gemini-2.5-pro", and "gemini-2.5-flash-lite".
3737
/// See Google AI documentation for current model availability and capabilities.
3838
/// </remarks>
39-
public string Model { get; init; } = "gemini-2.0-flash";
39+
public string Model { get; init; } = "gemini-2.5-flash";
4040

4141
/// <summary>
4242
/// Gets or initializes the timeout duration in seconds for HTTP client requests.

SWEN3.Paperless.RabbitMq/GenAI/GenAIExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public static class GenAIExtensions
3535
/// {
3636
/// "Gemini": {
3737
/// "ApiKey": "your-api-key",
38-
/// "Model": "gemini-2.0-flash",
38+
/// "Model": "gemini-2.5-flash",
3939
/// "TimeoutSeconds": 30
4040
/// }
4141
/// }

SWEN3.Paperless.RabbitMq/Models/OcrCommand.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,9 @@ namespace SWEN3.Paperless.RabbitMq.Models;
99
/// <param name="JobId">Unique identifier for the OCR job.</param>
1010
/// <param name="FileName">Name of the file to process.</param>
1111
/// <param name="FilePath">Path to the file in storage.</param>
12+
/// <param name="CreatedAt">
13+
/// When the document was originally uploaded. Optional for backward compatibility.
14+
/// Consumers should fall back to <see cref="DateTimeOffset.UtcNow" /> if null.
15+
/// </param>
1216
/// <seealso cref="OcrEvent" />
13-
public record OcrCommand(Guid JobId, string FileName, string FilePath);
17+
public record OcrCommand(Guid JobId, string FileName, string FilePath, DateTimeOffset? CreatedAt = null);

SWEN3.Paperless.RabbitMq/SWEN3.Paperless.RabbitMq.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<PackageId>SWEN3.Paperless.RabbitMq</PackageId>
1010
<Title>SWEN3.Paperless.RabbitMq - RabbitMQ Messaging with SSE Streaming &amp; AI Summarization</Title>
11-
<Version>2.1.2</Version>
11+
<Version>2.2.0</Version>
1212
<Authors>Alexander Nachtmann</Authors>
1313
<Copyright>Copyright © 2025 Alexander Nachtmann</Copyright>
1414

0 commit comments

Comments
 (0)