fix routes, tactic steps

tests
Maxime BATISTA 9 months ago
parent 32913b791b
commit 19ec55009b

1
.gitignore vendored

@ -6,6 +6,7 @@
# Build results
efbundle
Migrations
[Dd]ebug/
[Rr]elease/

@ -48,6 +48,22 @@ public class TacticController(ITacticService service) : ControllerBase
return result != null ? Ok(result.ToDto()) : NotFound();
}
public record GetTacticStepsTreeResponse(TacticStepDto Root);
[HttpGet("/tactics/{tacticId:int}/tree")]
[Authorize]
public async Task<IActionResult> GetTacticStepsRoot(int tacticId)
{
var userId = this.CurrentUserId();
if (!await service.HasAnyRights(userId, tacticId))
{
return Unauthorized();
}
var root = (await service.GetRootStep(tacticId)).ToDto();
return Ok(new GetTacticStepsTreeResponse(root));
}
public record CreateNewRequest(
[StringLength(50, MinimumLength = 1)]
@ -70,14 +86,24 @@ public class TacticController(ITacticService service) : ControllerBase
"HALF" => CourtType.Half,
_ => throw new ArgumentOutOfRangeException() //unreachable
};
var id = await service.CreateNew(userId, req.Name, courtType);
var id = await service.AddTactic(userId, req.Name, courtType);
return new CreateNewResponse(id);
}
private record GetStepContentResponse(string Content);
public record AddStepRequest(int ParentId, object Content);
public record AddStepResponse(int StepId);
[HttpGet("/tactics/{tacticId:int}/{stepId:int}")]
[HttpPost("/tactics/{tacticId:int}/steps")]
public async Task<IActionResult> AddStep(int tacticId, [FromBody] AddStepRequest req)
{
var stepId = await service.AddTacticStep(tacticId, req.ParentId, JsonSerializer.Serialize(req.Content));
return stepId != null ? Ok(new AddStepResponse(stepId ?? 0)) : NotFound();
}
[HttpGet("/tactics/{tacticId:int}/steps/{stepId:int}")]
[Authorize]
public async Task<IActionResult> GetStepContent(int tacticId, int stepId)
{
@ -89,13 +115,28 @@ public class TacticController(ITacticService service) : ControllerBase
}
var json = await service.GetTacticStepContent(tacticId, stepId);
return Ok(new GetStepContentResponse(json!));
return json != null ? Ok(JsonSerializer.Deserialize<object>(json)) : NotFound();
}
[HttpDelete("/tactics/{tacticId:int}/steps/{stepId:int}")]
[Authorize]
public async Task<IActionResult> RemoveStepContent(int tacticId, int stepId)
{
var userId = this.CurrentUserId();
if (!await service.HasAnyRights(userId, tacticId))
{
return Unauthorized();
}
var found = await service.RemoveTacticStep(tacticId, stepId);
return found ? Ok() : NotFound();
}
public record SaveStepContentRequest(object Content);
[HttpPut("/tactics/{tacticId:int}/{stepId:int}")]
[HttpPut("/tactics/{tacticId:int}/steps/{stepId:int}")]
[Authorize]
public async Task<IActionResult> SaveStepContent(int tacticId, int stepId, [FromBody] SaveStepContentRequest req)
{

@ -8,4 +8,9 @@ public static class ModelToDto
{
return new TacticDto(t.Id, t.Name, t.OwnerId, t.CourtType.ToString().ToUpper(), new DateTimeOffset(t.CreationDate).ToUnixTimeMilliseconds());
}
public static TacticStepDto ToDto(this TacticStep t)
{
return new TacticStepDto(t.Id, t.Parent, t.Children.Select(s => s.ToDto()));
}
}

@ -0,0 +1,3 @@
namespace API.DTO;
public record TacticStepDto(int Id, int? ParentId, IEnumerable<TacticStepDto> Children);

@ -57,9 +57,6 @@ public class AppContext : DbContext
builder.Entity<MemberEntity>()
.HasKey("UserId", "TeamId");
builder.Entity<TacticStepEntity>()
.HasKey("TacticId", "StepId");
}
private static string HashString(string str)

