♻️ Simplified publisher subscription

This commit is contained in:
2026-01-12 00:52:48 +08:00
parent bd41568578
commit ed7d54c47a
7 changed files with 1850 additions and 49 deletions

View File

@@ -194,13 +194,6 @@ public class SnPublisherMember : ModelBase
} }
} }
public enum PublisherSubscriptionStatus
{
Active,
Expired,
Cancelled
}
public class SnPublisherSubscription : ModelBase public class SnPublisherSubscription : ModelBase
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
@@ -208,9 +201,6 @@ public class SnPublisherSubscription : ModelBase
public Guid PublisherId { get; set; } public Guid PublisherId { get; set; }
public SnPublisher Publisher { get; set; } = null!; public SnPublisher Publisher { get; set; } = null!;
public Guid AccountId { get; set; } public Guid AccountId { get; set; }
public PublisherSubscriptionStatus Status { get; set; } = PublisherSubscriptionStatus.Active;
public int Tier { get; set; } = 0;
} }
public class SnPublisherFeature : ModelBase public class SnPublisherFeature : ModelBase

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DysonNetwork.Sphere.Migrations
{
/// <inheritdoc />
public partial class RemoveSubscriptionTierAndStatus : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "status",
table: "publisher_subscriptions");
migrationBuilder.DropColumn(
name: "tier",
table: "publisher_subscriptions");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "status",
table: "publisher_subscriptions",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "tier",
table: "publisher_subscriptions",
type: "integer",
nullable: false,
defaultValue: 0);
}
}
}

View File

@@ -649,7 +649,8 @@ namespace DysonNetwork.Sphere.Migrations
b.Property<Dictionary<string, object>>("Metadata") b.Property<Dictionary<string, object>>("Metadata")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("metadata"); .HasColumnName("metadata")
.HasJsonPropertyName("meta");
b.Property<int?>("PinMode") b.Property<int?>("PinMode")
.HasColumnType("integer") .HasColumnType("integer")
@@ -1234,14 +1235,6 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("uuid") .HasColumnType("uuid")
.HasColumnName("publisher_id"); .HasColumnName("publisher_id");
b.Property<int>("Status")
.HasColumnType("integer")
.HasColumnName("status");
b.Property<int>("Tier")
.HasColumnType("integer")
.HasColumnName("tier");
b.Property<Instant>("UpdatedAt") b.Property<Instant>("UpdatedAt")
.HasColumnType("timestamp with time zone") .HasColumnType("timestamp with time zone")
.HasColumnName("updated_at"); .HasColumnName("updated_at");

View File

