Implement step 17 modules: threads/messages, notifications with automation (submission.created, idea.created, grant_call.opened), innovation test feedback, admin panel (submissions, verify, metrics, grant call status), Middleman adaptation and partnerships. Split multi-type files into one type per file and replace object-valued dictionaries with string-valued maps in data contracts (migrations 0006/0007).
102 lines
2.8 KiB
C#
102 lines
2.8 KiB
C#
using Asp.Versioning;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using TarninaHub.Application.Abstractions;
|
|
using TarninaHub.Application.Dtos;
|
|
using TarninaHub.Application.Security;
|
|
|
|
namespace TarninaHub.Controllers;
|
|
|
|
[ApiController]
|
|
[ApiVersion("1.0")]
|
|
[Route("api/threads")]
|
|
[Authorize]
|
|
public class ThreadsController : ControllerBase
|
|
{
|
|
private readonly IThreadService _threads;
|
|
|
|
public ThreadsController(IThreadService threads)
|
|
{
|
|
_threads = threads;
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<ActionResult<IReadOnlyList<ThreadResponse>>> List(CancellationToken cancellationToken)
|
|
{
|
|
var userId = RequireUserId(out var unauthorized);
|
|
|
|
if (unauthorized is not null)
|
|
{
|
|
return unauthorized;
|
|
}
|
|
|
|
var threads = await _threads.ListForUserAsync(userId, IsStaff(), cancellationToken);
|
|
|
|
return Ok(threads);
|
|
}
|
|
|
|
[HttpPost]
|
|
public async Task<ActionResult<ThreadResponse>> Create(
|
|
CreateThreadRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var userId = RequireUserId(out var unauthorized);
|
|
|
|
if (unauthorized is not null)
|
|
{
|
|
return unauthorized;
|
|
}
|
|
|
|
var created = await _threads.CreateAsync(userId, request, cancellationToken);
|
|
|
|
return CreatedAtAction(nameof(GetById), new { threadId = created.Id }, created);
|
|
}
|
|
|
|
[HttpGet("{threadId}")]
|
|
public async Task<ActionResult<ThreadResponse>> GetById(
|
|
string threadId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var userId = RequireUserId(out var unauthorized);
|
|
|
|
if (unauthorized is not null)
|
|
{
|
|
return unauthorized;
|
|
}
|
|
|
|
var thread = await _threads.GetAsync(threadId, userId, IsStaff(), cancellationToken);
|
|
|
|
return thread is null ? NotFound() : Ok(thread);
|
|
}
|
|
|
|
[HttpPost("{threadId}/messages")]
|
|
public async Task<ActionResult<MessageResponse>> AddMessage(
|
|
string threadId,
|
|
CreateMessageRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var userId = RequireUserId(out var unauthorized);
|
|
|
|
if (unauthorized is not null)
|
|
{
|
|
return unauthorized;
|
|
}
|
|
|
|
var message = await _threads.AddMessageAsync(threadId, userId, IsStaff(), request, cancellationToken);
|
|
|
|
return message is null ? NotFound() : StatusCode(StatusCodes.Status201Created, message);
|
|
}
|
|
|
|
private string RequireUserId(out ActionResult? unauthorized)
|
|
{
|
|
var userId = User.GetUserId();
|
|
|
|
unauthorized = string.IsNullOrWhiteSpace(userId) ? Unauthorized() : null;
|
|
|
|
return userId ?? string.Empty;
|
|
}
|
|
|
|
private bool IsStaff() =>
|
|
User.IsInRole(RoleNames.Operator) || User.IsInRole(RoleNames.Manager) || User.IsInRole(RoleNames.Admin);
|
|
}
|