@ -4,12 +4,16 @@ namespace AppContext.Entities;
public class TacticStepEntity
{
public int Id { get; set; }
public required int TacticId { get; set; }
public Tactic Tactic { get; set; }
public required int ParentId { get; set; }
public TacticStepEntity Parent { get; set; }
public IEnumerable<TacticStepEntity> Children { get; set; } = new List<TacticStepEntity>();
public required int? ParentId { get; set; }
public TacticStepEntity? Parent { get; set; }
public int StepId { get; set; }
public required string JsonContent { get; set; }

@ -1,221 +0,0 @@
// <auto-generated />
using System;
using AppContext;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AppContext.Migrations
{
[DbContext(typeof(AppContext))]
[Migration("20240218173232_m1")]
partial class m1
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.Property<int>("UserId")
.HasColumnType("INTEGER");
b.Property<int>("TeamId")
.HasColumnType("INTEGER");
b.Property<string>("Role")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("UserId", "TeamId");
b.HasIndex("TeamId");
b.ToTable("Members");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tactics");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.Property<int>("TacticId")
.HasColumnType("INTEGER");
b.Property<int>("StepId")
.HasColumnType("INTEGER");
b.Property<string>("JsonContent")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("ParentId")
.HasColumnType("INTEGER");
b.Property<int?>("ParentStepId")
.HasColumnType("INTEGER");
b.Property<int?>("ParentTacticId")
.HasColumnType("INTEGER");
b.HasKey("TacticId", "StepId");
b.HasIndex("ParentTacticId", "ParentStepId");
b.ToTable("TacticSteps");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("MainColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Picture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SecondColor")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Teams");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProfilePicture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<byte[]>("Salt")
.IsRequired()
.HasColumnType("BLOB");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.HasOne("AppContext.Entities.TeamEntity", "Team")
.WithMany("Members")
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.UserEntity", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Team");
b.Navigation("User");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.HasOne("AppContext.Entities.UserEntity", "Owner")
.WithMany("Tactics")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.HasOne("AppContext.Entities.TacticEntity", "Tactic")
.WithMany()
.HasForeignKey("TacticId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.TacticStepEntity", "Parent")
.WithMany("Children")
.HasForeignKey("ParentTacticId", "ParentStepId");
b.Navigation("Parent");
b.Navigation("Tactic");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.Navigation("Children");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Navigation("Members");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Navigation("Tactics");
});
#pragma warning restore 612, 618
}
}
}

@ -1,157 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AppContext.Migrations
{
/// <inheritdoc />
public partial class m1 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Teams",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: false),
Picture = table.Column<string>(type: "TEXT", nullable: false),
MainColor = table.Column<string>(type: "TEXT", nullable: false),
SecondColor = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Teams", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Password = table.Column<string>(type: "TEXT", nullable: false),
Salt = table.Column<byte[]>(type: "BLOB", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Email = table.Column<string>(type: "TEXT", nullable: false),
ProfilePicture = table.Column<string>(type: "TEXT", nullable: false),
IsAdmin = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Members",
columns: table => new
{
TeamId = table.Column<int>(type: "INTEGER", nullable: false),
UserId = table.Column<int>(type: "INTEGER", nullable: false),
Role = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Members", x => new { x.UserId, x.TeamId });
table.ForeignKey(
name: "FK_Members_Teams_TeamId",
column: x => x.TeamId,
principalTable: "Teams",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Members_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Tactics",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: false),
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false),
OwnerId = table.Column<int>(type: "INTEGER", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Tactics", x => x.Id);
table.ForeignKey(
name: "FK_Tactics_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TacticSteps",
columns: table => new
{
TacticId = table.Column<int>(type: "INTEGER", nullable: false),
StepId = table.Column<int>(type: "INTEGER", nullable: false),
ParentId = table.Column<int>(type: "INTEGER", nullable: true),
ParentTacticId = table.Column<int>(type: "INTEGER", nullable: true),
ParentStepId = table.Column<int>(type: "INTEGER", nullable: true),
JsonContent = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TacticSteps", x => new { x.TacticId, x.StepId });
table.ForeignKey(
name: "FK_TacticSteps_TacticSteps_ParentTacticId_ParentStepId",
columns: x => new { x.ParentTacticId, x.ParentStepId },
principalTable: "TacticSteps",
principalColumns: new[] { "TacticId", "StepId" });
table.ForeignKey(
name: "FK_TacticSteps_Tactics_TacticId",
column: x => x.TacticId,
principalTable: "Tactics",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Members_TeamId",
table: "Members",
column: "TeamId");
migrationBuilder.CreateIndex(
name: "IX_Tactics_OwnerId",
table: "Tactics",
column: "OwnerId");
migrationBuilder.CreateIndex(
name: "IX_TacticSteps_ParentTacticId_ParentStepId",
table: "TacticSteps",
columns: new[] { "ParentTacticId", "ParentStepId" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Members");
migrationBuilder.DropTable(
name: "TacticSteps");
migrationBuilder.DropTable(
name: "Teams");
migrationBuilder.DropTable(
name: "Tactics");
migrationBuilder.DropTable(
name: "Users");
}
}
}

@ -1,218 +0,0 @@
// <auto-generated />
using System;
using AppContext;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AppContext.Migrations
{
[DbContext(typeof(AppContext))]
partial class AppContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.Property<int>("UserId")
.HasColumnType("INTEGER");
b.Property<int>("TeamId")
.HasColumnType("INTEGER");
b.Property<string>("Role")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("UserId", "TeamId");
b.HasIndex("TeamId");
b.ToTable("Members");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tactics");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.Property<int>("TacticId")
.HasColumnType("INTEGER");
b.Property<int>("StepId")
.HasColumnType("INTEGER");
b.Property<string>("JsonContent")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("ParentId")
.HasColumnType("INTEGER");
b.Property<int?>("ParentStepId")
.HasColumnType("INTEGER");
b.Property<int?>("ParentTacticId")
.HasColumnType("INTEGER");
b.HasKey("TacticId", "StepId");
b.HasIndex("ParentTacticId", "ParentStepId");
b.ToTable("TacticSteps");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("MainColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Picture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SecondColor")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Teams");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProfilePicture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<byte[]>("Salt")
.IsRequired()
.HasColumnType("BLOB");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.HasOne("AppContext.Entities.TeamEntity", "Team")
.WithMany("Members")
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.UserEntity", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Team");
b.Navigation("User");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.HasOne("AppContext.Entities.UserEntity", "Owner")
.WithMany("Tactics")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.HasOne("AppContext.Entities.TacticEntity", "Tactic")
.WithMany()
.HasForeignKey("TacticId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.TacticStepEntity", "Parent")
.WithMany("Children")
.HasForeignKey("ParentTacticId", "ParentStepId");
b.Navigation("Parent");
b.Navigation("Tactic");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.Navigation("Children");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Navigation("Members");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Navigation("Tactics");
});
#pragma warning restore 612, 618
}
}
}

