feat(guild_chat): post text + stamp
Implements PostTextOrStampAsync: validates membership (NotInGuild), validates stamp id against UsableStampList (PermissionDenied), rejects type other than 0 or 1, allocates next per-guild message_id, appends row. Wires /guild_chat/post controller action mapping failures to result_code=2. Response is GuildChatPostResponse (empty body per spec). 7 integration tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -65,10 +65,38 @@ public sealed class GuildChatService : IGuildChatService
|
||||
return new(msgs, wait);
|
||||
}
|
||||
|
||||
// ── Not-yet-implemented stubs ────────────────────────────────────────────
|
||||
// ── Post text / stamp ────────────────────────────────────────────────────
|
||||
|
||||
public Task<ChatPostResult> PostTextOrStampAsync(long viewerId, int type, string message, CancellationToken ct = default)
|
||||
=> throw new NotImplementedException();
|
||||
public async Task<ChatPostResult> PostTextOrStampAsync(long viewerId, int type, string message, CancellationToken ct = default)
|
||||
{
|
||||
var m = await _members.GetMembershipAsync(viewerId, ct);
|
||||
if (m is null) return new(false, null);
|
||||
|
||||
var cfg = _cfg.Get<GuildConfig>();
|
||||
if (type == 1)
|
||||
{
|
||||
if (!int.TryParse(message, out var stampId) || !cfg.UsableStampList.Contains(stampId))
|
||||
return new(false, null);
|
||||
}
|
||||
else if (type != 0)
|
||||
{
|
||||
// Only NORMAL (0) and STAMP (1) are valid via this endpoint.
|
||||
return new(false, null);
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var nextId = await _msgs.GetMaxMessageIdAsync(m.GuildId, ct) + 1;
|
||||
var stored = await _msgs.AppendAsync(new GuildChatMessage
|
||||
{
|
||||
GuildId = m.GuildId,
|
||||
MessageId = nextId,
|
||||
AuthorViewerId = viewerId,
|
||||
MessageType = type == 1 ? GuildChatMessageType.Stamp : GuildChatMessageType.Normal,
|
||||
Body = message,
|
||||
CreatedAt = now,
|
||||
}, ct);
|
||||
return new(true, stored.MessageId);
|
||||
}
|
||||
|
||||
public Task<ChatPostResult> PostDeckAsync(long viewerId, string deckPayloadJson, CancellationToken ct = default)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
Reference in New Issue
Block a user