Compare commits

...

26 Commits

Author SHA1 Message Date
1a3ca3fc2d Patch endpoint 2026-03-26 17:49:43 +01:00
07bd241e0c Endpoint P2 2026-03-26 16:38:04 +01:00
579f50a2de Début endpoints 2026-03-26 15:34:49 +01:00
oistig
df6e559f00 Commit du reste des profils 2026-03-26 15:23:53 +01:00
oistig
1c1f9b2fcc Changements de models (à terminer) + GroupProfile 2026-03-19 17:53:02 +01:00
oistig
641552fba2 profiles encore parce que mathieu est un gros bebe 2026-03-19 17:06:15 +01:00
oistig
3699b28e03 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	Knots/obj/Debug/net8.0/Knots.assets.cache
#	Knots/obj/Debug/net8.0/Knots.csproj.AssemblyReference.cache
#	Knots/obj/project.nuget.cache
#	Knots/obj/project.packagespec.json
#	Knots/obj/rider.project.model.nuget.info
#	Knots/obj/rider.project.restore.info
2026-03-19 16:45:46 +01:00
oistig
26106c5db9 Ajout des profiles (pas fini) + Ajout du builder automapper dans Program.cs 2026-03-19 16:45:28 +01:00
b4595c173c Fin validator 2026-03-19 16:44:48 +01:00
oistig
ecd038f020 Fusion des patchs Tel et Email en un Patch Contact 2026-03-19 16:25:34 +01:00
oistig
00b79a58d0 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	Knots/obj/Debug/net8.0/Knots.AssemblyInfo.cs
#	Knots/obj/Debug/net8.0/Knots.AssemblyInfoInputs.cache
#	Knots/obj/rider.project.model.nuget.info
2026-03-19 16:19:07 +01:00
oistig
7c2e77ed99 Changements dans le Group Model + endpoints Patch des Groupes et Users 2026-03-19 16:18:52 +01:00
oistig
24613de57c commit 2026-03-19 15:11:43 +01:00
7acd4e7e11 Merge remote-tracking branch 'origin/develop' into develop 2026-03-19 15:10:00 +01:00
50227abc26 Validator update 2026-03-19 15:09:54 +01:00
oistig
dc9aa8c840 Merge remote-tracking branch 'origin/develop' into develop 2026-03-12 17:54:21 +01:00
oistig
3b178144ae Commit endpoints 2026-03-12 17:54:18 +01:00
3a83372403 Merge remote-tracking branch 'origin/develop' into develop 2026-03-12 17:44:44 +01:00
da3def1eea Ajout d'update pour patch + début validator 2026-03-12 17:44:39 +01:00
oistig
b7ad3c9af3 changement de nom de classe 2026-03-12 17:12:35 +01:00
oistig
696ec3da80 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	Knots/obj/Debug/net9.0/Knots.AssemblyInfo.cs
#	Knots/obj/Debug/net9.0/Knots.AssemblyInfoInputs.cache
2026-03-12 17:11:58 +01:00
oistig
55d50cf3df Endpoint de User 2026-03-12 17:11:48 +01:00
74cab09948 Changement à .NET8 2026-03-12 16:58:31 +01:00
db76d50079 Ajout des derniers validator 2026-03-12 16:42:38 +01:00
747cb84f88 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	Knots/Knots.csproj
2026-03-12 16:25:05 +01:00
fd33ac4744 Updates Models + Validator 2026-03-12 16:24:32 +01:00
282 changed files with 4996 additions and 2028 deletions

17
.idea/.idea.Knots/.idea/dataSources.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@romaric-thibault.fr" uuid="2e0ff1eb-4394-46d9-aa2d-362392df37df">
<driver-ref>sqlserver.jb</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.jetbrains.jdbc.sqlserver.SqlServerDriver</jdbc-driver>
<jdbc-url>Server=romaric-thibault.fr,1433</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@@ -2,5 +2,5 @@ namespace Knots.DTO.Discussion;
public class CreateDiscussionDto public class CreateDiscussionDto
{ {
public int Id { get; set; }
} }

View File

@@ -2,5 +2,5 @@ namespace Knots.DTO.Discussion;
public class DeleteDiscussionDto public class DeleteDiscussionDto
{ {
public int Id { get; set; }
} }

View File

@@ -2,5 +2,5 @@ namespace Knots.DTO.Discussion;
public class GetDiscussionDto public class GetDiscussionDto
{ {
public int Id { get; set; }
} }

View File

@@ -2,5 +2,5 @@ namespace Knots.DTO.Group;
public class DeleteGroupDto public class DeleteGroupDto
{ {
public string? Id { get; set; } public int? Id { get; set; }
} }

View File

@@ -0,0 +1,9 @@
namespace Knots.DTO.Group;
public class GetGroupDetailsDto
{
public int Id { get; set; }
public string? Nom { get; set; }
public int NombreMembres { get; set; }
public string? ProfilePicture { get; set; }
}

View File