@ -1,4 +1,5 @@
using AppContext.Entities;
using Microsoft.EntityFrameworkCore;
using Model;
namespace Converters;
@ -14,7 +15,19 @@ public static class EntitiesToModels
{
return new Tactic(entity.Id, entity.Name, entity.OwnerId, entity.Type, entity.CreationDate);
}
public static TacticStep ToModel(this TacticStepEntity entity, IQueryable<TacticStepEntity> steps)
{
return new TacticStep(
entity.StepId,
entity.ParentId,
steps.Where(s =>s.TacticId == entity.TacticId && s.ParentId == entity.StepId)
.AsEnumerable()
.Select(e => e.ToModel(steps)),
entity.JsonContent
);
}
public static Team ToModel(this TeamEntity entity)
{
return new Team(entity.Id, entity.Name, entity.Picture, entity.MainColor, entity.SecondColor);

@ -1,5 +0,0 @@
namespace DTO;
public class Class1
{
}

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

@ -28,6 +28,33 @@ public class DbTacticService(AppContext.AppContext context) : ITacticService
return tacticEntity.OwnerId == userId;
}
public async Task<int> AddTactic(int userId, string name, CourtType courtType)
{
var tacticEntity = new TacticEntity
{
Name = name,
CreationDate = DateTime.Now,
OwnerId = userId,
Type = courtType
};
await context.Tactics.AddAsync(tacticEntity);
await context.SaveChangesAsync();
var stepEntity = new TacticStepEntity
{
StepId = 1,
ParentId = null,
TacticId = tacticEntity.Id,
JsonContent = "{\"components\": []}"
};
await context.TacticSteps.AddAsync(stepEntity);
await context.SaveChangesAsync();
return tacticEntity.Id;
}
public async Task<bool> UpdateName(int tacticId, string name)
{
var entity = await context.Tactics.FirstOrDefaultAsync(t => t.Id == tacticId);
@ -57,6 +84,21 @@ public class DbTacticService(AppContext.AppContext context) : ITacticService
)?.JsonContent;
}
public async Task<TacticStep> GetRootStep(int tacticId)
{
return (await context.TacticSteps
.FirstAsync(e => e.TacticId == tacticId && e.ParentId == null))
.ToModel(context.TacticSteps);
}
public async Task<Tactic?> GetTactic(int tacticId)
{
return (await context.Tactics
.FirstOrDefaultAsync(s => s.Id == tacticId))
?.ToModel();
}
public Task<IEnumerable<Tactic>> ListUserTactics(int userId)
{
return Task.FromResult(context
@ -67,15 +109,25 @@ public class DbTacticService(AppContext.AppContext context) : ITacticService
);
}
public async Task<int> AddTacticStep(int tacticId, int parentStepId, string initialJson)
public async Task<int?> AddTacticStep(int tacticId, int parentStepId, string initialJson)
{
if (!context.Tactics.Any(t => t.Id == tacticId))
{
return null;
}
var nextStepId = context.TacticSteps
.Where(s => s.TacticId == tacticId)
.Max(s => s.StepId) + 1;
var entity = new TacticStepEntity
{
JsonContent = "{components: []}",
JsonContent = initialJson,
ParentId = parentStepId,
TacticId = tacticId
TacticId = tacticId,
StepId = nextStepId
};
await context.AddAsync(entity);
await context.SaveChangesAsync();
@ -84,15 +136,12 @@ public class DbTacticService(AppContext.AppContext context) : ITacticService
public async Task<bool> RemoveTacticStep(int tacticId, int stepId)
{
var toRemove = new List<int> { stepId };
var toRemove = new Stack<int>();
toRemove.Push(stepId);
while (toRemove.Count != 0)
while (toRemove.TryPop(out var id))
{
var id = toRemove[0];
toRemove.RemoveAt(0);
var step = await context.TacticSteps
.Include(s => s.Children)
.FirstOrDefaultAsync(t => t.TacticId == tacticId && t.StepId == id);
if (step == null)
@ -104,8 +153,11 @@ public class DbTacticService(AppContext.AppContext context) : ITacticService
);
}
var stepChildren = step.Children.Select(s => s.StepId);
toRemove.AddRange(stepChildren);
var stepChildren = context.TacticSteps.Where(s => s.ParentId == id);
foreach (var stepChild in stepChildren)
{
toRemove.Push(stepChild.StepId);
}
context.Remove(step);
}

