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;
///
/// Программы (spec 04 m08): версии, активация draft, применение
/// rules-предложения через author=admin-копию (🛡4 — оригинал не
/// меняется, Ф-9.3).
///
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 });
}
/// Применение предложения правил (Ф-9.3): author=admin-копия
/// тела rules-draft → активация; оригинал остаётся draft (🛡4).
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);
}
}
}