Created Woodpecker CI/CD deployment
All checks were successful
ci/woodpecker/tag/api_build Pipeline was successful
ci/woodpecker/tag/api_uploadimage Pipeline was successful
ci/woodpecker/tag/web_uploadimage Pipeline was successful

- Created Dockerfile for packing up API and Web projects as Docker image
This commit is contained in:
2023-03-27 21:48:25 -05:00
parent baf38aa3cd
commit 9bbd12e4c3
145 changed files with 30955 additions and 18248 deletions

View File

@ -0,0 +1,67 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using YABA.Models;
using YABA.Models.Interfaces;
namespace YABA.Data.Context
{
public class YABABaseContext : DbContext
{
public YABABaseContext() : base() { }
public YABABaseContext(DbContextOptions<YABABaseContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Add lookup backed data here
// SAMPLE
// var lookupBackedData = Enum.GetValues(typeof(LookupEnum)).Cast<LookupEnum>();
// modelBuilder.Entity<LookupModel>().HasData(lookupBackedData.Select(x => new LookupModel(x)));
modelBuilder.Model.GetEntityTypes()
.Where(entityType => typeof(ISoftDeletable).IsAssignableFrom(entityType.ClrType))
.ToList()
.ForEach(entityType =>
{
modelBuilder.Entity(entityType.ClrType)
.HasQueryFilter(ConvertFilterExpression<ISoftDeletable>(e => !e.IsDeleted, entityType.ClrType));
});
modelBuilder.Entity<BookmarkTag>()
.HasKey(x => new { x.BookmarkId, x.TagId });
modelBuilder.Entity<User>()
.HasIndex(x => x.Auth0Id)
.IsUnique();
modelBuilder.Entity<Tag>()
.HasIndex(x => new { x.Name, x.UserId })
.IsUnique();
modelBuilder.Entity<Bookmark>()
.HasIndex(x => new { x.Url, x.UserId })
.IsUnique();
}
public virtual DbSet<Bookmark> Bookmarks { get; set; }
public virtual DbSet<Tag> Tags { get; set; }
public virtual DbSet<BookmarkTag> BookmarkTags { get; set; }
public virtual DbSet<User> Users { get; set; }
private static LambdaExpression ConvertFilterExpression<TInterface>(
Expression<Func<TInterface, bool>> filterExpression,
Type entityType)
{
// SOURCE: https://stackoverflow.com/questions/47673524/ef-core-soft-delete-with-shadow-properties-and-query-filters/48744644#48744644
var newParam = Expression.Parameter(entityType);
var newBody = ReplacingExpressionVisitor.Replace(filterExpression.Parameters.Single(), newParam, filterExpression.Body);
return Expression.Lambda(newBody, newParam);
}
}
}

View File

@ -0,0 +1,18 @@

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
namespace YABA.Data.Context
{
public class YABABaseContextFactory : IDesignTimeDbContextFactory<YABABaseContext>
{
public YABABaseContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<YABABaseContext>();
optionsBuilder.UseNpgsql(args[0])
.UseSnakeCaseNamingConvention()
.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);
return new YABABaseContext(optionsBuilder.Options);
}
}
}

View File

@ -0,0 +1,13 @@
using Microsoft.EntityFrameworkCore;
namespace YABA.Data.Context
{
public class YABAReadOnlyContext : YABABaseContext
{
public YABAReadOnlyContext() : base() { }
public YABAReadOnlyContext(DbContextOptions<YABABaseContext> options) : base(options)
{
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
}
}

View File

@ -0,0 +1,57 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using YABA.Models.Interfaces;
namespace YABA.Data.Context
{
public class YABAReadWriteContext : YABABaseContext
{
public YABAReadWriteContext() : base() { }
public YABAReadWriteContext(DbContextOptions<YABABaseContext> options) : base(options)
{
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;
}
public override int SaveChanges()
{
var dateCreatedTrackableEntries = ChangeTracker
.Entries()
.Where(e => e.Entity is IDateCreatedTrackable && e.State == EntityState.Added);
foreach (var entry in dateCreatedTrackableEntries)
((IDateCreatedTrackable)entry.Entity).CreatedOn = DateTimeOffset.UtcNow;
var dateModifiedTrackableItems = ChangeTracker
.Entries()
.Where(e => e.Entity is IDateModifiedTrackable && (e.State == EntityState.Modified || e.State == EntityState.Added));
foreach (var entry in dateModifiedTrackableItems)
((IDateModifiedTrackable)entry.Entity).LastModified = DateTimeOffset.UtcNow;
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
var dateCreatedTrackableEntries = ChangeTracker
.Entries()
.Where(e => e.Entity is IDateCreatedTrackable && e.State == EntityState.Added);
foreach (var entry in dateCreatedTrackableEntries)
((IDateCreatedTrackable)entry.Entity).CreatedOn = DateTimeOffset.UtcNow;
var dateModifiedTrackableItems = ChangeTracker
.Entries()
.Where(e => e.Entity is IDateModifiedTrackable && (e.State == EntityState.Modified || e.State == EntityState.Added));
foreach (var entry in dateModifiedTrackableItems)
((IDateModifiedTrackable)entry.Entity).LastModified = DateTimeOffset.UtcNow;
return base.SaveChangesAsync(cancellationToken);
}
}
}