@ -0,0 +1,3 @@
namespace Model;
public record TacticStep(int Id, int? Parent, IEnumerable<TacticStep> Children, string Content);

@ -9,10 +9,18 @@ public interface ITacticService
public Task<bool> HasAnyRights(int userId, int tacticId);
public Task<int> AddTactic(int userId, string name, CourtType courtType);
public Task<bool> UpdateName(int tacticId, string name);
public Task<bool> SetTacticStepContent(int tacticId, int stepId, string json);
public Task<string?> GetTacticStepContent(int tacticId, int stepId);
public Task<Tactic?> GetTactic(int tacticId);
public Task<TacticStep> GetRootStep(int tacticId);
public Task<IEnumerable<Tactic>> ListUserTactics(int userId);
public Task<int> AddTacticStep(int tacticId, int parentStepId, string initialJson);
public Task<int?> AddTacticStep(int tacticId, int parentStepId, string initialJson);
public Task<bool> RemoveTacticStep(int tacticId, int stepId);
}

@ -1,218 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using StubContext;
#nullable disable
namespace StubContext.Migrations
{
[DbContext(typeof(StubAppContext))]
[Migration("20240212203956_m1")]
partial class m1
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.Property<int>("TeamId")
.HasColumnType("INTEGER");
b.Property<int>("UserId")
.HasColumnType("INTEGER");
b.Property<string>("Role")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("TeamId", "UserId");
b.HasIndex("UserId");
b.ToTable("Members");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<string>("JsonContent")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tactics");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("MainColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Picture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SecondColor")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Teams");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProfilePicture")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Users");
b.HasData(
new
{
Id = 1,
Email = "maxime@mail.com",
IsAdmin = true,
Name = "maxime",
Password = "Abq2gmly3eYK29oU+krGTUfRH2MAka//xH4nqbZV1Ak=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 2,
Email = "mael@mail.com",
IsAdmin = true,
Name = "mael",
Password = "b4IE5XGndyILJn/ZgMdX9YH+rcux1Rvp9X4adjzXzto=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 3,
Email = "yanis@mail.com",
IsAdmin = true,
Name = "yanis",
Password = "XZOJugDxViwhvojERZCWfwocYdwICNTyl8VwNZjdVdM=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 4,
Email = "simon@mail.com",
IsAdmin = true,
Name = "simon",
Password = "FzsWErXcFnZrRwgY6j18tXdFzq+Jm+jmYKeOTFVMy68=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 5,
Email = "vivien@mail.com",
IsAdmin = true,
Name = "vivien",
Password = "6oIi8obqxLNGf1UdE6dFVbffc/+z93AoZiZieibD5vM=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
});
});
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.HasOne("AppContext.Entities.TeamEntity", "Team")
.WithMany("Members")
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.UserEntity", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Team");
b.Navigation("User");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.HasOne("AppContext.Entities.UserEntity", "Owner")
.WithMany("Tactics")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Navigation("Members");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Navigation("Tactics");
});
#pragma warning restore 612, 618
}
}
}

@ -1,136 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace StubContext.Migrations
{
/// <inheritdoc />
public partial class m1 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Teams",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: false),
Picture = table.Column<string>(type: "TEXT", nullable: false),
MainColor = table.Column<string>(type: "TEXT", nullable: false),
SecondColor = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Teams", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Password = table.Column<string>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Email = table.Column<string>(type: "TEXT", nullable: false),
ProfilePicture = table.Column<string>(type: "TEXT", nullable: false),
IsAdmin = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Members",
columns: table => new
{
TeamId = table.Column<int>(type: "INTEGER", nullable: false),
UserId = table.Column<int>(type: "INTEGER", nullable: false),
Role = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Members", x => new { x.TeamId, x.UserId });
table.ForeignKey(
name: "FK_Members_Teams_TeamId",
column: x => x.TeamId,
principalTable: "Teams",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Members_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Tactics",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: false),
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false),
OwnerId = table.Column<int>(type: "INTEGER", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false),
JsonContent = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Tactics", x => x.Id);
table.ForeignKey(
name: "FK_Tactics_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Users",
columns: new[] { "Id", "Email", "IsAdmin", "Name", "Password", "ProfilePicture" },
values: new object[,]
{
{ 1, "maxime@mail.com", true, "maxime", "lhrwN9GTh2+T/KWpOnGJTI5rt8mZVrljOtDRuYv9Xck=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png" },
{ 2, "mael@mail.com", true, "mael", "m+9+DO+fDO5BH33h6rpEvHwVlFTt4Xb0Sa3/qGmDymI=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png" },
{ 3, "yanis@mail.com", true, "yanis", "I63Z72IN7LSzp1nG18wX2yAN2kM16WOxMIIMI3o5Nno=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png" },
{ 4, "simon@mail.com", true, "simon", "SGbhGgYSXuQpyvdKOlTrUxJcrV3iBZGt5NFZiWtxKWw=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png" },
{ 5, "vivien@mail.com", true, "vivien", "v5dtqo9qg96d7ajz+DQlvVZ1Mbeu9RstFXtuhX5SGfo=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png" }
});
migrationBuilder.CreateIndex(
name: "IX_Members_UserId",
table: "Members",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Tactics_OwnerId",
table: "Tactics",
column: "OwnerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Members");
migrationBuilder.DropTable(
name: "Tactics");
migrationBuilder.DropTable(
name: "Teams");
migrationBuilder.DropTable(
name: "Users");
}
}
}

