text-matcher/src/Nocr.TextMatcher.Migrator/Migrations/TextMatcherContextModelSnapshot.cs
ruberoid 78d1099bfc Add message deduplication and versioning for text match notifications
This update implements a comprehensive solution to prevent duplicate notifications
when Telegram messages are edited, while maintaining a full history of changes.

Features:
- New TextMatch entity to store match history with versioning
- Database migration for TextMatches table with proper indexes
- TextMatchRepository for managing match records
- TextSubscriptionUpdated event for message update notifications
- Enhanced MessageReceivedHandler with deduplication logic:
  * First match creates version 1 and publishes TextSubscriptionMatched
  * Subsequent updates create new versions and publish TextSubscriptionUpdated
  * Skips notifications if message text hasn't changed

Technical details:
- MessageId changed from int to long to match Telegram API types
- Proper indexes on (MessageId, SubscriptionId) and UserId
- Full audit trail of message edits in database

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 13:22:58 +04:00

115 lines
4.0 KiB
C#

// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Nocr.TextMatcher.Persistence;
#nullable disable
namespace Nocr.TextMatcher.Migrator.Migrations
{
[DbContext(typeof(TextMatcherContext))]
partial class TextMatcherContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("Nocr.TextMatcher.AppServices.TextMatches.TextMatch", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
b.Property<string>("ChatUsername")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.Property<DateTimeOffset>("CreatedDateTime")
.HasColumnType("datetime(6)");
b.Property<string>("From")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<int>("MessageId")
.HasColumnType("int");
b.Property<DateTimeOffset>("MessageOccuredDateTime")
.HasColumnType("datetime(6)");
b.Property<string>("MessageText")
.IsRequired()
.HasMaxLength(4096)
.HasColumnType("varchar(4096)");
b.Property<long>("SubscriptionId")
.HasColumnType("bigint");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.Property<int>("Version")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("UserId")
.HasDatabaseName("IX_TextMatches_UserId");
b.HasIndex("MessageId", "SubscriptionId")
.HasDatabaseName("IX_TextMatches_MessageId_SubscriptionId");
b.ToTable("TextMatches", (string)null);
});
modelBuilder.Entity("Nocr.TextMatcher.AppServices.TextSubscriptions.TextSubscription", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<string>("ChatUsername")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.Property<DateTimeOffset>("CreatedDateTime")
.HasColumnType("datetime(6)");
b.Property<int>("Rule")
.HasColumnType("int");
b.Property<string>("Template")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.Property<long>("UserId")
.HasColumnType("bigint");
b.HasKey("Id");
b.ToTable("TextSubscriptions");
});
#pragma warning restore 612, 618
}
}
}