@@ -3,7 +3,4 @@ namespace Knots.DTO.Group;
public class GetGroupDto public class GetGroupDto
{ {
public int Id { get; set; } public int Id { get; set; }
public string? Nom { get; set; }
public int NombreMembres { get; set; }
public string? ProfilePicture { get; set; }
} }

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.Group;
public class UpdateGroupMembersAmountDto
{
public int Id { get; set; }
public int MembersAmount { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.Group;
public class UpdateGroupNameDto
{
public int Id { get; set; }
public string? Name { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.Group;
public class UpdateGroupProfilePictureDto
{
public int Id { get; set; }
public string? ProfilePicture { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.Key;
public class GetKeyDetailsDto
{
public int Id { get; set; }
public string? EnKey { get; set; }
}

View File

@@ -3,5 +3,4 @@ namespace Knots.DTO.Key;
public class GetKeyDto public class GetKeyDto
{ {
public int Id { get; set; } public int Id { get; set; }
public string? EnKey { get; set; }
} }

View File

@@ -1,7 +1,9 @@
namespace Knots.DTO.Message; namespace Knots.DTO.Message;
public class UpdateMessageDto public class GetMessageDetailsDto
{ {
public int Id { get; set; }
public string? Contenu { get; set; } public string? Contenu { get; set; }
public DateTime Date { get; set; } public DateTime Date { get; set; }
public Boolean Type { get; set; }
} }

View File

@@ -2,7 +2,5 @@ namespace Knots.DTO.Message;
public class GetMessageDto public class GetMessageDto
{ {
public string? Contenu { get; set; } public int Id { get; set; }
public DateTime Date { get; set; }
public Boolean Type { get; set; }
} }

View File

@@ -2,5 +2,5 @@ namespace Knots.DTO.Role;
public class GetRoleDto public class GetRoleDto
{ {
public string? Id { get; set; } public string? Libelle { get; set; }
} }

View File

@@ -0,0 +1,11 @@
namespace Knots.DTO.User;
public class CreateUserDto
{
public string? Username { get; set; }
public string? Description {get; set;}
public string? Password { get; set; }
public string? Email { get; set; }
public string? Tel { get; set; }
public string? ProfilePicture { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace Knots.DTO.User;
public class DeleteUserDto
{
public string? Username { get; set; }
}

View File

@@ -0,0 +1,11 @@
namespace Knots.DTO.User;
public class GetUserDetailsDto
{
public string? Username { get; set; }
public string? Description {get; set;}
public string? Password { get; set; }
public string? Email { get; set; }
public string? Tel { get; set; }
public string? ProfilePicture { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace Knots.DTO.User;
public class GetUserDto
{
public string? Username { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace Knots.DTO.User;
public class UpdateUserContactDto
{
public int Id { get; set; }
public string? Email { get; set; }
public string? Tel { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.User;
public class UpdateUserDescriptionDto
{
public int Id { get; set; }
public string? Description {get; set;}
}

View File

@@ -0,0 +1,6 @@
namespace Knots.DTO.User;
public class UpdateUserDto
{
public int Id { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.User;
public class UpdateUserPasswordDto
{
public int Id { get; set; }
public string? Password { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.User;
public class UpdateUserProfilePictureDto
{
public int Id { get; set; }
public string? ProfilePicture { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace Knots.DTO.User;
public class UpdateUsernameDto
{
public int Id { get; set; }
public string? Username { get; set; }
}

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.Discussion;
namespace Knots.Endpoints.Discussion; namespace Knots.Endpoints.Discussion;
public class CreateDiscussionEndpoint public class CreateDiscussionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateDiscussionDto>
{ {
public override void Configure()
{
Post("/discussions");
AllowAnonymous();
}
public override async Task HandleAsync(CreateDiscussionDto req, CancellationToken ct)
{
Models.Discussion? discussion = mapper.Map<Models.Discussion>(req);
db.Discussions.Add(discussion);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.Discussion;
namespace Knots.Endpoints.Discussion; namespace Knots.Endpoints.Discussion;
public class DeleteDiscussionEndpoint public class DeleteDiscussionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteDiscussionDto>
{ {
public override void Configure()
{
Delete("/discussions");
AllowAnonymous();
}
public override async Task HandleAsync(DeleteDiscussionDto req, CancellationToken ct)
{
Models.Discussion? discussion = mapper.Map<Models.Discussion>(req);
db.Discussions.Remove(discussion);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,29 @@
using Knots.DTO.Discussion;
using Knots.DTO.Key;
using Microsoft.EntityFrameworkCore;
using FastEndpoints;
namespace Knots.Endpoints.Discussion; namespace Knots.Endpoints.Discussion;
public class GetDiscussionEndpoint public class GetDiscussionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<GetDiscussionDto>
{ {
public override void Configure()
{
Get("/groups");
AllowAnonymous();
}
public override async Task HandleAsync(GetDiscussionDto req, CancellationToken ct)
{
Models.Discussion? databaseDiscussion = await db.Discussions.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseDiscussion == null)
{
await Send.NotFoundAsync(ct);
return;
}
var keyDto = mapper.Map<GetKeyDetailsDto>(databaseDiscussion);
await Send.OkAsync(keyDto, ct);
}
} }

View File

@@ -1,6 +1,21 @@
using Knots.DTO.Group;
using FastEndpoints;
namespace Knots.Endpoints.Group; namespace Knots.Endpoints.Group;
public class CreateGroupEndpoint public class CreateGroupEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateGroupDto>
{ {
public override void Configure()
{
Post("/groups");
AllowAnonymous();
}
public override async Task HandleAsync(CreateGroupDto req, CancellationToken ct)
{
Models.Group? group = mapper.Map<Models.Group>(req);
db.Groups.Add(group);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.Group;
namespace Knots.Endpoints.Group; namespace Knots.Endpoints.Group;
public class DeleteGroupEndpoint public class DeleteGroupEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteGroupDto>
{ {
public override void Configure()
{
Delete("/groups");
AllowAnonymous();
}
public override async Task HandleAsync(DeleteGroupDto req, CancellationToken ct)
{
Models.Group? group = mapper.Map<Models.Group>(req);
db.Groups.Remove(group);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,29 @@
using FastEndpoints;
using Knots.DTO.Group;
using Knots.DTO.Key;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.Group; namespace Knots.Endpoints.Group;
public class GetGroupEndpoint public class GetGroupEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<GetGroupDetailsDto>
{ {
public override void Configure()
{
Get("/groups");
AllowAnonymous();
}
public override async Task HandleAsync(GetGroupDetailsDto req, CancellationToken ct)
{
Models.Group? databaseGroup = await db.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseGroup == null)
{
await Send.NotFoundAsync(ct);
return;
}
var keyDto = mapper.Map<GetKeyDetailsDto>(databaseGroup);
await Send.OkAsync(keyDto, ct);
}
} }

View File

@@ -0,0 +1,29 @@
using FastEndpoints;
using Knots.DTO.Group;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.Group;
public class PatchGroupMembersAmountEndpoint(KnotsDbContext knotsDbContext) : Endpoint<UpdateGroupMembersAmountDto>
{
public override void Configure()
{
Patch("/groups/{@Id}/membersAmount/", x => new {x.Id});
AllowAnonymous();
}
public override async Task HandleAsync(UpdateGroupMembersAmountDto req, CancellationToken ct)
{
Models.Group? databaseGroup = await knotsDbContext.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseGroup is null)
{
await Send.NotFoundAsync(ct);
return;
}
databaseGroup.MembersAmount = req.MembersAmount;
await knotsDbContext.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -0,0 +1,29 @@
using FastEndpoints;
using Knots.DTO.Group;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.Group;
public class PatchGroupNameEndpoint(KnotsDbContext knotsDbContext) : Endpoint<UpdateGroupNameDto>
{
public override void Configure()
{
Patch("/groups/{@Id}/name/", x => new {x.Id});
AllowAnonymous();
}
public override async Task HandleAsync(UpdateGroupNameDto req, CancellationToken ct)
{
Models.Group? databaseGroup = await knotsDbContext.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseGroup is null)
{
await Send.NotFoundAsync(ct);
return;
}
databaseGroup.Name = req.Name;
await knotsDbContext.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -0,0 +1,29 @@
using FastEndpoints;
using Knots.DTO.Group;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.Group;
public class PatchGroupProfilePictureEndpoint(KnotsDbContext knotsDbContext) : Endpoint<UpdateGroupProfilePictureDto>
{
public override void Configure()
{
Patch("/groups/{@Id}/profilePicture/", x => new {x.Id});
AllowAnonymous();
}
public override async Task HandleAsync(UpdateGroupProfilePictureDto req, CancellationToken ct)
{
Models.Group? databaseGroup = await knotsDbContext.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseGroup is null)
{
await Send.NotFoundAsync(ct);
return;
}
databaseGroup.ProfilePicture = req.ProfilePicture;
await knotsDbContext.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -1,6 +1,21 @@
using Knots.DTO.Key;
using FastEndpoints;
namespace Knots.Endpoints.Key; namespace Knots.Endpoints.Key;
public class CreateKeyEndpoint public class CreateKeyEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateKeyDto>
{ {
public override void Configure()
{
Post("/groups");
AllowAnonymous();
}
public override async Task HandleAsync(CreateKeyDto req, CancellationToken ct)
{
Models.Key? key = mapper.Map<Models.Key>(req);
db.Keys.Add(key);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.Key;
namespace Knots.Endpoints.Key; namespace Knots.Endpoints.Key;
public class DeleteKeyEndpoint public class DeleteKeyEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteKeyDto>
{ {
public override void Configure()
{
Delete("/groups");
AllowAnonymous();
}
public override async Task HandleAsync(DeleteKeyDto req, CancellationToken ct)
{
Models.Key? key = mapper.Map<Models.Key>(req);
db.Keys.Remove(key);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,29 @@
using FastEndpoints;
using Knots.DTO.Key;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.Key; namespace Knots.Endpoints.Key;
public class GetKeyEndpoint public class GetKeyEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <GetKeyDetailsDto>
{ {
public override void Configure()
{
Get("/keys/{@Id}");
AllowAnonymous();
}
public override async Task HandleAsync(GetKeyDetailsDto req, CancellationToken ct)
{
Models.Key? databaseKey = await db.Keys.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseKey == null)
{
await Send.NotFoundAsync(ct);
return;
}
var keyDto = mapper.Map<GetKeyDetailsDto>(databaseKey);
await Send.OkAsync(keyDto, ct);
}
} }

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.Message;
namespace Knots.Endpoints.Message; namespace Knots.Endpoints.Message;
public class CreateMessageEndpoint public class CreateMessageEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateMessageDto>
{ {
public override void Configure()
{
Post("/messages");
AllowAnonymous();
}
public override async Task HandleAsync(CreateMessageDto req, CancellationToken ct)
{
Models.Message? message = mapper.Map<Models.Message>(req);
db.Messages.Add(message);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.Message;
namespace Knots.Endpoints.Message; namespace Knots.Endpoints.Message;
public class DeleteMessageEndpoint public class DeleteMessageEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteMessageDto>
{ {
public override void Configure()
{
Delete("/messages");
AllowAnonymous();
}
public override async Task HandleAsync(DeleteMessageDto req, CancellationToken ct)
{
Models.Message? message = mapper.Map<Models.Message>(req);
db.Messages.Remove(message);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,29 @@
using FastEndpoints;
using Knots.DTO.Message;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.Message; namespace Knots.Endpoints.Message;
public class GetMessageEndpoint public class GetMessageEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <GetMessageDetailsDto>
{ {
public override void Configure()
{
Get("/messages/{@Id}");
AllowAnonymous();
}
public override async Task HandleAsync(GetMessageDetailsDto req, CancellationToken ct)
{
Models.Message? databaseMessage = await db.Messages.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseMessage == null)
{
await Send.NotFoundAsync(ct);
return;
}
var messageDto = mapper.Map<GetMessageDetailsDto>(databaseMessage);
await Send.OkAsync(messageDto, ct);
}
} }

View File

@@ -1,6 +1,22 @@
using FastEndpoints;
using Knots.DTO.Role;
using Knots.DTO.User;
namespace Knots.Endpoints.Role; namespace Knots.Endpoints.Role;
public class CreateRoleEndpoint public class CreateRoleEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateRoleDto>
{ {
public override void Configure()
{
Post("/roles");
AllowAnonymous();
}
public override async Task HandleAsync(CreateRoleDto req, CancellationToken ct)
{
Models.Role? role = mapper.Map<Models.Role>(req);
db.Roles.Add(role);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -0,0 +1,21 @@
using FastEndpoints;
using Knots.DTO.Role;
namespace Knots.Endpoints.Role;
public class DeleteRoleEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteRoleDto>
{
public override void Configure()
{
Delete("/roles");
AllowAnonymous();
}
public override async Task HandleAsync(DeleteRoleDto req, CancellationToken ct)
{
Models.Role? role = mapper.Map<Models.Role>(req);
db.Roles.Remove(role);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -1,6 +1,29 @@
using FastEndpoints;
using Knots.DTO.Role;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.Role; namespace Knots.Endpoints.Role;
public class GetRoleEndpoint public class GetRoleEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <GetRoleDto>
{ {
public override void Configure()
{
Get ("/roles/{@Id}", x => new { x.Libelle });
AllowAnonymous();
}
public override async Task HandleAsync(GetRoleDto req, CancellationToken ct)
{
Models.Role? databaseRole = await db.Roles.SingleOrDefaultAsync(x => x.Libelle == req.Libelle, cancellationToken: ct);
if (databaseRole == null)
{
await Send.NotFoundAsync(ct);
return;
}
var roleDto = mapper.Map<GetRoleDto>(databaseRole);
await Send.OkAsync(roleDto, ct);
}
} }

View File

@@ -1,6 +0,0 @@
namespace Knots.Endpoints.Role;
public class UpdateRoleEndpoint
{
}

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.User;
namespace Knots.Endpoints.User; namespace Knots.Endpoints.User;
public class CreateUserEndpoint public class CreateUserEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateUserDto, GetUserDto>
{ {
public override void Configure()
{
Post("/users");
AllowAnonymous();
}
public override async Task HandleAsync(CreateUserDto req, CancellationToken ct)
{
Models.User? user = mapper.Map<Models.User>(req);
db.Users.Add(user);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,21 @@
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User; namespace Knots.Endpoints.User;
public class DeleteUserEndpoint public class DeleteUserEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <DeleteUserDto>
{ {
public override void Configure()
{
Delete ("/users/{@Id}");
}
public override async Task HandleAsync(DeleteUserDto req, CancellationToken ct)
{
Models.User? user = mapper.Map<Models.User>(req);
db.Users.Add(user);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
} }

View File

@@ -1,6 +1,24 @@
using AutoMapper.QueryableExtensions;
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User; namespace Knots.Endpoints.User;
public class GetAllUsersEndpoint public class GetAllUsersEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : EndpointWithoutRequest<List<GetUserDetailsDto>>
{ {
public override void Configure()
{
Get ("/users");
AllowAnonymous();
}
public override async Task HandleAsync(CancellationToken ct)
{
var users = await db.Users
.ProjectTo<GetUserDetailsDto>(mapper.ConfigurationProvider)
.ToListAsync(ct);
await Send.OkAsync(users, ct);
}
} }

View File

@@ -1,6 +1,28 @@
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User; namespace Knots.Endpoints.User;
public class GetUserEndpoint public class GetUserEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <GetUserDetailsDto>
{ {
public override void Configure()
{
Get ("/users/{@Id}", x => new { x.Username });
AllowAnonymous();
}
public override async Task HandleAsync(GetUserDetailsDto req, CancellationToken ct)
{
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Username == req.Username, cancellationToken: ct);
if (databaseUser == null)
{
await Send.NotFoundAsync(ct);
return;
}
var userDto = mapper.Map<GetUserDetailsDto>(databaseUser);
await Send.OkAsync(userDto, ct);
}
} }

View File

@@ -0,0 +1,47 @@
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User;
public class PatchUserContactEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserContactDto>
{
public override void Configure()
{
Patch("/users/{@Id}/contact/", x => new {x.Id});
AllowAnonymous();
}
public override async Task HandleAsync(UpdateUserContactDto req, CancellationToken ct)
{
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseUser is null)
{
await Send.NotFoundAsync(ct);
return;
}
if (databaseUser.Email != req.Email)
{
databaseUser.Email = req.Email;
}
else
{
databaseUser.Email = databaseUser.Email;
}
if (databaseUser.Tel != req.Tel)
{
databaseUser.Tel = req.Tel;
}else
{
databaseUser.Tel = databaseUser.Tel;
}
mapper.Map(req, databaseUser);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -0,0 +1,30 @@
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User;
public class PatchUserDescriptionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserDescriptionDto>
{
public override void Configure()
{
Patch("/users/{@Id}/description/");
AllowAnonymous();
}
public override async Task HandleAsync(UpdateUserDescriptionDto req, CancellationToken ct)
{
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseUser is null)
{
await Send.NotFoundAsync(ct);
return;
}
mapper.Map(req, databaseUser);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -0,0 +1,30 @@
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User;
public class PatchUserPasswordEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserPasswordDto>
{
public override void Configure()
{
Patch("/users/{@Id}/password/", x => new {x.Id});
AllowAnonymous();
}
public override async Task HandleAsync(UpdateUserPasswordDto req, CancellationToken ct)
{
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseUser is null)
{
await Send.NotFoundAsync(ct);
return;
}
mapper.Map(req, databaseUser);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -0,0 +1,30 @@
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User;
public class PatchUserProfilePictureEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserProfilePictureDto>
{
public override void Configure()
{
Patch("/users/{@Id}/profilepicture/", x => new {x.Id});
AllowAnonymous();
}
public override async Task HandleAsync(UpdateUserProfilePictureDto req, CancellationToken ct)
{
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseUser is null)
{
await Send.NotFoundAsync(ct);
return;
}
mapper.Map(req, databaseUser);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -0,0 +1,31 @@
using FastEndpoints;
using Knots.DTO.User;
using Microsoft.EntityFrameworkCore;
namespace Knots.Endpoints.User;
public class PatchUsernameEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUsernameDto>
{
public override void Configure()
{
Patch("/users/{@Id}/username/");
AllowAnonymous();
}
public override async Task HandleAsync(UpdateUsernameDto req, CancellationToken ct)
{
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
if (databaseUser is null)
{
await Send.NotFoundAsync(ct);
return;
}
mapper.Map(req, databaseUser);
await db.SaveChangesAsync(ct);
await Send.NoContentAsync(ct);
}
}

View File

@@ -1,6 +0,0 @@
namespace Knots.Endpoints.User;
public class UpdateUserEndpoint
{
}

View File

@@ -1,26 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="16.1.1" />
<PackageReference Include="FastEndpoints" Version="8.0.1" /> <PackageReference Include="FastEndpoints" Version="8.0.1" />
<PackageReference Include="FastEndpoints.Swagger" Version="8.0.1" /> <PackageReference Include="FastEndpoints.Swagger" Version="8.0.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8"/> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.25" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.14" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.25" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.14"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.25">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.14" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.25" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="DTO\User\" /> <Folder Include="Endpoints\" />
<Folder Include="Validators\" /> <Folder Include="Migrations\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,165 @@
// <auto-generated />
using System;
using Knots;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Knots.Migrations
{
[DbContext(typeof(KnotsDbContext))]
[Migration("20260312155557_Initial")]
partial class Initial
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.25")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Knots.Models.Discussion", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.HasKey("Id");
b.ToTable("Discussions");
});
modelBuilder.Entity("Knots.Models.Group", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Nom")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<int>("NombreMembres")
.HasColumnType("int");
b.Property<string>("ProfilePicture")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Groups");
});
modelBuilder.Entity("Knots.Models.Key", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("EnKey")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Keys");
});
modelBuilder.Entity("Knots.Models.Message", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Contenu")
.IsRequired()
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime>("Date")
.HasColumnType("datetime2");
b.Property<bool>("Type")
.HasColumnType("bit");
b.HasKey("Id");
b.ToTable("Messages");
});
modelBuilder.Entity("Knots.Models.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Libelle")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Roles");
});
modelBuilder.Entity("Knots.Models.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(70)
.HasColumnType("nvarchar(70)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ProfilePicture")
.HasColumnType("nvarchar(max)");
b.Property<string>("Tel")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Username")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Users");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,123 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Knots.Migrations
{
/// <inheritdoc />
public partial class Initial : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Discussions",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1")
},
constraints: table =>
{
table.PrimaryKey("PK_Discussions", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Groups",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Nom = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
NombreMembres = table.Column<int>(type: "int", nullable: false),
ProfilePicture = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Groups", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Keys",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
EnKey = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Keys", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Contenu = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: false),
Date = table.Column<DateTime>(type: "datetime2", nullable: false),
Type = table.Column<bool>(type: "bit", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Messages", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Roles",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Libelle = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Roles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Username = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
Description = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
Email = table.Column<string>(type: "nvarchar(70)", maxLength: 70, nullable: false),
Tel = table.Column<string>(type: "nvarchar(max)", nullable: false),
ProfilePicture = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Discussions");
migrationBuilder.DropTable(
name: "Groups");
migrationBuilder.DropTable(
name: "Keys");
migrationBuilder.DropTable(
name: "Messages");
migrationBuilder.DropTable(
name: "Roles");
migrationBuilder.DropTable(
name: "Users");
}
}
}

View File

@@ -0,0 +1,162 @@
// <auto-generated />
using System;
using Knots;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Knots.Migrations
{
[DbContext(typeof(KnotsDbContext))]
partial class KnotsDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.25")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Knots.Models.Discussion", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.HasKey("Id");
b.ToTable("Discussions");
});
modelBuilder.Entity("Knots.Models.Group", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Nom")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<int>("NombreMembres")
.HasColumnType("int");
b.Property<string>("ProfilePicture")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Groups");
});
modelBuilder.Entity("Knots.Models.Key", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("EnKey")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Keys");
});
modelBuilder.Entity("Knots.Models.Message", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Contenu")
.IsRequired()
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<DateTime>("Date")
.HasColumnType("datetime2");
b.Property<bool>("Type")
.HasColumnType("bit");
b.HasKey("Id");
b.ToTable("Messages");
});
modelBuilder.Entity("Knots.Models.Role", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Libelle")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Roles");
});
modelBuilder.Entity("Knots.Models.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Description")
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(70)
.HasColumnType("nvarchar(70)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ProfilePicture")
.HasColumnType("nvarchar(max)");
b.Property<string>("Tel")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Username")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Users");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -5,4 +5,7 @@ namespace Knots.Models;
public class Discussion public class Discussion
{ {
[Key] public int Id { get; set; } [Key] public int Id { get; set; }
public List<Message> Messages { get; set; }
public Key KeyId { get; set; }
} }

View File

@@ -6,7 +6,10 @@ namespace Knots.Models;
public class Group public class Group
{ {
[Key] public int Id { get; set; } [Key] public int Id { get; set; }
[Required, MaxLength(50)] public string? Nom { get; set; } [Required, MaxLength(50)] public string? Name { get; set; }
[Required] public int NombreMembres { get; set; } [Required] public int MembersAmount { get; set; }
public string? ProfilePicture { get; set; } public string? ProfilePicture { get; set; }
public Key KeyId { get; set; }
List<Message> Messages { get; set; }
List<User> Users { get; set; }
} }

View File

@@ -6,4 +6,5 @@ public class Key
{ {
[Key] public int Id { get; set; } [Key] public int Id { get; set; }
[Required, MaxLength(50)] public string? EnKey { get; set; } [Required, MaxLength(50)] public string? EnKey { get; set; }
List<Message> Messages { get; set; }
} }

View File

@@ -8,4 +8,7 @@ public class Message
[Required, MaxLength(1000)] public string? Contenu { get; set; } [Required, MaxLength(1000)] public string? Contenu { get; set; }
[Required] public DateTime Date { get; set; } [Required] public DateTime Date { get; set; }
[Required] public Boolean Type { get; set; } [Required] public Boolean Type { get; set; }
public Group Group { get; set; }
public Key Key { get; set; }
public User User { get; set; }
} }

View File

@@ -5,5 +5,5 @@ namespace Knots.Models;
public class Role public class Role
{ {
public int Id { get; set; } public int Id { get; set; }
[Required, MaxLength(50)] public string Libelle { get; set; } [Required, MaxLength(50)] public string? Libelle { get; set; }
} }

View File

@@ -11,4 +11,5 @@ public class User
[Required, MaxLength(70)] public string? Email { get; set; } [Required, MaxLength(70)] public string? Email { get; set; }
[Required, Length(10, 10)] public string? Tel { get; set; } [Required, Length(10, 10)] public string? Tel { get; set; }
public string? ProfilePicture { get; set; } public string? ProfilePicture { get; set; }
public List<Message> Messages { get; set; }
} }

View File

@@ -0,0 +1,17 @@
using AutoMapper;
using Knots.DTO.Discussion;
using Knots.Models;
namespace Knots.Profiles;
public class DiscussionProfile : Profile
{
public DiscussionProfile()
{
CreateMap<Discussion, GetDiscussionDto>();
CreateMap<Discussion, CreateDiscussionDto>();
CreateMap<CreateDiscussionDto, Discussion>();
}
}

View File

@@ -0,0 +1,15 @@
using AutoMapper;
using Knots.DTO.Group;
using Knots.Models;
namespace Knots.Profiles;
public class GroupProfile : Profile
{
public GroupProfile()
{
CreateMap<Group, GetGroupDto>();
CreateMap<Group, GetGroupDetailsDto>();
CreateMap<CreateGroupDto, Group>();
}
}

View File

@@ -0,0 +1,16 @@
using AutoMapper;
using Knots.DTO.Discussion;
using Knots.DTO.Key;
using Knots.Models;
namespace Knots.Profiles;
public class KeyProfile : Profile
{
public KeyProfile()
{
CreateMap<Key, GetKeyDetailsDto>();
CreateMap<Key, CreateKeyDto>();
CreateMap<CreateKeyDto, Key>();
}
}

View File

@@ -0,0 +1,16 @@
using AutoMapper;
using Knots.DTO.Discussion;
using Knots.DTO.Message;
using Knots.Models;
namespace Knots.Profiles;
public class MessageProfile : Profile
{
MessageProfile()
{
CreateMap<Message, GetMessageDetailsDto>();
CreateMap<Message, CreateMessageDto>();
CreateMap<CreateMessageDto, Message>();
}
}

View File

@@ -0,0 +1,16 @@
using AutoMapper;
using Knots.DTO.Discussion;
using Knots.DTO.Role;
using Knots.Models;
namespace Knots.Profiles;
public class RoleProfile : Profile
{
public RoleProfile()
{
CreateMap<Role, GetRoleDto>();
CreateMap<Role, CreateRoleDto>();
CreateMap<CreateRoleDto, Role>();
}
}

View File

@@ -0,0 +1,29 @@
using AutoMapper;
using Knots.DTO.Discussion;
using Knots.DTO.User;
using Knots.Models;
namespace Knots.Profiles;
public class UserProfile : Profile
{
UserProfile()
{
CreateMap<User, GetUserDetailsDto>();
CreateMap<User, GetUserDto>();
CreateMap<CreateUserDto, User>();
CreateMap<UpdateUserDto, User>();
CreateMap<UpdateUserContactDto, User>();
CreateMap<UpdateUserDescriptionDto, User>();
CreateMap<UpdateUsernameDto, User>();
CreateMap<UpdateUserProfilePictureDto, User>();
CreateMap<UpdateUserPasswordDto, User>();
CreateMap<User, UpdateUserContactDto>();
CreateMap<User, UpdateUserDto>();
CreateMap<User, UpdateUserDescriptionDto>();
CreateMap<User, UpdateUserProfilePictureDto>();
CreateMap<User, UpdateUserPasswordDto>();
CreateMap<User, CreateUserDto>();
}
}

View File

@@ -1,23 +1,38 @@
var builder = WebApplication.CreateBuilder(args); using Knots;
using FastEndpoints;
using FastEndpoints.Swagger;
// Add services to the container. WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(); // On ajoute ici la configuration de la base de données
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddDbContext<KnotsDbContext>();
builder.Services.AddOpenApi();
var app = builder.Build(); //On ajoute le CORS au code
builder.Services.AddCors(options =>
{ options.AddDefaultPolicy(policyBuilder =>
{
policyBuilder
.WithOrigins("http://localhost:4200")
.WithMethods("GET", "POST", "PUT", "PATCH", "DELETE")
.AllowAnyHeader();
});
});
// Configure the HTTP request pipeline. builder.Services.AddAutoMapper(cfg => { }, typeof(Program).Assembly);
if (app.Environment.IsDevelopment())
{ // On construit l'application en lui donnant vie
app.MapOpenApi(); WebApplication app = builder.Build();
} app.UseAuthentication()
.UseAuthorization()
.UseFastEndpoints(options =>
{
options.Endpoints.RoutePrefix = "API";
options.Endpoints.ShortNames = true;
}
).UseSwaggerGen();
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseAuthorization(); app.UseCors();
app.MapControllers();
app.Run(); app.Run();

View File

@@ -0,0 +1,15 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Discussion;
namespace Knots.Validators.Discussion;
public class CreateDiscussionDtoValidator : Validator<CreateDiscussionDto>
{
public CreateDiscussionDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("Id is required");
}
}

View File

@@ -0,0 +1,15 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Discussion;
namespace Knots.Validators.Discussion;
public class DeleteDiscussionDtoValidator : Validator<DeleteDiscussionDto>
{
public DeleteDiscussionDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("Id is required");
}
}

View File

@@ -0,0 +1,21 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Group;
namespace Knots.Validators.Group;
public class CreateGroupDtoValidator : Validator<CreateGroupDto>
{
public CreateGroupDtoValidator()
{
RuleFor(x => x.Nom)
.NotEmpty()
.WithMessage("You must enter a name for the group")
.MaximumLength(50)
.WithMessage("Maximum 50 character are required");
RuleFor(x => x.NombreMembres)
.NotEmpty()
.WithMessage("Members cannot be empty");
}
}

View File

@@ -0,0 +1,17 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Group;
namespace Knots.Validators.Group;
public class DeleteGroupDtoValidator : Validator<DeleteGroupDto>
{
public DeleteGroupDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("Id is required")
.GreaterThan(0)
.WithMessage("Id cannot be less than zero");
}
}

View File

@@ -0,0 +1,15 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Group;
namespace Knots.Validators.Group;
public class GetGroupDtoValidator : Validator<GetGroupDto>
{
public GetGroupDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("Id cannot be empty");
}
}

View File

@@ -0,0 +1,9 @@
using FastEndpoints;
using Knots.DTO.Group;
namespace Knots.Validators.Group;
public class UpdateGroupDtoValidator : Validator<UpdateGroupDto>
{
}

View File

@@ -0,0 +1,21 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Group;
namespace Knots.Validators.Group;
public class UpdateGroupMembersAmountDtoValidator : Validator<UpdateGroupMembersAmountDto>
{
public UpdateGroupMembersAmountDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("L'id est requis")
.GreaterThan(0)
.WithMessage("L'id doit être supérieur à 0");
RuleFor(x => x.MembersAmount)
.NotEmpty()
.WithMessage("Le nombre de membres est requis");
}
}

View File

@@ -0,0 +1,20 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Group;
namespace Knots.Validators.Group;
public class UpdateGroupNameDtoValidator : Validator<UpdateGroupNameDto>
{
public UpdateGroupNameDtoValidator()
{
RuleFor(x => x.Id)
.NotNull()
.WithMessage("L'id doit être renseigné");
RuleFor(x => x.Name)
.NotEmpty()
.WithMessage("Le nom de groupe est requis");
}
}

View File

@@ -0,0 +1,15 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Key;
namespace Knots.Validators.Key;
public class CreateKeyDtoValidator : Validator<CreateKeyDto>
{
public CreateKeyDtoValidator()
{
RuleFor(x => x.EnKey)
.NotEmpty()
.WithMessage("La clé de chiffrement ne doit pas être nulle.");
}
}

View File

@@ -0,0 +1,17 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Key;
namespace Knots.Validators.Key;
public class DeleteKeyDtoValidator : Validator<DeleteKeyDto>
{
public DeleteKeyDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("L'id doit être renseigné")
.GreaterThan(0)
.WithMessage("L'id renseigné doit être supérieur à 0");
}
}

View File

@@ -0,0 +1,17 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Key;
namespace Knots.Validators.Key;
public class GetKeyDtoValidator : Validator<GetKeyDto>
{
public GetKeyDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("L'id est requis")
.GreaterThan(0)
.WithMessage("L'id doit être supérieur à 0");
}
}

View File

@@ -0,0 +1,26 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Message;
namespace Knots.Validators.Message;
public class CreateMessageDtoValidator : Validator<CreateMessageDto>
{
public CreateMessageDtoValidator()
{
RuleFor(x => x.Contenu)
.NotEmpty()
.WithMessage("Le message ne peux pas être vide")
.MaximumLength(1000)
.WithMessage("Le message ne doit pas faire plus de 1000 caractères");
RuleFor(x => x.Date)
.NotEmpty()
.WithMessage("La date ne peut pas être vide");
RuleFor(x => x.Type)
.NotEmpty()
.WithMessage("Le type de message doit être renseigné");
}
}

View File

@@ -0,0 +1,6 @@
namespace Knots.Validators.Message;
public class DeleteMessageDtoValidator
{
}

View File

@@ -0,0 +1,6 @@
namespace Knots.Validators.Message;
public class GetMessageDtoValidator
{
}

View File

@@ -0,0 +1,6 @@
namespace Knots.Validators.Message;
public class UpdateMessagesDto
{
}

View File

@@ -0,0 +1,17 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Role;
namespace Knots.Validators.Role;
public class CreateRoleDtoValidator : Validator<CreateRoleDto>
{
public CreateRoleDtoValidator()
{
RuleFor(x => x.Libelle)
.NotEmpty()
.WithMessage("Libelle cannot be empty")
.MaximumLength(50)
.WithMessage("Libelle maximum length is 50");
}
}

View File

@@ -0,0 +1,15 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Role;
namespace Knots.Validators.Role;
public class DeleteRoleDtoValidator : Validator<DeleteRoleDto>
{
public DeleteRoleDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("Id cannot be empty");
}
}

View File

@@ -0,0 +1,17 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.Role;
namespace Knots.Validators.Role;
public class GetRoleDtoValidator : Validator<GetRoleDto>
{
public GetRoleDtoValidator()
{
RuleFor(x => x.Libelle)
.NotEmpty()
.WithMessage("Libelle cannot be empty")
.MaximumLength(50)
.WithMessage("Libelle maximum length is 50");
}
}

View File

@@ -0,0 +1,6 @@
namespace Knots.Validators.User;
public class CreateUserDtoValidator
{
}

View File

@@ -0,0 +1,6 @@
namespace Knots.Validators.User;
public class DeleteUserDtoValidator
{
}

View File

@@ -0,0 +1,6 @@
namespace Knots.Validators.User;
public class GetUserDtoValidator
{
}

View File

@@ -0,0 +1,27 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.User;
namespace Knots.Validators.User;
public class UpdateUserContactDtoValidator : Validator<UpdateUserContactDto>
{
public UpdateUserContactDtoValidator()
{
RuleFor(x => x.Id)
.NotEmpty()
.WithMessage("L'id est requis")
.GreaterThan(0)
.WithMessage("L'id doit être supérieur à 0");
RuleFor(x => x.Email)
.NotEmpty()
.WithMessage("L'email est requis")
.EmailAddress()
.WithMessage("Ce n'est pas un email valide");
RuleFor(x => x.Tel)
.NotEmpty()
.WithMessage("Le numéro de téléphone est requis");
}
}

View File

@@ -0,0 +1,15 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.User;
namespace Knots.Validators.User;
public class UpdateUserDescriptionDtoValidator : Validator<UpdateUserDescriptionDto>
{
public UpdateUserDescriptionDtoValidator()
{
RuleFor(x => x.Description)
.MaximumLength(200)
.WithMessage("La description ne doit pas dépasser les 200 caractères");
}
}

View File

@@ -0,0 +1,6 @@
namespace Knots.Validators.User;
public class UpdateUserDtoValidator
{
}

View File

@@ -0,0 +1,15 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.User;
namespace Knots.Validators.User;
public class UpdateUserProfilePictureDtoValidator : Validator<UpdateUserProfilePictureDto>
{
public UpdateUserProfilePictureDtoValidator()
{
RuleFor(x => x.ProfilePicture)
.NotEmpty()
.WithMessage("La photo de profil ne doit pas être vide");
}
}

View File

@@ -0,0 +1,17 @@
using FastEndpoints;
using FluentValidation;
using Knots.DTO.User;
namespace Knots.Validators.User;
public class UpdateUsernameDtoValidator : Validator<UpdateUsernameDto>
{
public UpdateUsernameDtoValidator()
{
RuleFor(x => x.Username)
.NotEmpty()
.WithMessage("Le nom d'utilisateur doit être renseigné")
.MaximumLength(50)
.WithMessage("Le nom d'utilisateur ne doit pas dépasser les 50 caractères");
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More