@ -1,268 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using StubContext;
#nullable disable
namespace StubContext.Migrations
{
[DbContext(typeof(StubAppContext))]
[Migration("20240221223713_m3")]
partial class m3
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.Property<int>("TeamId")
.HasColumnType("INTEGER");
b.Property<int>("UserId")
.HasColumnType("INTEGER");
b.Property<string>("Role")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("TeamId", "UserId");
b.HasIndex("UserId");
b.ToTable("Members");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tactics");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("JsonContent")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("ParentId")
.HasColumnType("INTEGER");
b.Property<int>("StepId")
.HasColumnType("INTEGER");
b.Property<int>("TacticId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("ParentId");
b.HasIndex("TacticId");
b.ToTable("TacticSteps");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("MainColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Picture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SecondColor")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Teams");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProfilePicture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<byte[]>("Salt")
.IsRequired()
.HasColumnType("BLOB");
b.HasKey("Id");
b.ToTable("Users");
b.HasData(
new
{
Id = 1,
Email = "maxime@mail.com",
IsAdmin = true,
Name = "maxime",
Password = "MA/xRuayPtWrv8x3Cgz5OzmlHs/d2kdqpsejjELTgVo=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 150, 122, 99, 167, 226, 248, 165, 213, 13, 3, 4, 9, 173, 71, 224, 221, 124, 172, 97, 145, 188, 142, 224, 77, 247, 77, 124, 37, 24, 107, 43, 189 }
},
new
{
Id = 2,
Email = "mael@mail.com",
IsAdmin = true,
Name = "mael",
Password = "d4SIGx08pW4fFOFycWyscF9MwGhN5/1b0NC1Qk23YCw=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 139, 244, 180, 246, 0, 73, 0, 219, 14, 221, 232, 49, 46, 122, 94, 50, 119, 154, 154, 53, 224, 187, 86, 230, 63, 73, 65, 232, 218, 136, 75, 142 }
},
new
{
Id = 3,
Email = "yanis@mail.com",
IsAdmin = true,
Name = "yanis",
Password = "rtqwioPIa+g4C7hlsJMynrxVjUYw1V09z21bA6nBORM=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 154, 78, 98, 162, 75, 166, 161, 47, 28, 160, 107, 245, 28, 33, 244, 213, 64, 247, 249, 28, 216, 58, 63, 44, 71, 179, 227, 67, 81, 146, 81, 87 }
},
new
{
Id = 4,
Email = "simon@mail.com",
IsAdmin = true,
Name = "simon",
Password = "RWebQFKoA5GHSVibfFwKJ+YrgliWiCjzHmDCQYA6h9Y=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 151, 193, 143, 48, 112, 90, 1, 91, 205, 85, 248, 129, 36, 50, 255, 5, 247, 95, 2, 156, 141, 189, 98, 4, 223, 179, 132, 19, 109, 43, 75, 43 }
},
new
{
Id = 5,
Email = "vivien@mail.com",
IsAdmin = true,
Name = "vivien",
Password = "aduT6b63cL7GYh6qX1VdL0YvQIDz7uXxwnqrM9SSzzU=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 163, 203, 253, 50, 184, 48, 93, 231, 249, 199, 182, 214, 40, 190, 70, 79, 53, 18, 26, 151, 57, 183, 166, 150, 179, 165, 48, 68, 12, 31, 129, 242 }
});
});
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.HasOne("AppContext.Entities.TeamEntity", "Team")
.WithMany("Members")
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.UserEntity", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Team");
b.Navigation("User");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.HasOne("AppContext.Entities.UserEntity", "Owner")
.WithMany("Tactics")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.HasOne("AppContext.Entities.TacticStepEntity", "Parent")
.WithMany()
.HasForeignKey("ParentId");
b.HasOne("AppContext.Entities.TacticEntity", "Tactic")
.WithMany()
.HasForeignKey("TacticId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
b.Navigation("Tactic");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Navigation("Members");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Navigation("Tactics");
});
#pragma warning restore 612, 618
}
}
}