@@ -138,7 +138,6 @@ public class PublisherService(
// If not in cache, fetch from a database // If not in cache, fetch from a database
var publishersId = await db.PublisherSubscriptions var publishersId = await db.PublisherSubscriptions
.Where(p => p.AccountId == userId) .Where(p => p.AccountId == userId)
.Where(p => p.Status == PublisherSubscriptionStatus.Active)
.Select(p => p.PublisherId) .Select(p => p.PublisherId)
.ToListAsync(); .ToListAsync();
publishers = await db.Publishers publishers = await db.Publishers

View File

@@ -17,7 +17,6 @@ public class PublisherSubscriptionController(
{ {
public class SubscribeRequest public class SubscribeRequest
{ {
public int? Tier { get; set; }
} }
[HttpGet("{name}/subscription")] [HttpGet("{name}/subscription")]
@@ -53,8 +52,7 @@ public class PublisherSubscriptionController(
{ {
var subscription = await subs.CreateSubscriptionAsync( var subscription = await subs.CreateSubscriptionAsync(
Guid.Parse(currentUser.Id), Guid.Parse(currentUser.Id),
publisher.Id, publisher.Id
request.Tier ?? 0
); );
return subscription; return subscription;
@@ -101,7 +99,7 @@ public class PublisherSubscriptionController(
var pubQuery = db.PublisherSubscriptions var pubQuery = db.PublisherSubscriptions
.Include(ps => ps.Publisher) .Include(ps => ps.Publisher)
.Where(ps => ps.AccountId == accountId && ps.Status == PublisherSubscriptionStatus.Active) .Where(ps => ps.AccountId == accountId)
.OrderByDescending(ps => ps.CreatedAt) .OrderByDescending(ps => ps.CreatedAt)
.AsQueryable(); .AsQueryable();

View File

@@ -27,8 +27,7 @@ public class PublisherSubscriptionService(
{ {
return await db.PublisherSubscriptions return await db.PublisherSubscriptions
.AnyAsync(p => p.AccountId == accountId && .AnyAsync(p => p.AccountId == accountId &&
p.PublisherId == publisherId && p.PublisherId == publisherId);
p.Status == PublisherSubscriptionStatus.Active);
} }
/// <summary> /// <summary>
@@ -77,8 +76,7 @@ public class PublisherSubscriptionService(
// Gather subscribers // Gather subscribers
var subscribers = await db.PublisherSubscriptions var subscribers = await db.PublisherSubscriptions
.Where(p => p.PublisherId == post.PublisherId && .Where(p => p.PublisherId == post.PublisherId)
p.Status == PublisherSubscriptionStatus.Active)
.ToListAsync(); .ToListAsync();
if (subscribers.Count == 0) if (subscribers.Count == 0)
return 0; return 0;
@@ -150,7 +148,7 @@ public class PublisherSubscriptionService(
{ {
return await db.PublisherSubscriptions return await db.PublisherSubscriptions
.Include(p => p.Publisher) .Include(p => p.Publisher)
.Where(p => p.AccountId == accountId && p.Status == PublisherSubscriptionStatus.Active) .Where(p => p.AccountId == accountId)
.ToListAsync(); .ToListAsync();
} }
@@ -163,7 +161,6 @@ public class PublisherSubscriptionService(
{ {
return await db.PublisherSubscriptions return await db.PublisherSubscriptions
.Where(p => p.PublisherId == publisherId) .Where(p => p.PublisherId == publisherId)
.Where(p => p.Status == PublisherSubscriptionStatus.Active)
.ToListAsync(); .ToListAsync();
} }
@@ -172,37 +169,23 @@ public class PublisherSubscriptionService(
/// </summary> /// </summary>
/// <param name="accountId">The account ID</param> /// <param name="accountId">The account ID</param>
/// <param name="publisherId">The publisher ID</param> /// <param name="publisherId">The publisher ID</param>
/// <param name="tier">Optional subscription tier</param>
/// <returns>The created subscription</returns> /// <returns>The created subscription</returns>
public async Task<SnPublisherSubscription> CreateSubscriptionAsync( public async Task<SnPublisherSubscription> CreateSubscriptionAsync(
Guid accountId, Guid accountId,
Guid publisherId, Guid publisherId
int tier = 0
) )
{ {
// Check if a subscription already exists // Check if a subscription already exists
var existingSubscription = await GetSubscriptionAsync(accountId, publisherId); var existingSubscription = await GetSubscriptionAsync(accountId, publisherId);
if (existingSubscription != null) if (existingSubscription != null)
{
// If it exists but is not active, reactivate it
if (existingSubscription.Status == PublisherSubscriptionStatus.Active) return existingSubscription;
existingSubscription.Status = PublisherSubscriptionStatus.Active;
existingSubscription.Tier = tier;
await db.SaveChangesAsync();
return existingSubscription; return existingSubscription;
// If it's already active, just return it
}
// Create a new subscription // Create a new subscription
var subscription = new SnPublisherSubscription var subscription = new SnPublisherSubscription
{ {
AccountId = accountId, AccountId = accountId,
PublisherId = publisherId, PublisherId = publisherId,
Status = PublisherSubscriptionStatus.Active,
Tier = tier,
}; };
db.PublisherSubscriptions.Add(subscription); db.PublisherSubscriptions.Add(subscription);
@@ -214,18 +197,18 @@ public class PublisherSubscriptionService(
} }
/// <summary> /// <summary>
/// Cancels a subscription /// Deletes a subscription
/// </summary> /// </summary>
/// <param name="accountId">The account ID</param> /// <param name="accountId">The account ID</param>
/// <param name="publisherId">The publisher ID</param> /// <param name="publisherId">The publisher ID</param>
/// <returns>True if the subscription was cancelled, false if it wasn't found</returns> /// <returns>True if the subscription was deleted, false if it wasn't found</returns>
public async Task<bool> CancelSubscriptionAsync(Guid accountId, Guid publisherId) public async Task<bool> CancelSubscriptionAsync(Guid accountId, Guid publisherId)
{ {
var subscription = await GetSubscriptionAsync(accountId, publisherId); var subscription = await GetSubscriptionAsync(accountId, publisherId);
if (subscription is not { Status: PublisherSubscriptionStatus.Active }) if (subscription is null)
return false; return false;
subscription.Status = PublisherSubscriptionStatus.Cancelled; db.PublisherSubscriptions.Remove(subscription);
await db.SaveChangesAsync(); await db.SaveChangesAsync();
await cache.RemoveAsync(string.Format(PublisherService.SubscribedPublishersCacheKey, accountId)); await cache.RemoveAsync(string.Format(PublisherService.SubscribedPublishersCacheKey, accountId));