102 lines
3.7 KiB
C#
102 lines
3.7 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Server.WatchBody.Core.Dal.Src.Domain;
|
|
using Server.WatchBody.Core.Dal.Src.Repository;
|
|
using Server.WatchBody.Core.Programs;
|
|
using Server.WatchBody.Web.Services;
|
|
|
|
namespace Server.WatchBody.Web.Controllers.Admin;
|
|
|
|
/// <summary>
|
|
/// Программы (spec 04 m08): версии, активация draft, применение
|
|
/// rules-предложения через author=admin-копию (🛡4 — оригинал не
|
|
/// меняется, Ф-9.3).
|
|
/// </summary>
|
|
public class AdminProgramsController(
|
|
AdminAuthService auth,
|
|
IProgramRepository programs,
|
|
ProgramStore store) : AdminControllerBase(auth)
|
|
{
|
|
public ActionResult List(int athleteId)
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
var versions = store.ListVersions(athleteId);
|
|
return new JsonResult(new
|
|
{
|
|
items = versions.Select(v => new
|
|
{
|
|
versionId = v.Id,
|
|
v.Version,
|
|
v.Status,
|
|
v.Author,
|
|
v.BasedOnVersion,
|
|
v.Rationale,
|
|
v.CreatedAt,
|
|
}),
|
|
});
|
|
}
|
|
|
|
public ActionResult Get(string versionId, int athleteId)
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
if (!Guid.TryParse(versionId, out var id)) return ErrorJson(400, "versionId не uuid");
|
|
var version = store.GetVersion(athleteId, id);
|
|
if (version == null) return ErrorJson(404, "not_found");
|
|
return new JsonResult(new
|
|
{
|
|
versionId = version.Id,
|
|
version.Version,
|
|
version.Status,
|
|
version.Author,
|
|
version.BasedOnVersion,
|
|
version.Body,
|
|
version.Rationale,
|
|
version.CreatedAt,
|
|
});
|
|
}
|
|
|
|
public ActionResult Activate(string versionId, int athleteId)
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
if (!Guid.TryParse(versionId, out var id)) return ErrorJson(400, "versionId не uuid");
|
|
try
|
|
{
|
|
store.Activate(athleteId, id);
|
|
}
|
|
catch (ProgramStoreException e)
|
|
{
|
|
return ErrorJson(400, e.Message);
|
|
}
|
|
var version = store.GetVersion(athleteId, id)!;
|
|
return new JsonResult(new { versionId = id, version.Version, status = version.Status });
|
|
}
|
|
|
|
/// <summary>Применение предложения правил (Ф-9.3): author=admin-копия
|
|
/// тела rules-draft → активация; оригинал остаётся draft (🛡4).</summary>
|
|
public ActionResult Apply(string versionId, int athleteId)
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
if (!Guid.TryParse(versionId, out var id)) return ErrorJson(400, "versionId не uuid");
|
|
var source = store.GetVersion(athleteId, id);
|
|
if (source == null) return ErrorJson(404, "not_found");
|
|
if (source.Author != ProgramVersionAuthors.Rules || source.Status != ProgramVersionStatuses.Draft)
|
|
return ErrorJson(400, "применять можно только draft-предложение правил (author=rules)");
|
|
|
|
try
|
|
{
|
|
var applied = store.CreateDraft(athleteId, source.Body, ProgramVersionAuthors.Admin,
|
|
$"{source.Rationale} (применено из консоли)".TrimStart());
|
|
store.Activate(athleteId, applied.Id);
|
|
return new JsonResult(new
|
|
{
|
|
versionId = applied.Id,
|
|
version = applied.Version,
|
|
status = store.GetVersion(athleteId, applied.Id)!.Status,
|
|
});
|
|
}
|
|
catch (ProgramStoreException e)
|
|
{
|
|
return ErrorJson(400, e.Message);
|
|
}
|
|
}
|
|
}
|