@ -1,176 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace StubContext.Migrations
{
/// <inheritdoc />
public partial class m3 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Teams",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: false),
Picture = table.Column<string>(type: "TEXT", nullable: false),
MainColor = table.Column<string>(type: "TEXT", nullable: false),
SecondColor = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Teams", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Password = table.Column<string>(type: "TEXT", nullable: false),
Salt = table.Column<byte[]>(type: "BLOB", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false),
Email = table.Column<string>(type: "TEXT", nullable: false),
ProfilePicture = table.Column<string>(type: "TEXT", nullable: false),
IsAdmin = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Members",
columns: table => new
{
TeamId = table.Column<int>(type: "INTEGER", nullable: false),
UserId = table.Column<int>(type: "INTEGER", nullable: false),
Role = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Members", x => new { x.TeamId, x.UserId });
table.ForeignKey(
name: "FK_Members_Teams_TeamId",
column: x => x.TeamId,
principalTable: "Teams",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Members_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Tactics",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: false),
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false),
OwnerId = table.Column<int>(type: "INTEGER", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Tactics", x => x.Id);
table.ForeignKey(
name: "FK_Tactics_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "TacticSteps",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
TacticId = table.Column<int>(type: "INTEGER", nullable: false),
ParentId = table.Column<int>(type: "INTEGER", nullable: true),
StepId = table.Column<int>(type: "INTEGER", nullable: false),
JsonContent = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TacticSteps", x => x.Id);
table.ForeignKey(
name: "FK_TacticSteps_TacticSteps_ParentId",
column: x => x.ParentId,
principalTable: "TacticSteps",
principalColumn: "Id");
table.ForeignKey(
name: "FK_TacticSteps_Tactics_TacticId",
column: x => x.TacticId,
principalTable: "Tactics",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Users",
columns: new[] { "Id", "Email", "IsAdmin", "Name", "Password", "ProfilePicture", "Salt" },
values: new object[,]
{
{ 1, "maxime@mail.com", true, "maxime", "MA/xRuayPtWrv8x3Cgz5OzmlHs/d2kdqpsejjELTgVo=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png", new byte[] { 150, 122, 99, 167, 226, 248, 165, 213, 13, 3, 4, 9, 173, 71, 224, 221, 124, 172, 97, 145, 188, 142, 224, 77, 247, 77, 124, 37, 24, 107, 43, 189 } },
{ 2, "mael@mail.com", true, "mael", "d4SIGx08pW4fFOFycWyscF9MwGhN5/1b0NC1Qk23YCw=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png", new byte[] { 139, 244, 180, 246, 0, 73, 0, 219, 14, 221, 232, 49, 46, 122, 94, 50, 119, 154, 154, 53, 224, 187, 86, 230, 63, 73, 65, 232, 218, 136, 75, 142 } },
{ 3, "yanis@mail.com", true, "yanis", "rtqwioPIa+g4C7hlsJMynrxVjUYw1V09z21bA6nBORM=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png", new byte[] { 154, 78, 98, 162, 75, 166, 161, 47, 28, 160, 107, 245, 28, 33, 244, 213, 64, 247, 249, 28, 216, 58, 63, 44, 71, 179, 227, 67, 81, 146, 81, 87 } },
{ 4, "simon@mail.com", true, "simon", "RWebQFKoA5GHSVibfFwKJ+YrgliWiCjzHmDCQYA6h9Y=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png", new byte[] { 151, 193, 143, 48, 112, 90, 1, 91, 205, 85, 248, 129, 36, 50, 255, 5, 247, 95, 2, 156, 141, 189, 98, 4, 223, 179, 132, 19, 109, 43, 75, 43 } },
{ 5, "vivien@mail.com", true, "vivien", "aduT6b63cL7GYh6qX1VdL0YvQIDz7uXxwnqrM9SSzzU=", "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png", new byte[] { 163, 203, 253, 50, 184, 48, 93, 231, 249, 199, 182, 214, 40, 190, 70, 79, 53, 18, 26, 151, 57, 183, 166, 150, 179, 165, 48, 68, 12, 31, 129, 242 } }
});
migrationBuilder.CreateIndex(
name: "IX_Members_UserId",
table: "Members",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Tactics_OwnerId",
table: "Tactics",
column: "OwnerId");
migrationBuilder.CreateIndex(
name: "IX_TacticSteps_ParentId",
table: "TacticSteps",
column: "ParentId");
migrationBuilder.CreateIndex(
name: "IX_TacticSteps_TacticId",
table: "TacticSteps",
column: "TacticId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Members");
migrationBuilder.DropTable(
name: "TacticSteps");
migrationBuilder.DropTable(
name: "Teams");
migrationBuilder.DropTable(
name: "Tactics");
migrationBuilder.DropTable(
name: "Users");
}
}
}

@ -1,265 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using StubContext;
#nullable disable
namespace StubContext.Migrations
{
[DbContext(typeof(StubAppContext))]
[Migration("20240306225043_m8")]
partial class m8
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.Property<int>("TeamId")
.HasColumnType("INTEGER");
b.Property<int>("UserId")
.HasColumnType("INTEGER");
b.Property<string>("Role")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("TeamId", "UserId");
b.HasIndex("UserId");
b.ToTable("Members");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tactics");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("JsonContent")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("ParentId")
.HasColumnType("INTEGER");
b.Property<int>("TacticId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("ParentId");
b.HasIndex("TacticId");
b.ToTable("TacticSteps");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("MainColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Picture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SecondColor")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Teams");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProfilePicture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<byte[]>("Salt")
.IsRequired()
.HasColumnType("BLOB");
b.HasKey("Id");
b.ToTable("Users");
b.HasData(
new
{
Id = 1,
Email = "maxime@mail.com",
IsAdmin = true,
Name = "maxime",
Password = "cs6sYeniFuGPCc9vpIqfT55QoM81UQmQfCXj5Zs7ntQ=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 219, 58, 14, 214, 249, 185, 223, 243, 156, 162, 179, 40, 110, 116, 140, 235, 236, 189, 8, 126, 125, 98, 211, 121, 18, 143, 101, 72, 246, 167, 190, 180 }
},
new
{
Id = 2,
Email = "mael@mail.com",
IsAdmin = true,
Name = "mael",
Password = "7KlgzhGDNvmU0U6XrLxn2yByXS3cH/zGhMdp7YfEB0I=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 66, 149, 79, 107, 102, 133, 242, 64, 186, 228, 147, 19, 180, 220, 44, 136, 109, 113, 7, 105, 119, 124, 2, 143, 144, 210, 152, 190, 218, 198, 212, 20 }
},
new
{
Id = 3,
Email = "yanis@mail.com",
IsAdmin = true,
Name = "yanis",
Password = "c4WNJmzdK+W2yobGFAHCoi4U9LIocZAprxD+CZYYH/U=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 47, 0, 22, 126, 22, 151, 17, 116, 14, 185, 249, 205, 99, 227, 162, 199, 72, 196, 162, 149, 10, 80, 231, 77, 30, 156, 105, 208, 60, 50, 195, 10 }
},
new
{
Id = 4,
Email = "simon@mail.com",
IsAdmin = true,
Name = "simon",
Password = "x/mFMIqJPOIOUQLPtWykgx5h+cr+CQCuPqRKaEat170=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 125, 255, 139, 144, 133, 136, 63, 202, 189, 150, 61, 176, 48, 173, 95, 132, 57, 67, 19, 8, 183, 136, 252, 180, 167, 4, 159, 181, 191, 232, 116, 10 }
},
new
{
Id = 5,
Email = "vivien@mail.com",
IsAdmin = true,
Name = "vivien",
Password = "WO9P7aYnSHFe6YZkhiaJhPNHsP4Kj/PdtHmFlGJ7Tog=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png",
Salt = new byte[] { 182, 6, 140, 209, 134, 112, 40, 156, 196, 122, 95, 6, 97, 90, 172, 94, 224, 61, 31, 137, 148, 37, 128, 243, 66, 82, 115, 218, 53, 14, 144, 13 }
});
});
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.HasOne("AppContext.Entities.TeamEntity", "Team")
.WithMany("Members")
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.UserEntity", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Team");
b.Navigation("User");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.HasOne("AppContext.Entities.UserEntity", "Owner")
.WithMany("Tactics")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AppContext.Entities.TacticStepEntity", b =>
{
b.HasOne("AppContext.Entities.TacticStepEntity", "Parent")
.WithMany()
.HasForeignKey("ParentId");
b.HasOne("AppContext.Entities.TacticEntity", "Tactic")
.WithMany()
.HasForeignKey("TacticId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Parent");
b.Navigation("Tactic");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Navigation("Members");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Navigation("Tactics");
});
#pragma warning restore 612, 618
}
}
}

