feat(postit): migrate editable profile data and admin profile flow
This commit is contained in:
parent
f8c2a01ef4
commit
af1e572f32
38 changed files with 6573 additions and 19 deletions
54
src/Yavsc.Server/Helpers/ResourceUsageTelemetryMiddleware.cs
Normal file
54
src/Yavsc.Server/Helpers/ResourceUsageTelemetryMiddleware.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#nullable enable
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Server.Helpers;
|
||||
|
||||
public sealed class ResourceUsageTelemetryMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public ResourceUsageTelemetryMiddleware(
|
||||
RequestDelegate next,
|
||||
IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_next = next;
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
var userId = context.User.GetUserId();
|
||||
if (string.IsNullOrWhiteSpace(userId))
|
||||
{
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
var userName = context.User.Identity?.Name ?? userId;
|
||||
var requestBytes = context.Request.ContentLength ?? 0L;
|
||||
|
||||
try
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
finally
|
||||
{
|
||||
var responseBytes = context.Response.ContentLength ?? 0L;
|
||||
var totalBytes = requestBytes + responseBytes;
|
||||
var bandwidthMb = totalBytes <= 0 ? 0m : (decimal)totalBytes / (1024m * 1024m);
|
||||
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
await ResourceUsageTracker.RecordAsync(
|
||||
db,
|
||||
userId,
|
||||
userName,
|
||||
apiCalls: 1m,
|
||||
bandwidthMb: bandwidthMb,
|
||||
actorUserId: userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/Yavsc.Server/Helpers/ResourceUsageTracker.cs
Normal file
69
src/Yavsc.Server/Helpers/ResourceUsageTracker.cs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#nullable enable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Server.Helpers;
|
||||
|
||||
public static class ResourceUsageTracker
|
||||
{
|
||||
public static async Task RecordAsync(
|
||||
ApplicationDbContext dbContext,
|
||||
string userId,
|
||||
string userName,
|
||||
decimal cpuSeconds = 0m,
|
||||
long storageBytes = 0,
|
||||
decimal apiCalls = 0m,
|
||||
decimal bandwidthMb = 0m,
|
||||
string? actorUserId = null,
|
||||
string currency = Constants.ResourceUsageDefaultCurrency)
|
||||
{
|
||||
if (dbContext is null || string.IsNullOrWhiteSpace(userId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var effectiveActor = string.IsNullOrWhiteSpace(actorUserId) ? userId : actorUserId;
|
||||
var now = DateTime.UtcNow;
|
||||
var storageMb = storageBytes <= 0 ? 0m : (decimal)storageBytes / (1024m * 1024m);
|
||||
|
||||
var record = await dbContext.ResourceUsageRecords
|
||||
.Where(r => r.UserId == userId)
|
||||
.OrderByDescending(r => r.RecordedAtUtc)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (record is null)
|
||||
{
|
||||
record = new ResourceUsageRecord
|
||||
{
|
||||
UserId = userId,
|
||||
UserName = string.IsNullOrWhiteSpace(userName) ? userId : userName,
|
||||
RecordedAtUtc = now,
|
||||
ApiCalls = apiCalls,
|
||||
CpuSeconds = cpuSeconds,
|
||||
BandwidthMb = bandwidthMb,
|
||||
StorageMb = storageMb,
|
||||
EstimatedCompensation = 0m,
|
||||
Currency = currency,
|
||||
UserCreated = effectiveActor,
|
||||
UserModified = effectiveActor,
|
||||
DateCreated = now,
|
||||
DateModified = now,
|
||||
};
|
||||
dbContext.ResourceUsageRecords.Add(record);
|
||||
await dbContext.SaveChangesAsync(effectiveActor);
|
||||
return;
|
||||
}
|
||||
|
||||
record.UserName = string.IsNullOrWhiteSpace(userName) ? record.UserName : userName;
|
||||
record.RecordedAtUtc = now;
|
||||
record.ApiCalls += apiCalls;
|
||||
record.CpuSeconds += cpuSeconds;
|
||||
record.BandwidthMb += bandwidthMb;
|
||||
record.StorageMb += storageMb;
|
||||
record.Currency = string.IsNullOrWhiteSpace(currency) ? record.Currency : currency;
|
||||
record.DateModified = now;
|
||||
record.UserModified = effectiveActor;
|
||||
|
||||
await dbContext.SaveChangesAsync(effectiveActor);
|
||||
}
|
||||
}
|
||||
|
|
@ -58,6 +58,14 @@ namespace Yavsc.Models
|
|||
}
|
||||
builder.UseIdentityByDefaultColumns();
|
||||
|
||||
builder.Entity<ResourceUsageRecord>(entity =>
|
||||
{
|
||||
entity.HasKey(r => r.Id);
|
||||
entity.HasIndex(r => new { r.UserId, r.RecordedAtUtc });
|
||||
entity.Property(r => r.Currency).HasMaxLength(8).HasDefaultValue(Constants.ResourceUsageDefaultCurrency);
|
||||
entity.Property(r => r.UserName).HasMaxLength(256);
|
||||
});
|
||||
|
||||
// Customize the ASP.NET Identity model and override the defaults if needed.
|
||||
// For example, you can rename the ASP.NET Identity table names and more.
|
||||
// Add your customizations after calling base.OnModelCreating(builder);
|
||||
|
|
@ -324,6 +332,7 @@ namespace Yavsc.Models
|
|||
|
||||
public DbSet<Estimate> Estimates { get; set; }
|
||||
public DbSet<Signature> Signatures { get; set; }
|
||||
public DbSet<ResourceUsageRecord> ResourceUsageRecords { get; set; }
|
||||
public DbSet<AccountBalance> BankStatus { get; set; }
|
||||
public DbSet<BalanceImpact> BalanceImpact { get; set; }
|
||||
|
||||
|
|
|
|||
36
src/Yavsc.Server/Models/ResourceUsageRecord.cs
Normal file
36
src/Yavsc.Server/Models/ResourceUsageRecord.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models;
|
||||
|
||||
public sealed class ResourceUsageRecord : ITrackedEntity
|
||||
{
|
||||
[Key]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(256)]
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[MaxLength(256)]
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public DateTime RecordedAtUtc { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public decimal ApiCalls { get; set; }
|
||||
public decimal CpuSeconds { get; set; }
|
||||
public decimal BandwidthMb { get; set; }
|
||||
public decimal StorageMb { get; set; }
|
||||
public decimal EstimatedCompensation { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(8)]
|
||||
public string Currency { get; set; } = Constants.ResourceUsageDefaultCurrency;
|
||||
|
||||
public DateTime DateCreated { get; set; } = DateTime.UtcNow;
|
||||
public string UserCreated { get; set; } = string.Empty;
|
||||
public DateTime DateModified { get; set; } = DateTime.UtcNow;
|
||||
public string UserModified { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ using Yavsc.Abstract.Identity;
|
|||
namespace Yavsc.Models.Auth
|
||||
{
|
||||
public class Me : IApplicationUser {
|
||||
public Me(string userId, string userName, string email, string avatar, ILocation address, string gCalId)
|
||||
public Me(string userId, string userName, string email, string avatar, ILocation address, string gCalId, string? fullName = null)
|
||||
{
|
||||
Id = userId;
|
||||
UserName = userName;
|
||||
|
|
@ -11,10 +11,14 @@ namespace Yavsc.Models.Auth
|
|||
Avatar = avatar;
|
||||
PostalAddress = address;
|
||||
DedicatedGoogleCalendar = gCalId;
|
||||
FullName = fullName ?? string.Empty;
|
||||
Address = address?.Address ?? string.Empty;
|
||||
}
|
||||
public string Id { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string FullName { get; set; }
|
||||
public string EMail { get; set; }
|
||||
public string Address { get; set; }
|
||||
public string[] Roles { get; set; }
|
||||
/// <summary>
|
||||
/// Known as profile, could point to an avatar
|
||||
|
|
@ -24,18 +28,18 @@ namespace Yavsc.Models.Auth
|
|||
|
||||
public IAccountBalance AccountBalance
|
||||
{
|
||||
get; set;
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string DedicatedGoogleCalendar
|
||||
{
|
||||
get; set;
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ILocation PostalAddress
|
||||
{
|
||||
get; set;
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue