feat(backend): add communication, tester, admin and middleman modules

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).
This commit is contained in:
Rafał Tyński
2026-10-04 03:49:45 +02:00
parent f4f3b3896a
commit fa1199539b
136 changed files with 2338 additions and 574 deletions
@@ -0,0 +1,57 @@
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/partnerships")]
[Authorize]
public class PartnershipsController : ControllerBase
{
private readonly IPartnershipService _partnerships;
public PartnershipsController(IPartnershipService partnerships)
{
_partnerships = partnerships;
}
[HttpGet]
public async Task<ActionResult<IReadOnlyList<PartnershipResponse>>> List(CancellationToken cancellationToken)
{
var userId = User.GetUserId();
if (string.IsNullOrWhiteSpace(userId))
{
return Unauthorized();
}
var partnerships = await _partnerships.ListForUserAsync(userId, IsStaff(), cancellationToken);
return Ok(partnerships);
}
[HttpPost]
public async Task<ActionResult<PartnershipResponse>> Create(
CreatePartnershipRequest request,
CancellationToken cancellationToken)
{
var userId = User.GetUserId();
if (string.IsNullOrWhiteSpace(userId))
{
return Unauthorized();
}
var created = await _partnerships.CreateAsync(userId, request, cancellationToken);
return StatusCode(StatusCodes.Status201Created, created);
}
private bool IsStaff() =>
User.IsInRole(RoleNames.Operator) || User.IsInRole(RoleNames.Manager) || User.IsInRole(RoleNames.Admin);
}