@ -1,99 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace StubContext.Migrations
{
/// <inheritdoc />
public partial class m8 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "StepId",
table: "TacticSteps");
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "Password", "Salt" },
values: new object[] { "cs6sYeniFuGPCc9vpIqfT55QoM81UQmQfCXj5Zs7ntQ=", new byte[] { 219, 58, 14, 214, 249, 185, 223, 243, 156, 162, 179, 40, 110, 116, 140, 235, 236, 189, 8, 126, 125, 98, 211, 121, 18, 143, 101, 72, 246, 167, 190, 180 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "Password", "Salt" },
values: new object[] { "7KlgzhGDNvmU0U6XrLxn2yByXS3cH/zGhMdp7YfEB0I=", new byte[] { 66, 149, 79, 107, 102, 133, 242, 64, 186, 228, 147, 19, 180, 220, 44, 136, 109, 113, 7, 105, 119, 124, 2, 143, 144, 210, 152, 190, 218, 198, 212, 20 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "Password", "Salt" },
values: new object[] { "c4WNJmzdK+W2yobGFAHCoi4U9LIocZAprxD+CZYYH/U=", new byte[] { 47, 0, 22, 126, 22, 151, 17, 116, 14, 185, 249, 205, 99, 227, 162, 199, 72, 196, 162, 149, 10, 80, 231, 77, 30, 156, 105, 208, 60, 50, 195, 10 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "Password", "Salt" },
values: new object[] { "x/mFMIqJPOIOUQLPtWykgx5h+cr+CQCuPqRKaEat170=", new byte[] { 125, 255, 139, 144, 133, 136, 63, 202, 189, 150, 61, 176, 48, 173, 95, 132, 57, 67, 19, 8, 183, 136, 252, 180, 167, 4, 159, 181, 191, 232, 116, 10 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "Password", "Salt" },
values: new object[] { "WO9P7aYnSHFe6YZkhiaJhPNHsP4Kj/PdtHmFlGJ7Tog=", new byte[] { 182, 6, 140, 209, 134, 112, 40, 156, 196, 122, 95, 6, 97, 90, 172, 94, 224, 61, 31, 137, 148, 37, 128, 243, 66, 82, 115, 218, 53, 14, 144, 13 } });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "StepId",
table: "TacticSteps",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "Password", "Salt" },
values: new object[] { "MA/xRuayPtWrv8x3Cgz5OzmlHs/d2kdqpsejjELTgVo=", new byte[] { 150, 122, 99, 167, 226, 248, 165, 213, 13, 3, 4, 9, 173, 71, 224, 221, 124, 172, 97, 145, 188, 142, 224, 77, 247, 77, 124, 37, 24, 107, 43, 189 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "Password", "Salt" },
values: new object[] { "d4SIGx08pW4fFOFycWyscF9MwGhN5/1b0NC1Qk23YCw=", new byte[] { 139, 244, 180, 246, 0, 73, 0, 219, 14, 221, 232, 49, 46, 122, 94, 50, 119, 154, 154, 53, 224, 187, 86, 230, 63, 73, 65, 232, 218, 136, 75, 142 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "Password", "Salt" },
values: new object[] { "rtqwioPIa+g4C7hlsJMynrxVjUYw1V09z21bA6nBORM=", new byte[] { 154, 78, 98, 162, 75, 166, 161, 47, 28, 160, 107, 245, 28, 33, 244, 213, 64, 247, 249, 28, 216, 58, 63, 44, 71, 179, 227, 67, 81, 146, 81, 87 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "Password", "Salt" },
values: new object[] { "RWebQFKoA5GHSVibfFwKJ+YrgliWiCjzHmDCQYA6h9Y=", new byte[] { 151, 193, 143, 48, 112, 90, 1, 91, 205, 85, 248, 129, 36, 50, 255, 5, 247, 95, 2, 156, 141, 189, 98, 4, 223, 179, 132, 19, 109, 43, 75, 43 } });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "Password", "Salt" },
values: new object[] { "aduT6b63cL7GYh6qX1VdL0YvQIDz7uXxwnqrM9SSzzU=", new byte[] { 163, 203, 253, 50, 184, 48, 93, 231, 249, 199, 182, 214, 40, 190, 70, 79, 53, 18, 26, 151, 57, 183, 166, 150, 179, 165, 48, 68, 12, 31, 129, 242 } });
}
}
}

