fix: cheers, it builds now

This commit is contained in:
2025-09-30 19:17:10 +03:00
parent dcbdb393cf
commit 0021c352dc
11 changed files with 8 additions and 156 deletions

View File

@@ -1,34 +0,0 @@
using System.Security.Claims;
using LctMonolith.Services;
using LctMonolith.Services.Contracts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace LctMonolith.Controllers;
/// <summary>
/// Endpoints exposing gamification progress information.
/// </summary>
[ApiController]
[Route("api/gamification")]
[Authorize]
public class GamificationController : ControllerBase
{
private readonly IGamificationService _gamificationService;
public GamificationController(IGamificationService gamificationService)
{
_gamificationService = gamificationService;
}
private Guid GetUserId() => Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
/// <summary>Returns current user progress snapshot (rank, xp, outstanding requirements).</summary>
[HttpGet("progress")]
public async Task<IActionResult> GetProgress(CancellationToken ct)
{
var snapshot = await _gamificationService.GetProgressAsync(GetUserId(), ct);
return Ok(snapshot);
}
}

View File

@@ -1,41 +0,0 @@
using System.Security.Claims;
using LctMonolith.Services;
using LctMonolith.Services.Contracts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace LctMonolith.Controllers;
/// <summary>
/// Inventory endpoints for viewing owned store items and artifacts.
/// </summary>
[ApiController]
[Route("api/inventory")]
[Authorize]
public class InventoryController : ControllerBase
{
private readonly IInventoryService _inventory;
public InventoryController(IInventoryService inventory)
{
_inventory = inventory;
}
private Guid GetUserId() => Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
/// <summary>List owned store inventory entries.</summary>
[HttpGet("store-items")]
public async Task<IActionResult> GetStoreItems(CancellationToken ct)
{
var items = await _inventory.GetStoreInventoryAsync(GetUserId(), ct);
return Ok(items.Select(i => new { i.StoreItemId, i.Quantity, i.AcquiredAt, i.IsReturned, i.StoreItem?.Name }));
}
/// <summary>List owned artifacts.</summary>
[HttpGet("artifacts")]
public async Task<IActionResult> GetArtifacts(CancellationToken ct)
{
var artifacts = await _inventory.GetArtifactsAsync(GetUserId(), ct);
return Ok(artifacts.Select(a => new { a.ArtifactId, a.ObtainedAt, a.Artifact?.Name, a.Artifact?.Rarity }));
}
}

View File

@@ -1,53 +0,0 @@
using System.Security.Claims;
using LctMonolith.Models.Database;
using LctMonolith.Services;
using LctMonolith.Services.Contracts;
using LctMonolith.Services.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace LctMonolith.Controllers;
/// <summary>
/// Endpoints for listing and managing missions.
/// </summary>
[ApiController]
[Route("api/missions")]
[Authorize]
public class MissionsController : ControllerBase
{
private readonly IMissionService _missionService;
public MissionsController(IMissionService missionService)
{
_missionService = missionService;
}
private Guid GetUserId() => Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
/// <summary>Returns missions currently available to the authenticated user.</summary>
[HttpGet]
public async Task<ActionResult<IEnumerable<Mission>>> GetAvailable(CancellationToken ct)
{
var userId = GetUserId();
var list = await _missionService.GetAvailableMissionsAsync(userId, ct);
return Ok(list);
}
/// <summary>Create a mission (HR functionality for now any authenticated user).</summary>
[HttpPost]
public async Task<ActionResult<Mission>> Create(CreateMissionModel model, CancellationToken ct)
{
var mission = await _missionService.CreateMissionAsync(model, ct);
return CreatedAtAction(nameof(GetAvailable), new { id = mission.Id }, mission);
}
/// <summary>Update mission status for current user (submit/complete/etc.).</summary>
[HttpPatch("{missionId:guid}/status")]
public async Task<ActionResult> UpdateStatus(Guid missionId, UpdateMissionStatusRequest req, CancellationToken ct)
{
var userId = GetUserId();
var result = await _missionService.UpdateStatusAsync(userId, missionId, req.Status, req.SubmissionData, ct);
return Ok(new { result.MissionId, result.Status, result.UpdatedAt });
}
}

View File

@@ -18,21 +18,21 @@ public static class DbSeeder
{ {
var ranks = new List<Rank> var ranks = new List<Rank>
{ {
new() { Name = "Искатель", Order = 0, RequiredExperience = 0 }, new() { Title = "Искатель", ExpNeeded = 0 },
new() { Name = "Пилот-кандидат", Order = 1, RequiredExperience = 500 }, new() { Title = "Пилот-кандидат", ExpNeeded = 500 },
new() { Name = "Принятый в экипаж", Order = 2, RequiredExperience = 1500 } new() { Title = "Принятый в экипаж", ExpNeeded = 1500 }
}; };
db.Ranks.AddRange(ranks); db.Ranks.AddRange(ranks);
Log.Information("Seeded {Count} ranks", ranks.Count); Log.Information("Seeded {Count} ranks", ranks.Count);
} }
if (!await db.Competencies.AnyAsync(ct)) if (!await db.Skills.AnyAsync(ct))
{ {
var comps = new[] var comps = new[]
{ {
"Вера в дело","Стремление к большему","Общение","Аналитика","Командование","Юриспруденция","Трёхмерное мышление","Базовая экономика","Основы аэронавигации" "Вера в дело","Стремление к большему","Общение","Аналитика","Командование","Юриспруденция","Трёхмерное мышление","Базовая экономика","Основы аэронавигации"
}.Select(n => new Competency { Name = n }); }.Select(n => new Skill { Title = n });
db.Competencies.AddRange(comps); db.Skills.AddRange(comps);
Log.Information("Seeded competencies"); Log.Information("Seeded competencies");
} }

