Add Community Formula Library feature
Companies can now share their custom formula templates to a platform-wide community library. Other tenants can browse, preview, and import formulas as independent local copies. Includes attribution (source company name), "Inspired by" lineage for re-contributed formulas, import counts, own-formula badge, cascade diagram nullification, and AI assistant + help docs updates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -289,6 +289,12 @@ public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDataPro
|
||||
/// </summary>
|
||||
public DbSet<PowderCatalogItem> PowderCatalogItems { get; set; }
|
||||
|
||||
/// <summary>Community library of shared formula templates. Platform-level, no tenant filter.</summary>
|
||||
public DbSet<FormulaLibraryItem> FormulaLibraryItems { get; set; }
|
||||
|
||||
/// <summary>Per-company record of which community library formulas a company has imported.</summary>
|
||||
public DbSet<FormulaLibraryImport> FormulaLibraryImports { get; set; }
|
||||
|
||||
/// <summary>User-submitted bug reports; tenant-filtered with soft delete.</summary>
|
||||
public DbSet<BugReport> BugReports { get; set; }
|
||||
/// <summary>File attachments for bug reports; soft-delete only (no tenant filter — access controlled via parent BugReport).</summary>
|
||||
@@ -2074,6 +2080,49 @@ modelBuilder.Entity<Job>()
|
||||
.HasIndex(c => new { c.CompanyId, c.MemoNumber })
|
||||
.IsUnique()
|
||||
.HasDatabaseName("IX_CreditMemos_CompanyId_MemoNumber");
|
||||
|
||||
// FormulaLibraryItem — platform-level, no tenant filter, no soft delete
|
||||
// Self-referential "Inspired by" FK uses NoAction; cascade nullification handled in service.
|
||||
modelBuilder.Entity<FormulaLibraryItem>()
|
||||
.HasOne(f => f.InspiredBy)
|
||||
.WithMany()
|
||||
.HasForeignKey(f => f.InspiredByFormulaLibraryItemId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
|
||||
modelBuilder.Entity<FormulaLibraryItem>()
|
||||
.HasIndex(f => f.SourceCompanyId)
|
||||
.HasDatabaseName("IX_FormulaLibraryItems_SourceCompanyId");
|
||||
|
||||
modelBuilder.Entity<FormulaLibraryItem>()
|
||||
.HasIndex(f => f.IsPublished)
|
||||
.HasDatabaseName("IX_FormulaLibraryItems_IsPublished");
|
||||
|
||||
// FormulaLibraryImport — tenant-scoped; unique per (CompanyId, FormulaLibraryItemId)
|
||||
modelBuilder.Entity<FormulaLibraryImport>()
|
||||
.HasOne(i => i.FormulaLibraryItem)
|
||||
.WithMany()
|
||||
.HasForeignKey(i => i.FormulaLibraryItemId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
modelBuilder.Entity<FormulaLibraryImport>()
|
||||
.HasOne(i => i.ResultingCustomItemTemplate)
|
||||
.WithMany()
|
||||
.HasForeignKey(i => i.ResultingCustomItemTemplateId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
modelBuilder.Entity<FormulaLibraryImport>()
|
||||
.HasIndex(i => new { i.CompanyId, i.FormulaLibraryItemId })
|
||||
.IsUnique()
|
||||
.HasDatabaseName("IX_FormulaLibraryImports_Company_Item");
|
||||
|
||||
// CustomItemTemplate → FormulaLibraryItem (nullable; only set on imported templates)
|
||||
modelBuilder.Entity<CustomItemTemplate>()
|
||||
.HasOne(t => t.SourceFormulaLibraryItem)
|
||||
.WithMany()
|
||||
.HasForeignKey(t => t.SourceFormulaLibraryItemId)
|
||||
.IsRequired(false)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user