@ -1,215 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using StubContext;
#nullable disable
namespace StubContext.Migrations
{
[DbContext(typeof(StubAppContext))]
partial class StubAppContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.Property<int>("TeamId")
.HasColumnType("INTEGER");
b.Property<int>("UserId")
.HasColumnType("INTEGER");
b.Property<string>("Role")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("TeamId", "UserId");
b.HasIndex("UserId");
b.ToTable("Members");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreationDate")
.HasColumnType("TEXT");
b.Property<string>("JsonContent")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("OwnerId")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Tactics");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("MainColor")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Picture")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SecondColor")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Teams");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("TEXT");
b.Property<bool>("IsAdmin")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProfilePicture")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("Users");
b.HasData(
new
{
Id = 1,
Email = "maxime@mail.com",
IsAdmin = true,
Name = "maxime",
Password = "cRJvoN/47sgLBqqriPmmThe0HRkZ0IvXw6qomIcnZ7M=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 2,
Email = "mael@mail.com",
IsAdmin = true,
Name = "mael",
Password = "opi1I908QEQ3POUbgBjHd/998dWJmvVTmRuDcxlv3do=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 3,
Email = "yanis@mail.com",
IsAdmin = true,
Name = "yanis",
Password = "7qmnCq6Kto7dEMhH7chzpqetNkbAMFhxLMxMKo599ws=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 4,
Email = "simon@mail.com",
IsAdmin = true,
Name = "simon",
Password = "Hzx7qgkwFMtVZsMp+DK6+ui8AGhbxSeCMC2bOdvLaQA=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
},
new
{
Id = 5,
Email = "vivien@mail.com",
IsAdmin = true,
Name = "vivien",
Password = "Cjntk37NpF7fct5OfJftgzeZi+ki4Y8aYHsKKm9RmBA=",
ProfilePicture = "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png"
});
});
modelBuilder.Entity("AppContext.Entities.MemberEntity", b =>
{
b.HasOne("AppContext.Entities.TeamEntity", "Team")
.WithMany("Members")
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AppContext.Entities.UserEntity", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Team");
b.Navigation("User");
});
modelBuilder.Entity("AppContext.Entities.TacticEntity", b =>
{
b.HasOne("AppContext.Entities.UserEntity", "Owner")
.WithMany("Tactics")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AppContext.Entities.TeamEntity", b =>
{
b.Navigation("Members");
});
modelBuilder.Entity("AppContext.Entities.UserEntity", b =>
{
b.Navigation("Tactics");
});
#pragma warning restore 612, 618
}
}
}
Loading…
Cancel
Save