✨ Sticker pack ownerships
This commit is contained in:
@@ -59,6 +59,7 @@ public class AppDatabase(
|
|||||||
|
|
||||||
public DbSet<Sticker.Sticker> Stickers { get; set; }
|
public DbSet<Sticker.Sticker> Stickers { get; set; }
|
||||||
public DbSet<StickerPack> StickerPacks { get; set; }
|
public DbSet<StickerPack> StickerPacks { get; set; }
|
||||||
|
public DbSet<StickerPackOwnership> StickerPackOwnerships { get; set; }
|
||||||
|
|
||||||
public DbSet<CustomApp> CustomApps { get; set; }
|
public DbSet<CustomApp> CustomApps { get; set; }
|
||||||
public DbSet<CustomAppSecret> CustomAppSecrets { get; set; }
|
public DbSet<CustomAppSecret> CustomAppSecrets { get; set; }
|
||||||
|
2126
DysonNetwork.Sphere/Migrations/20250805183629_AddStickerOwnerships.Designer.cs
generated
Normal file
2126
DysonNetwork.Sphere/Migrations/20250805183629_AddStickerOwnerships.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using NodaTime;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DysonNetwork.Sphere.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddStickerOwnerships : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "sticker_pack_ownerships",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
pack_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||||
|
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_sticker_pack_ownerships", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_sticker_pack_ownerships_sticker_packs_pack_id",
|
||||||
|
column: x => x.pack_id,
|
||||||
|
principalTable: "sticker_packs",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_sticker_pack_ownerships_pack_id",
|
||||||
|
table: "sticker_pack_ownerships",
|
||||||
|
column: "pack_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "sticker_pack_ownerships");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1427,6 +1427,42 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.ToTable("sticker_packs", (string)null);
|
b.ToTable("sticker_packs", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DysonNetwork.Sphere.Sticker.StickerPackOwnership", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<Guid>("AccountId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("account_id");
|
||||||
|
|
||||||
|
b.Property<Instant>("CreatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at");
|
||||||
|
|
||||||
|
b.Property<Instant?>("DeletedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("deleted_at");
|
||||||
|
|
||||||
|
b.Property<Guid>("PackId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("pack_id");
|
||||||
|
|
||||||
|
b.Property<Instant>("UpdatedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_sticker_pack_ownerships");
|
||||||
|
|
||||||
|
b.HasIndex("PackId")
|
||||||
|
.HasDatabaseName("ix_sticker_pack_ownerships_pack_id");
|
||||||
|
|
||||||
|
b.ToTable("sticker_pack_ownerships", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Sphere.WebReader.WebArticle", b =>
|
modelBuilder.Entity("DysonNetwork.Sphere.WebReader.WebArticle", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
@@ -1910,7 +1946,7 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
modelBuilder.Entity("DysonNetwork.Sphere.Sticker.Sticker", b =>
|
modelBuilder.Entity("DysonNetwork.Sphere.Sticker.Sticker", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("DysonNetwork.Sphere.Sticker.StickerPack", "Pack")
|
b.HasOne("DysonNetwork.Sphere.Sticker.StickerPack", "Pack")
|
||||||
.WithMany()
|
.WithMany("Stickers")
|
||||||
.HasForeignKey("PackId")
|
.HasForeignKey("PackId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
@@ -1931,6 +1967,18 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.Navigation("Publisher");
|
b.Navigation("Publisher");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DysonNetwork.Sphere.Sticker.StickerPackOwnership", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("DysonNetwork.Sphere.Sticker.StickerPack", "Pack")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PackId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_sticker_pack_ownerships_sticker_packs_pack_id");
|
||||||
|
|
||||||
|
b.Navigation("Pack");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Sphere.WebReader.WebArticle", b =>
|
modelBuilder.Entity("DysonNetwork.Sphere.WebReader.WebArticle", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("DysonNetwork.Sphere.WebReader.WebFeed", "Feed")
|
b.HasOne("DysonNetwork.Sphere.WebReader.WebFeed", "Feed")
|
||||||
@@ -2060,6 +2108,11 @@ namespace DysonNetwork.Sphere.Migrations
|
|||||||
b.Navigation("RealmTags");
|
b.Navigation("RealmTags");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("DysonNetwork.Sphere.Sticker.StickerPack", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Stickers");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("DysonNetwork.Sphere.WebReader.WebFeed", b =>
|
modelBuilder.Entity("DysonNetwork.Sphere.WebReader.WebFeed", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("Articles");
|
b.Navigation("Articles");
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using DysonNetwork.Pass.Account;
|
||||||
using DysonNetwork.Shared.Data;
|
using DysonNetwork.Shared.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
@@ -13,11 +15,11 @@ public class Sticker : ModelBase, IIdentifiedResource
|
|||||||
|
|
||||||
// Outdated fields, for backward compability
|
// Outdated fields, for backward compability
|
||||||
[MaxLength(32)] public string? ImageId { get; set; }
|
[MaxLength(32)] public string? ImageId { get; set; }
|
||||||
|
|
||||||
[Column(TypeName = "jsonb")] public CloudFileReferenceObject? Image { get; set; } = null!;
|
[Column(TypeName = "jsonb")] public CloudFileReferenceObject? Image { get; set; } = null!;
|
||||||
|
|
||||||
public Guid PackId { get; set; }
|
public Guid PackId { get; set; }
|
||||||
public StickerPack Pack { get; set; } = null!;
|
[JsonIgnore] public StickerPack Pack { get; set; } = null!;
|
||||||
|
|
||||||
public string ResourceIdentifier => $"sticker:{Id}";
|
public string ResourceIdentifier => $"sticker:{Id}";
|
||||||
}
|
}
|
||||||
@@ -29,8 +31,19 @@ public class StickerPack : ModelBase
|
|||||||
[MaxLength(1024)] public string Name { get; set; } = null!;
|
[MaxLength(1024)] public string Name { get; set; } = null!;
|
||||||
[MaxLength(4096)] public string Description { get; set; } = string.Empty;
|
[MaxLength(4096)] public string Description { get; set; } = string.Empty;
|
||||||
[MaxLength(128)] public string Prefix { get; set; } = null!;
|
[MaxLength(128)] public string Prefix { get; set; } = null!;
|
||||||
|
|
||||||
|
public List<Sticker> Stickers { get; set; } = new();
|
||||||
|
|
||||||
public Guid PublisherId { get; set; }
|
public Guid PublisherId { get; set; }
|
||||||
public Publisher.Publisher Publisher { get; set; } = null!;
|
public Publisher.Publisher Publisher { get; set; } = null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class StickerPackOwnership : ModelBase
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
|
||||||
|
public Guid PackId { get; set; }
|
||||||
|
public StickerPack Pack { get; set; } = null!;
|
||||||
|
public Guid AccountId { get; set; }
|
||||||
|
[NotMapped] public Account Account { get; set; } = null!;
|
||||||
|
}
|
||||||
|
@@ -3,6 +3,7 @@ using DysonNetwork.Shared.Auth;
|
|||||||
using DysonNetwork.Shared.Data;
|
using DysonNetwork.Shared.Data;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using DysonNetwork.Sphere.Publisher;
|
using DysonNetwork.Sphere.Publisher;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
@@ -61,6 +62,25 @@ public class StickerController(AppDatabase db, StickerService st, FileService.Fi
|
|||||||
return Ok(packs);
|
return Ok(packs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("me")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult<List<StickerPackOwnership>>> ListStickerPacksOwned()
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||||
|
var accountId = Guid.Parse(currentUser.Id);
|
||||||
|
|
||||||
|
var ownershipsId = await db.StickerPackOwnerships
|
||||||
|
.Where(p => p.AccountId == accountId)
|
||||||
|
.Select(p => p.PackId)
|
||||||
|
.ToListAsync();
|
||||||
|
var packs = await db.StickerPacks
|
||||||
|
.Where(p => ownershipsId.Contains(p.Id))
|
||||||
|
.Include(p => p.Stickers)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Ok(packs);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("{id:guid}")]
|
[HttpGet("{id:guid}")]
|
||||||
public async Task<ActionResult<StickerPack>> GetStickerPack(Guid id)
|
public async Task<ActionResult<StickerPack>> GetStickerPack(Guid id)
|
||||||
{
|
{
|
||||||
@@ -318,4 +338,46 @@ public class StickerController(AppDatabase db, StickerService st, FileService.Fi
|
|||||||
sticker = await st.CreateStickerAsync(sticker);
|
sticker = await st.CreateStickerAsync(sticker);
|
||||||
return Ok(sticker);
|
return Ok(sticker);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
[HttpPost("{packId:guid}/own")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult<StickerPackOwnership>> AcquireStickerPack([FromRoute] Guid packId)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
var pack = await db.StickerPacks
|
||||||
|
.Where(p => p.Id == packId)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
if (pack is null) return NotFound();
|
||||||
|
|
||||||
|
var ownership = new StickerPackOwnership
|
||||||
|
{
|
||||||
|
PackId = packId,
|
||||||
|
AccountId = Guid.Parse(currentUser.Id)
|
||||||
|
};
|
||||||
|
db.StickerPackOwnerships.Add(ownership);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(ownership);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{packId:guid}/own")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<IActionResult> ReleaseStickerPack([FromRoute] Guid packId)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not Account currentUser)
|
||||||
|
return Unauthorized();
|
||||||
|
var accountId = Guid.Parse(currentUser.Id);
|
||||||
|
|
||||||
|
var ownership = await db.StickerPackOwnerships
|
||||||
|
.Where(p => p.PackId == packId && p.AccountId == accountId)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
if (ownership is null) return NotFound();
|
||||||
|
|
||||||
|
db.Remove(ownership);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user