Skip to content

Commit d0f0988

Browse files
Add project deletion functionality with controller, service, and repository methods
1 parent 1f8aa21 commit d0f0988

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed
Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
using Microsoft.AspNetCore.Authorization;
22
using Microsoft.AspNetCore.Mvc;
3-
using sparkly_server.Domain.Projects;
43
using sparkly_server.DTO.Projects;
5-
using sparkly_server.Enum;
64
using sparkly_server.Services.Projects;
7-
using sparkly_server.Services.Users;
85

96
namespace sparkly_server.Controllers.Projects
107
{
@@ -14,23 +11,18 @@ namespace sparkly_server.Controllers.Projects
1411
public class ProjectsController : ControllerBase
1512
{
1613
private readonly IProjectService _projects;
17-
private readonly ICurrentUser _currentUser;
18-
private readonly IUserService _users;
1914

20-
public ProjectsController(IProjectService projects, ICurrentUser currentUser, IUserService users)
21-
{
22-
_projects = projects;
23-
_currentUser = currentUser;
24-
_users = users;
25-
}
26-
15+
public ProjectsController(IProjectService projects) => _projects = projects;
16+
17+
// Random projects to feed the homepage
2718
[HttpGet("random")]
2819
public async Task<IActionResult> GetRandomProjects([FromQuery] int take = 20, CancellationToken ct = default)
2920
{
3021
var response = await _projects.GetRandomPublicAsync(take, ct);
3122
return Ok(response);
3223
}
3324

25+
// Create project
3426
[HttpPost("create")]
3527
public async Task<IActionResult> CreateProject([FromBody] CreateProjectRequest request)
3628
{
@@ -41,13 +33,15 @@ public async Task<IActionResult> CreateProject([FromBody] CreateProjectRequest r
4133
return Ok(response);
4234
}
4335

36+
// Get project by id
4437
[HttpGet("{projectId:guid}")]
4538
public async Task<IActionResult> GetProjectById(Guid projectId, CancellationToken ct = default)
4639
{
4740
var project = await _projects.GetProjectByIdAsync(projectId, ct);
4841
return Ok(project);
4942
}
5043

44+
// Update project by id (admin only)
5145
[HttpPut("update/{projectId:guid}")]
5246
public async Task<IActionResult> UpdateProject(
5347
Guid projectId,
@@ -57,5 +51,14 @@ public async Task<IActionResult> UpdateProject(
5751
await _projects.UpdateProjectAsync(projectId, request, cn);
5852
return NoContent();
5953
}
54+
55+
// Delete project by id (admin only)
56+
[HttpDelete("delete/{projectId:guid}")]
57+
public async Task<IActionResult> DeleteProject(Guid projectId, CancellationToken ct = default)
58+
{
59+
await _projects.DeleteProjectAsync(projectId, ct);
60+
61+
return NoContent();
62+
}
6063
}
6164
}

src/Services/Projects/IProjectRepository.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ public interface IProjectRepository
1010
Task<bool> IsProjectNameTakenAsync(string projectName, CancellationToken cn);
1111
Task<IReadOnlyList<Project>> GetRandomPublicAsync(int take, CancellationToken ct = default);
1212
Task SaveChangesAsync(CancellationToken cancellationToken = default);
13+
Task DeleteAsync(Guid id, CancellationToken cancellationToken = default);
1314
}
1415
}

src/Services/Projects/IProjectService.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,9 @@ Task UpdateProjectAsync(
5252
Guid projectId,
5353
UpdateProjectRequest request,
5454
CancellationToken cancellationToken = default);
55+
56+
Task DeleteProjectAsync(
57+
Guid projectId,
58+
CancellationToken cancellationToken = default);
5559
}
5660
}

src/Services/Projects/ProjectRepository.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ public Task SaveChangesAsync(CancellationToken cancellationToken = default)
4343
{
4444
return _db.SaveChangesAsync(cancellationToken);
4545
}
46-
46+
public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
47+
{
48+
await _db.Projects
49+
.Where(p => p.Id == id)
50+
.ExecuteDeleteAsync(cancellationToken);
51+
}
52+
4753
public async Task<IReadOnlyList<Project>> GetRandomPublicAsync(int take, CancellationToken ct = default)
4854
{
4955
return await _db.Projects

src/Services/Projects/ProjectService.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,24 @@ public async Task UpdateProjectAsync(Guid projectId, UpdateProjectRequest reques
198198
project.SetVisibility(request.Visibility);
199199
}
200200

201+
await _projects.SaveChangesAsync(cancellationToken);
202+
}
203+
public async Task DeleteProjectAsync(Guid projectId, CancellationToken cancellationToken = default)
204+
{
205+
var userId = _currentUser.UserId
206+
?? throw new InvalidOperationException("User is not authenticated");
207+
208+
var project = await _projects.GetByIdAsync(projectId, cancellationToken)
209+
?? throw new InvalidOperationException("Project not found");
210+
211+
var isAdmin = _currentUser.IsInRole(Roles.Admin);
212+
var isOwner = project.IsOwner(userId);
213+
214+
if (!isOwner && !isAdmin)
215+
throw new UnauthorizedAccessException("You are not allowed to delete this project.");
216+
217+
_projects.DeleteAsync(projectId, cancellationToken);
218+
201219
await _projects.SaveChangesAsync(cancellationToken);
202220
}
203221
}

0 commit comments

Comments
 (0)