diff --git a/FinlyticNews/Migrations/20260813202646_CheckPendingNews.Designer.cs b/FinlyticNews/Migrations/20260813202646_CheckPendingNews.Designer.cs new file mode 100644 index 0000000..914a348 --- /dev/null +++ b/FinlyticNews/Migrations/20260813202646_CheckPendingNews.Designer.cs @@ -0,0 +1,174 @@ +// +using System; +using FinlyticNews.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace FinlyticNews.Migrations +{ + [DbContext(typeof(NewsDbContext))] + [Migration("20260813202646_CheckPendingNews")] + partial class CheckPendingNews + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("FinlyticNews.Entities.ArticleSourceEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Source") + .IsRequired() + .HasColumnType("text"); + + b.Property("Type") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ArticleSources"); + }); + + modelBuilder.Entity("FinlyticNews.Entities.MatchedAssetEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Isin") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("NewsArticleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("Isin"); + + b.HasIndex("NewsArticleId"); + + b.ToTable("MatchedAssets"); + }); + + modelBuilder.Entity("FinlyticNews.Entities.NewsArticleEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Author") + .HasColumnType("text"); + + b.Property("ContentRaw") + .IsRequired() + .HasColumnType("text"); + + b.Property("Language") + .HasColumnType("text"); + + b.Property("PublishedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ScrapedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("SourceUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("Summary") + .HasColumnType("text"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("SourceUrl") + .IsUnique(); + + b.HasIndex("Status"); + + b.HasIndex("PublishedAt", "ScrapedAt"); + + b.ToTable("NewsArticles"); + }); + + modelBuilder.Entity("FinlyticNews.Entities.NewsSettingsEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ArticleRetentionDays") + .HasColumnType("integer"); + + b.Property("DefaultPageSize") + .HasColumnType("integer"); + + b.Property("N8nWebhookUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("PollingFrequencyMinutes") + .HasColumnType("integer"); + + b.Property("ScrapingIntervalMinutes") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("FinlyticNews.Entities.MatchedAssetEntity", b => + { + b.HasOne("FinlyticNews.Entities.NewsArticleEntity", "NewsArticle") + .WithMany("MatchedAssets") + .HasForeignKey("NewsArticleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NewsArticle"); + }); + + modelBuilder.Entity("FinlyticNews.Entities.NewsArticleEntity", b => + { + b.Navigation("MatchedAssets"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/FinlyticNews/Migrations/20260813202646_CheckPendingNews.cs b/FinlyticNews/Migrations/20260813202646_CheckPendingNews.cs new file mode 100644 index 0000000..407245a --- /dev/null +++ b/FinlyticNews/Migrations/20260813202646_CheckPendingNews.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace FinlyticNews.Migrations +{ + /// + public partial class CheckPendingNews : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/FinlyticSentiment/Migrations/20260813202634_CheckPendingSentiment.Designer.cs b/FinlyticSentiment/Migrations/20260813202634_CheckPendingSentiment.Designer.cs new file mode 100644 index 0000000..a43b810 --- /dev/null +++ b/FinlyticSentiment/Migrations/20260813202634_CheckPendingSentiment.Designer.cs @@ -0,0 +1,63 @@ +// +using System; +using FinlyticSentiment.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace FinlyticSentiment.Migrations +{ + [DbContext(typeof(SentimentDbContext))] + [Migration("20260813202634_CheckPendingSentiment")] + partial class CheckPendingSentiment + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("FinlyticSentiment.Entities.SentimentSettingsEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("EnglishWebhookUrl") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("GermanWebhookUrl") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("MaxBatchSize") + .HasColumnType("integer"); + + b.Property("MinConfidenceScore") + .HasColumnType("double precision"); + + b.Property("SweepIntervalMinutes") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("sentiment_settings", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/FinlyticSentiment/Migrations/20260813202634_CheckPendingSentiment.cs b/FinlyticSentiment/Migrations/20260813202634_CheckPendingSentiment.cs new file mode 100644 index 0000000..3271db9 --- /dev/null +++ b/FinlyticSentiment/Migrations/20260813202634_CheckPendingSentiment.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace FinlyticSentiment.Migrations +{ + /// + public partial class CheckPendingSentiment : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/FinlyticTechnicalAnalysis/Database/TechnicalAnalysisDbContext.cs b/FinlyticTechnicalAnalysis/Database/TechnicalAnalysisDbContext.cs index 1c6f7de..056a344 100644 --- a/FinlyticTechnicalAnalysis/Database/TechnicalAnalysisDbContext.cs +++ b/FinlyticTechnicalAnalysis/Database/TechnicalAnalysisDbContext.cs @@ -1,3 +1,4 @@ +using FinlyticCore.Entities.Settings; using FinlyticTechnicalAnalysis.Entities; using Microsoft.EntityFrameworkCore; @@ -9,6 +10,7 @@ public class TechnicalAnalysisDbContext : DbContext { } + public DbSet DynamicSettings => Set(); public DbSet MarketCandles => Set(); public DbSet MacroData => Set(); public DbSet CachedAnalyses => Set(); @@ -18,6 +20,12 @@ public class TechnicalAnalysisDbContext : DbContext { base.OnModelCreating(modelBuilder); + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id); + entity.HasIndex(e => e.Key); + }); + modelBuilder.Entity() .HasIndex(c => new { c.Symbol, c.Interval, c.Timestamp }) .IsUnique(); diff --git a/FinlyticTechnicalAnalysis/Migrations/20260813202624_CheckPendingTechnicalAnalysis.Designer.cs b/FinlyticTechnicalAnalysis/Migrations/20260813202624_CheckPendingTechnicalAnalysis.Designer.cs new file mode 100644 index 0000000..0c6fc46 --- /dev/null +++ b/FinlyticTechnicalAnalysis/Migrations/20260813202624_CheckPendingTechnicalAnalysis.Designer.cs @@ -0,0 +1,162 @@ +// +using System; +using FinlyticTechnicalAnalysis.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace FinlyticTechnicalAnalysis.Migrations +{ + [DbContext(typeof(TechnicalAnalysisDbContext))] + [Migration("20260813202624_CheckPendingTechnicalAnalysis")] + partial class CheckPendingTechnicalAnalysis + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("FinlyticTechnicalAnalysis.Entities.CachedAnalysisEntity", b => + { + b.Property("Isin") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("AnalysisJson") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("CalculatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Ticker") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Isin"); + + b.HasIndex("Isin"); + + b.ToTable("CachedAnalyses"); + }); + + modelBuilder.Entity("FinlyticTechnicalAnalysis.Entities.MacroDataEntity", b => + { + b.Property("Symbol") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("LastUpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("PreviousClose") + .HasColumnType("decimal(18, 6)"); + + b.Property("TrendState") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Value") + .HasColumnType("decimal(18, 6)"); + + b.HasKey("Symbol"); + + b.ToTable("MacroData"); + }); + + modelBuilder.Entity("FinlyticTechnicalAnalysis.Entities.MarketCandleEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Ask") + .HasColumnType("decimal(18, 6)"); + + b.Property("Bid") + .HasColumnType("decimal(18, 6)"); + + b.Property("Close") + .HasColumnType("decimal(18, 6)"); + + b.Property("High") + .HasColumnType("decimal(18, 6)"); + + b.Property("Interval") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Low") + .HasColumnType("decimal(18, 6)"); + + b.Property("Open") + .HasColumnType("decimal(18, 6)"); + + b.Property("Symbol") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Volume") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Symbol", "Interval", "Timestamp") + .IsUnique(); + + b.ToTable("MarketCandles"); + }); + + modelBuilder.Entity("FinlyticTechnicalAnalysis.Entities.TaSettingsEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("EmaShortPeriod") + .HasColumnType("integer"); + + b.Property("RsiOverboughtLimit") + .HasColumnType("double precision"); + + b.Property("RsiOversoldLimit") + .HasColumnType("double precision"); + + b.Property("SmaLongPeriod") + .HasColumnType("integer"); + + b.Property("SmaMediumPeriod") + .HasColumnType("integer"); + + b.Property("SupertrendMultiplier") + .HasColumnType("double precision"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/FinlyticTechnicalAnalysis/Migrations/20260813202624_CheckPendingTechnicalAnalysis.cs b/FinlyticTechnicalAnalysis/Migrations/20260813202624_CheckPendingTechnicalAnalysis.cs new file mode 100644 index 0000000..a540ee0 --- /dev/null +++ b/FinlyticTechnicalAnalysis/Migrations/20260813202624_CheckPendingTechnicalAnalysis.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace FinlyticTechnicalAnalysis.Migrations +{ + /// + public partial class CheckPendingTechnicalAnalysis : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/FinlyticTechnicalAnalysis/Program.cs b/FinlyticTechnicalAnalysis/Program.cs index 913f883..76bdf77 100644 --- a/FinlyticTechnicalAnalysis/Program.cs +++ b/FinlyticTechnicalAnalysis/Program.cs @@ -30,10 +30,10 @@ builder.Services.AddSingleton(); // Register Technical Analysis Services builder.Services.AddSingleton(); -builder.Services.AddSingleton(); +builder.Services.AddTransient(); builder.Services.AddScoped(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddTransient(); +builder.Services.AddSingleton(); // Register MQTT Client (as a Hosted Service) builder.Services.AddHostedService();