Initial commit
This commit is contained in:
107
MoneyMap/Data/MoneyMapContext.cs
Normal file
107
MoneyMap/Data/MoneyMapContext.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MoneyMap.Models;
|
||||
using MoneyMap.Services;
|
||||
|
||||
namespace MoneyMap.Data
|
||||
{
|
||||
public class MoneyMapContext : DbContext
|
||||
{
|
||||
public MoneyMapContext(DbContextOptions<MoneyMapContext> options) : base(options) { }
|
||||
|
||||
public DbSet<Card> Cards => Set<Card>();
|
||||
public DbSet<Transaction> Transactions => Set<Transaction>();
|
||||
public DbSet<Receipt> Receipts => Set<Receipt>();
|
||||
public DbSet<ReceiptParseLog> ReceiptParseLogs => Set<ReceiptParseLog>();
|
||||
public DbSet<ReceiptLineItem> ReceiptLineItems => Set<ReceiptLineItem>();
|
||||
|
||||
public DbSet<CategoryMapping> CategoryMappings => Set<CategoryMapping>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
// ---------- CARD ----------
|
||||
modelBuilder.Entity<Card>(e =>
|
||||
{
|
||||
e.Property(x => x.Issuer).HasMaxLength(100).IsRequired();
|
||||
e.Property(x => x.Last4).HasMaxLength(4).IsRequired();
|
||||
e.Property(x => x.Owner).HasMaxLength(100);
|
||||
e.HasIndex(x => new { x.Issuer, x.Last4, x.Owner });
|
||||
});
|
||||
|
||||
// ---------- TRANSACTION ----------
|
||||
modelBuilder.Entity<Transaction>(e =>
|
||||
{
|
||||
e.Property(x => x.TransactionType).HasMaxLength(20);
|
||||
e.Property(x => x.Name).HasMaxLength(200).IsRequired();
|
||||
e.Property(x => x.Memo).HasMaxLength(500).HasDefaultValue(string.Empty);
|
||||
e.Property(x => x.Amount).HasColumnType("decimal(18,2)");
|
||||
e.Property(x => x.Category).HasMaxLength(100);
|
||||
e.Property(x => x.CardLast4).HasMaxLength(4);
|
||||
|
||||
// Card (required). If a card is deleted, block delete when txns exist (no cascades).
|
||||
e.HasOne(x => x.Card)
|
||||
.WithMany(c => c.Transactions)
|
||||
.HasForeignKey(x => x.CardId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
// ---------- RECEIPT ----------
|
||||
modelBuilder.Entity<Receipt>(e =>
|
||||
{
|
||||
e.Property(x => x.FileName).HasMaxLength(260).IsRequired();
|
||||
e.Property(x => x.ContentType).HasMaxLength(100).HasDefaultValue("application/octet-stream");
|
||||
e.Property(x => x.StoragePath).HasMaxLength(1024).IsRequired();
|
||||
e.Property(x => x.FileHashSha256).HasMaxLength(64).IsRequired();
|
||||
|
||||
e.Property(x => x.Merchant).HasMaxLength(200);
|
||||
e.Property(x => x.Subtotal).HasColumnType("decimal(18,2)");
|
||||
e.Property(x => x.Tax).HasColumnType("decimal(18,2)");
|
||||
e.Property(x => x.Total).HasColumnType("decimal(18,2)");
|
||||
e.Property(x => x.Currency).HasMaxLength(8);
|
||||
|
||||
// Receipt must belong to a Transaction. If txn is deleted, cascade remove receipts.
|
||||
e.HasOne(x => x.Transaction)
|
||||
.WithMany(t => t.Receipts)
|
||||
.HasForeignKey(x => x.TransactionId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
// ---------- RECEIPT PARSE LOG ----------
|
||||
modelBuilder.Entity<ReceiptParseLog>(e =>
|
||||
{
|
||||
e.Property(x => x.Provider).HasMaxLength(50).IsRequired();
|
||||
e.Property(x => x.Model).HasMaxLength(100).IsRequired();
|
||||
e.Property(x => x.ProviderJobId).HasMaxLength(100);
|
||||
e.Property(x => x.ExtractedTextPath).HasMaxLength(1024);
|
||||
|
||||
e.HasOne(x => x.Receipt)
|
||||
.WithMany(r => r.ParseLogs)
|
||||
.HasForeignKey(x => x.ReceiptId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
// ---------- RECEIPT LINE ITEM ----------
|
||||
modelBuilder.Entity<ReceiptLineItem>(e =>
|
||||
{
|
||||
e.Property(x => x.Description).HasMaxLength(300).IsRequired();
|
||||
e.Property(x => x.Unit).HasMaxLength(16);
|
||||
e.Property(x => x.UnitPrice).HasColumnType("decimal(18,4)");
|
||||
e.Property(x => x.LineTotal).HasColumnType("decimal(18,2)");
|
||||
e.Property(x => x.Sku).HasMaxLength(64);
|
||||
e.Property(x => x.Category).HasMaxLength(100);
|
||||
|
||||
e.HasOne(x => x.Receipt)
|
||||
.WithMany(r => r.LineItems)
|
||||
.HasForeignKey(x => x.ReceiptId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
// ---------- Extra SQL Server–friendly indexes ----------
|
||||
// Fast filtering by date/amount/category
|
||||
modelBuilder.Entity<Transaction>().HasIndex(x => x.Date);
|
||||
modelBuilder.Entity<Transaction>().HasIndex(x => x.Amount);
|
||||
modelBuilder.Entity<Transaction>().HasIndex(x => x.Category);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user