View File

@@ -13,8 +13,8 @@ public class AppUser : IdentityUser<Guid>
public Rank? Rank { get; set; } public Rank? Rank { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
public ICollection<UserCompetency> Competencies { get; set; } = new List<UserCompetency>(); public ICollection<PlayerSkill> Competencies { get; set; } = new List<PlayerSkill>();
public ICollection<UserMission> Missions { get; set; } = new List<UserMission>(); public ICollection<PlayerMission> Missions { get; set; } = new List<PlayerMission>();
public ICollection<UserInventoryItem> Inventory { get; set; } = new List<UserInventoryItem>(); public ICollection<UserInventoryItem> Inventory { get; set; } = new List<UserInventoryItem>();
public ICollection<Transaction> Transactions { get; set; } = new List<Transaction>(); public ICollection<Transaction> Transactions { get; set; } = new List<Transaction>();
public ICollection<RefreshToken> RefreshTokens { get; set; } = new List<RefreshToken>(); public ICollection<RefreshToken> RefreshTokens { get; set; } = new List<RefreshToken>();

View File

@@ -95,11 +95,8 @@ builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
// Domain services // Domain services
builder.Services.AddScoped<ITokenService, TokenService>(); builder.Services.AddScoped<ITokenService, TokenService>();
builder.Services.AddScoped<IGamificationService, LctMonolith>();
builder.Services.AddScoped<IMissionService, MissionService>();
builder.Services.AddScoped<IStoreService, StoreService>(); builder.Services.AddScoped<IStoreService, StoreService>();
builder.Services.AddScoped<INotificationService, NotificationService>(); builder.Services.AddScoped<INotificationService, NotificationService>();
builder.Services.AddScoped<IInventoryService, InventoryService>();
builder.Services.AddScoped<IAnalyticsService, AnalyticsService>(); builder.Services.AddScoped<IAnalyticsService, AnalyticsService>();
// CORS // CORS

View File

@@ -17,16 +17,12 @@ public class AnalyticsService : IAnalyticsService
{ {
var totalUsers = await _uow.Users.Query().CountAsync(ct); var totalUsers = await _uow.Users.Query().CountAsync(ct);
var totalMissions = await _uow.Missions.Query().CountAsync(ct); var totalMissions = await _uow.Missions.Query().CountAsync(ct);
var completedMissions = await _uow.UserMissions.Query(um => um.Status == MissionStatus.Completed).CountAsync(ct);
var totalArtifacts = await _uow.Artifacts.Query().CountAsync(ct);
var totalStoreItems = await _uow.StoreItems.Query().CountAsync(ct); var totalStoreItems = await _uow.StoreItems.Query().CountAsync(ct);
var totalExperience = await _uow.Users.Query().SumAsync(u => (long)u.Experience, ct); var totalExperience = await _uow.Users.Query().SumAsync(u => (long)u.Experience, ct);
return new AnalyticsSummary return new AnalyticsSummary
{ {
TotalUsers = totalUsers, TotalUsers = totalUsers,
TotalMissions = totalMissions, TotalMissions = totalMissions,
CompletedMissions = completedMissions,
TotalArtifacts = totalArtifacts,
TotalStoreItems = totalStoreItems, TotalStoreItems = totalStoreItems,
TotalExperience = totalExperience TotalExperience = totalExperience
}; };

View File

@@ -1,7 +1,5 @@
using LctMonolith.Services.Models; using LctMonolith.Services.Models;
using LctMonolith.Services.Models;
namespace LctMonolith.Services; namespace LctMonolith.Services;
public interface IAnalyticsService public interface IAnalyticsService

View File

@@ -5,5 +5,4 @@ namespace LctMonolith.Services.Contracts;
public interface IInventoryService public interface IInventoryService
{ {
Task<IEnumerable<UserInventoryItem>> GetStoreInventoryAsync(Guid userId, CancellationToken ct = default); Task<IEnumerable<UserInventoryItem>> GetStoreInventoryAsync(Guid userId, CancellationToken ct = default);
Task<IEnumerable<UserArtifact>> GetArtifactsAsync(Guid userId, CancellationToken ct = default);
} }

View File

@@ -1,9 +0,0 @@
using LctMonolith.Models.Database;
namespace LctMonolith.Services.Models;
public class UpdateMissionStatusRequest
{
public MissionStatus Status { get; set; }
public string? SubmissionData { get; set; }
}

View File

@@ -10,7 +10,6 @@ using LctMonolith.Services.Models;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Serilog;
namespace LctMonolith.Services; namespace LctMonolith.Services;