Anonymous poll

This commit is contained in:
2025-09-07 23:22:34 +08:00
parent eaa3a9c297
commit fa01b7027a
6 changed files with 2204 additions and 4 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DysonNetwork.Sphere.Migrations
{
/// <inheritdoc />
public partial class AddPollAnonymousOrNot : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "is_anonymous",
table: "polls",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "is_anonymous",
table: "polls");
}
}
}

View File

@@ -395,6 +395,10 @@ namespace DysonNetwork.Sphere.Migrations
.HasColumnType("timestamp with time zone")
.HasColumnName("ended_at");
b.Property<bool>("IsAnonymous")
.HasColumnType("boolean")
.HasColumnName("is_anonymous");
b.Property<Guid>("PublisherId")
.HasColumnType("uuid")
.HasColumnName("publisher_id");

View File

@@ -2,6 +2,7 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using System.Text.Json.Serialization;
using DysonNetwork.Pass.Account;
using DysonNetwork.Shared.Data;
using NodaTime;
@@ -16,6 +17,7 @@ public class Poll : ModelBase
[MaxLength(4096)] public string? Description { get; set; }
public Instant? EndedAt { get; set; }
public bool IsAnonymous { get; set; }
public Guid PublisherId { get; set; }
[JsonIgnore] public Publisher.Publisher? Publisher { get; set; }
@@ -62,4 +64,5 @@ public class PollAnswer : ModelBase
public Guid AccountId { get; set; }
public Guid PollId { get; set; }
[JsonIgnore] public Poll? Poll { get; set; }
[NotMapped] public Account? Account { get; set; }
}

View File

@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using DysonNetwork.Shared.Proto;
using DysonNetwork.Shared.Registry;
using DysonNetwork.Sphere.Publisher;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@@ -11,7 +12,12 @@ namespace DysonNetwork.Sphere.Poll;
[ApiController]
[Route("/api/polls")]
public class PollController(AppDatabase db, PollService polls, Publisher.PublisherService pub) : ControllerBase
public class PollController(
AppDatabase db,
PollService polls,
Publisher.PublisherService pub,
AccountClientHelper accountsHelper
) : ControllerBase
{
[HttpGet("{id:guid}")]
public async Task<ActionResult<PollWithStats>> GetPoll(Guid id)
@@ -101,6 +107,20 @@ public class PollController(AppDatabase db, PollService polls, Publisher.Publish
.Take(take)
.ToListAsync();
if (!poll.IsAnonymous)
{
var answeredAccountsId = answers.Select(x => x.AccountId).Distinct().ToList();
var answeredAccounts = await accountsHelper.GetAccountBatch(answeredAccountsId);
// Populate Account field for each answer
foreach (var answer in answers)
{
var protoValue = answeredAccounts.FirstOrDefault(a => a.Id == answer.AccountId.ToString());
if (protoValue is not null)
answer.Account = Pass.Account.Account.FromProtoValue(protoValue);
}
}
return Ok(answers);
}
@@ -148,6 +168,7 @@ public class PollController(AppDatabase db, PollService polls, Publisher.Publish
public string? Title { get; set; }
public string? Description { get; set; }
public Instant? EndedAt { get; set; }
public bool? IsAnonymous { get; set; }
public List<PollRequestQuestion>? Questions { get; set; }
}
@@ -194,6 +215,7 @@ public class PollController(AppDatabase db, PollService polls, Publisher.Publish
Title = request.Title,
Description = request.Description,
EndedAt = request.EndedAt,
IsAnonymous = request.IsAnonymous ?? false,
PublisherId = publisher.Id,
Questions = request.Questions.Select(q => q.ToQuestion()).ToList()
};
@@ -238,6 +260,7 @@ public class PollController(AppDatabase db, PollService polls, Publisher.Publish
if (request.Title != null) poll.Title = request.Title;
if (request.Description != null) poll.Description = request.Description;
if (request.EndedAt.HasValue) poll.EndedAt = request.EndedAt;
if (request.IsAnonymous.HasValue) poll.IsAnonymous = request.IsAnonymous.Value;
db.Update(poll);
await db.SaveChangesAsync();

View File

@@ -75,7 +75,7 @@ public class PollService(AppDatabase db, ICacheService cache)
var questionId = question.Id.ToString();
if (question.IsRequired && !answer.ContainsKey(questionId))
throw new Exception($"Missing required field: {question.Title}");
else if (!answer.ContainsKey(questionId))
if (!answer.ContainsKey(questionId))
continue;
switch (question.Type)
{
@@ -269,7 +269,7 @@ public class PollService(AppDatabase db, ICacheService cache)
await cache.SetWithGroupsAsync(
cacheKey,
stats,
new[] { PollCacheGroupPrefix + question.PollId },
[PollCacheGroupPrefix + question.PollId],
TimeSpan.FromHours(1));
return stats;