Currency creation and minting with basis of transactions
This commit is contained in:
@ -79,10 +79,7 @@ namespace IO.Swagger.Controllers
|
||||
public virtual async Task<IActionResult> LoginUser([FromBody]AuthLoginBody body)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
var errors = ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage));
|
||||
return BadRequest(errors);
|
||||
}
|
||||
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
||||
var user = await repository.LoginUser(body);
|
||||
return user == null ? Unauthorized() : Ok(new { token = jwt.GenerateJwt(user.Id) });
|
||||
}
|
||||
@ -102,10 +99,7 @@ namespace IO.Swagger.Controllers
|
||||
public async Task<IActionResult> RegisterUser([FromBody]AuthRegisterBody body)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
var errors = ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage));
|
||||
return BadRequest(errors);
|
||||
}
|
||||
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
||||
|
||||
var user = await repository.RegisterUser(body);
|
||||
return user == null ? StatusCode(409) : Ok(new { token = jwt.GenerateJwt(user.Id) });
|
||||
|
||||
@ -18,6 +18,10 @@ using IO.Swagger.Attributes;
|
||||
using IO.Swagger.Security;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using IO.Swagger.Models.dto;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using IO.Swagger.Repositories;
|
||||
|
||||
namespace IO.Swagger.Controllers
|
||||
{
|
||||
@ -27,6 +31,13 @@ namespace IO.Swagger.Controllers
|
||||
[ApiController]
|
||||
public class CurrencyApiController : ControllerBase
|
||||
{
|
||||
private readonly ICurrencyRepository repo;
|
||||
|
||||
public CurrencyApiController(ICurrencyRepository repo)
|
||||
{
|
||||
this.repo = repo ?? throw new ArgumentNullException(nameof(repo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a digital asset to the user's collection
|
||||
/// </summary>
|
||||
@ -86,23 +97,23 @@ namespace IO.Swagger.Controllers
|
||||
/// <response code="201">Currency type created successfully</response>
|
||||
/// <response code="400">Bad Request</response>
|
||||
/// <response code="401">Unauthorized</response>
|
||||
/// <response code="422">Unprocessable Content</response>
|
||||
[HttpPost]
|
||||
[Route("/v1/api/currency/create")]
|
||||
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
||||
[ValidateModelState]
|
||||
[SwaggerOperation("CreateCurrency")]
|
||||
public virtual IActionResult CreateCurrency([FromBody]CurrencyCreateBody body)
|
||||
public virtual async Task<IActionResult> CreateCurrency([FromBody]CurrencyCreateBody body)
|
||||
{
|
||||
//TODO: Uncomment the next line to return response 201 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
||||
// return StatusCode(201);
|
||||
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
||||
if (!int.TryParse(userIdString, out int userId))
|
||||
return Unauthorized();
|
||||
|
||||
//TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
||||
// return StatusCode(400);
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
||||
|
||||
//TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
||||
// return StatusCode(401);
|
||||
|
||||
throw new NotImplementedException();
|
||||
var createdCurr = await repo.CreateCurrency(body, userId);
|
||||
return createdCurr ? StatusCode(201) : StatusCode(422);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -112,23 +123,22 @@ namespace IO.Swagger.Controllers
|
||||
/// <response code="200">Successful minting</response>
|
||||
/// <response code="400">Bad Request</response>
|
||||
/// <response code="401">Unauthorized</response>
|
||||
/// <response code="409">Conflict - User is not owner or currency does not exist</response>
|
||||
[HttpPost]
|
||||
[Route("/v1/api/currency/mint")]
|
||||
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
|
||||
[ValidateModelState]
|
||||
[SwaggerOperation("MintCurrency")]
|
||||
public virtual IActionResult MintCurrency([FromBody]CurrencyMintBody body)
|
||||
public virtual async Task<IActionResult> MintCurrency([FromBody]CurrencyMintBody body)
|
||||
{
|
||||
//TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
||||
// return StatusCode(200);
|
||||
var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
|
||||
if (!int.TryParse(userIdString, out int userId))
|
||||
return Unauthorized();
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)));
|
||||
|
||||
//TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
||||
// return StatusCode(400);
|
||||
|
||||
//TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
|
||||
// return StatusCode(401);
|
||||
|
||||
throw new NotImplementedException();
|
||||
var minted = await repo.MintCurrency(body, userId);
|
||||
return minted ? Ok() : StatusCode(409);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
177
src/IO.Swagger/Migrations/20230819185130_Started transactions and currencies.Designer.cs
generated
Normal file
177
src/IO.Swagger/Migrations/20230819185130_Started transactions and currencies.Designer.cs
generated
Normal file
@ -0,0 +1,177 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using IO.Swagger.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IO.Swagger.Migrations
|
||||
{
|
||||
[DbContext(typeof(BankDbContext))]
|
||||
[Migration("20230819185130_Started transactions and currencies")]
|
||||
partial class Startedtransactionsandcurrencies
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Currency", b =>
|
||||
{
|
||||
b.Property<int>("CurrencyId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("CurrencyId"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("nvarchar(32)");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.HasMaxLength(4)
|
||||
.HasColumnType("nvarchar(4)");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("CurrencyId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Transaction", b =>
|
||||
{
|
||||
b.Property<int>("TransactionId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("TransactionId"));
|
||||
|
||||
b.Property<float>("Amount")
|
||||
.HasColumnType("real");
|
||||
|
||||
b.Property<int>("CurrencyId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("FromUserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Memo")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("nvarchar(32)");
|
||||
|
||||
b.Property<int>("ToUserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("TransactionTime")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.HasKey("TransactionId");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.HasIndex("FromUserId");
|
||||
|
||||
b.HasIndex("ToUserId");
|
||||
|
||||
b.ToTable("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("nvarchar(32)");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("nvarchar(32)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Currency", b =>
|
||||
{
|
||||
b.HasOne("IO.Swagger.Models.db.User", "User")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Transaction", b =>
|
||||
{
|
||||
b.HasOne("IO.Swagger.Models.db.Currency", "Currency")
|
||||
.WithMany("Transactions")
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("IO.Swagger.Models.db.User", "FromUser")
|
||||
.WithMany("TransactionsFrom")
|
||||
.HasForeignKey("FromUserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("IO.Swagger.Models.db.User", "ToUser")
|
||||
.WithMany("TransactionsTo")
|
||||
.HasForeignKey("ToUserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
|
||||
b.Navigation("FromUser");
|
||||
|
||||
b.Navigation("ToUser");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Currency", b =>
|
||||
{
|
||||
b.Navigation("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.User", b =>
|
||||
{
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("TransactionsFrom");
|
||||
|
||||
b.Navigation("TransactionsTo");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IO.Swagger.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Startedtransactionsandcurrencies : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Currencies",
|
||||
columns: table => new
|
||||
{
|
||||
CurrencyId = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Name = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true),
|
||||
Symbol = table.Column<string>(type: "nvarchar(4)", maxLength: 4, nullable: true),
|
||||
UserId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Currencies", x => x.CurrencyId);
|
||||
table.ForeignKey(
|
||||
name: "FK_Currencies_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Transactions",
|
||||
columns: table => new
|
||||
{
|
||||
TransactionId = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
FromUserId = table.Column<int>(type: "int", nullable: false),
|
||||
ToUserId = table.Column<int>(type: "int", nullable: false),
|
||||
Amount = table.Column<float>(type: "real", nullable: false),
|
||||
Memo = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: false),
|
||||
CurrencyId = table.Column<int>(type: "int", nullable: false),
|
||||
TransactionTime = table.Column<DateTime>(type: "datetime2", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Transactions", x => x.TransactionId);
|
||||
table.ForeignKey(
|
||||
name: "FK_Transactions_Currencies_CurrencyId",
|
||||
column: x => x.CurrencyId,
|
||||
principalTable: "Currencies",
|
||||
principalColumn: "CurrencyId");
|
||||
table.ForeignKey(
|
||||
name: "FK_Transactions_Users_FromUserId",
|
||||
column: x => x.FromUserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_Transactions_Users_ToUserId",
|
||||
column: x => x.ToUserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Currencies_UserId",
|
||||
table: "Currencies",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Transactions_CurrencyId",
|
||||
table: "Transactions",
|
||||
column: "CurrencyId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Transactions_FromUserId",
|
||||
table: "Transactions",
|
||||
column: "FromUserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Transactions_ToUserId",
|
||||
table: "Transactions",
|
||||
column: "ToUserId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Transactions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Currencies");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using IO.Swagger.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
@ -21,6 +22,71 @@ namespace IO.Swagger.Migrations
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Currency", b =>
|
||||
{
|
||||
b.Property<int>("CurrencyId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("CurrencyId"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("nvarchar(32)");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.HasMaxLength(4)
|
||||
.HasColumnType("nvarchar(4)");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("CurrencyId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Transaction", b =>
|
||||
{
|
||||
b.Property<int>("TransactionId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("TransactionId"));
|
||||
|
||||
b.Property<float>("Amount")
|
||||
.HasColumnType("real");
|
||||
|
||||
b.Property<int>("CurrencyId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("FromUserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Memo")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("nvarchar(32)");
|
||||
|
||||
b.Property<int>("ToUserId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("TransactionTime")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.HasKey("TransactionId");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.HasIndex("FromUserId");
|
||||
|
||||
b.HasIndex("ToUserId");
|
||||
|
||||
b.ToTable("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -50,6 +116,58 @@ namespace IO.Swagger.Migrations
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Currency", b =>
|
||||
{
|
||||
b.HasOne("IO.Swagger.Models.db.User", "User")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Transaction", b =>
|
||||
{
|
||||
b.HasOne("IO.Swagger.Models.db.Currency", "Currency")
|
||||
.WithMany("Transactions")
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("IO.Swagger.Models.db.User", "FromUser")
|
||||
.WithMany("TransactionsFrom")
|
||||
.HasForeignKey("FromUserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("IO.Swagger.Models.db.User", "ToUser")
|
||||
.WithMany("TransactionsTo")
|
||||
.HasForeignKey("ToUserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
|
||||
b.Navigation("FromUser");
|
||||
|
||||
b.Navigation("ToUser");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.Currency", b =>
|
||||
{
|
||||
b.Navigation("Transactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IO.Swagger.Models.db.User", b =>
|
||||
{
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("TransactionsFrom");
|
||||
|
||||
b.Navigation("TransactionsTo");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
||||
23
src/IO.Swagger/Models/db/Currency.cs
Normal file
23
src/IO.Swagger/Models/db/Currency.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace IO.Swagger.Models.db
|
||||
{
|
||||
public class Currency
|
||||
{
|
||||
public int CurrencyId { get; set; }
|
||||
[StringLength(32, MinimumLength = 1)]
|
||||
public string Name { get; set; }
|
||||
[StringLength(4, MinimumLength = 1)]
|
||||
public string Symbol { get; set; }
|
||||
|
||||
[ForeignKey("FK_Currency_UserId")]
|
||||
public int UserId { get; set; }
|
||||
public User User { get; set; }
|
||||
|
||||
public ICollection<Transaction> Transactions { get; set; }
|
||||
}
|
||||
}
|
||||
28
src/IO.Swagger/Models/db/Transaction.cs
Normal file
28
src/IO.Swagger/Models/db/Transaction.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.VisualBasic;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace IO.Swagger.Models.db
|
||||
{
|
||||
public class Transaction
|
||||
{
|
||||
public int TransactionId { get; set; }
|
||||
public int FromUserId { get; set; }
|
||||
public User FromUser { get; set; }
|
||||
public int ToUserId { get; set; }
|
||||
public User ToUser { get; set; }
|
||||
|
||||
[Range(0.01, float.MaxValue)]
|
||||
public float Amount { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(32, MinimumLength = 2)]
|
||||
public string Memo { get; set; }
|
||||
|
||||
public Currency Currency { get; set; }
|
||||
public int CurrencyId { get; set; }
|
||||
|
||||
public DateTime TransactionTime { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace IO.Swagger.Models.db
|
||||
{
|
||||
@ -12,6 +14,11 @@ namespace IO.Swagger.Models.db
|
||||
public string LastName { get; set; }
|
||||
public string PasswordHash { get; set; }
|
||||
public string Salt { get; set; }
|
||||
|
||||
public ICollection<Currency> Currencies { get; set; }
|
||||
|
||||
public ICollection<Transaction> TransactionsFrom { get; set; }
|
||||
public ICollection<Transaction> TransactionsTo { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -31,14 +31,16 @@ namespace IO.Swagger.Models.dto
|
||||
/// </summary>
|
||||
|
||||
[DataMember(Name = "currencyId")]
|
||||
public int? CurrencyId { get; set; }
|
||||
[Required]
|
||||
public int CurrencyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets Amount
|
||||
/// </summary>
|
||||
|
||||
[Required]
|
||||
[DataMember(Name = "amount")]
|
||||
public decimal? Amount { get; set; }
|
||||
public float Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string presentation of the object
|
||||
|
||||
55
src/IO.Swagger/Repositories/CurrencyRepository.cs
Normal file
55
src/IO.Swagger/Repositories/CurrencyRepository.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using IO.Swagger.Models.db;
|
||||
using IO.Swagger.Models.dto;
|
||||
using IO.Swagger.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IO.Swagger.Repositories
|
||||
{
|
||||
public class CurrencyRepository : ICurrencyRepository
|
||||
{
|
||||
BankDbContext context;
|
||||
|
||||
public CurrencyRepository(BankDbContext context)
|
||||
{
|
||||
this.context = context ?? throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
public async Task<bool> CreateCurrency(CurrencyCreateBody request, int userId)
|
||||
{
|
||||
request.Symbol = request.Symbol.Trim();
|
||||
request.Name = request.Name.Trim();
|
||||
if (await context.Currencies.AnyAsync(c => c.Symbol == request.Symbol || c.Name.ToLower() == request.Name.ToLower()))
|
||||
return false;
|
||||
|
||||
await context.Currencies.AddAsync(new Currency
|
||||
{
|
||||
Name = request.Name,
|
||||
Symbol = request.Symbol,
|
||||
UserId = userId
|
||||
});
|
||||
|
||||
return await context.SaveChangesAsync() > 0;
|
||||
}
|
||||
|
||||
public async Task<bool> MintCurrency(CurrencyMintBody request, int userId)
|
||||
{
|
||||
var existsAndIsOwner = await context.Currencies.AnyAsync(c => c.CurrencyId == request.CurrencyId && c.UserId == userId);
|
||||
if (!existsAndIsOwner)
|
||||
return false;
|
||||
|
||||
await context.Transactions.AddAsync(new Transaction
|
||||
{
|
||||
Amount = request.Amount,
|
||||
CurrencyId = request.CurrencyId,
|
||||
ToUserId = userId,
|
||||
FromUserId = userId,
|
||||
Memo = "Minting"
|
||||
});
|
||||
|
||||
return await context.SaveChangesAsync() > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/IO.Swagger/Repositories/ICurrencyRepository.cs
Normal file
11
src/IO.Swagger/Repositories/ICurrencyRepository.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using IO.Swagger.Models.dto;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IO.Swagger.Repositories
|
||||
{
|
||||
public interface ICurrencyRepository
|
||||
{
|
||||
Task<bool> CreateCurrency(CurrencyCreateBody request, int userId);
|
||||
Task<bool> MintCurrency(CurrencyMintBody request, int userId);
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,44 @@ namespace IO.Swagger.Services
|
||||
}
|
||||
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<Currency> Currencies { get; set; }
|
||||
public DbSet<Transaction> Transactions { get; set; }
|
||||
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// currency -> user FK
|
||||
modelBuilder.Entity<User>()
|
||||
.HasMany(u => u.Currencies)
|
||||
.WithOne(c => c.User)
|
||||
.HasForeignKey(c => c.UserId)
|
||||
.HasPrincipalKey(u => u.Id)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
|
||||
// transaction -> from user
|
||||
modelBuilder.Entity<User>()
|
||||
.HasMany(u => u.TransactionsFrom)
|
||||
.WithOne(t => t.FromUser)
|
||||
.HasForeignKey(t => t.FromUserId)
|
||||
.HasPrincipalKey(u => u.Id)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
// transaction -> to user
|
||||
modelBuilder.Entity<User>()
|
||||
.HasMany(u => u.TransactionsTo)
|
||||
.WithOne(t => t.ToUser)
|
||||
.HasForeignKey(t => t.ToUserId)
|
||||
.HasPrincipalKey(u => u.Id)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
// transaction -> currency
|
||||
modelBuilder.Entity<Transaction>()
|
||||
.HasOne(t => t.Currency)
|
||||
.WithMany(c => c.Transactions)
|
||||
.HasForeignKey(t => t.CurrencyId)
|
||||
.HasPrincipalKey(c => c.CurrencyId)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ namespace IO.Swagger
|
||||
}
|
||||
Console.WriteLine(connectionString);
|
||||
services.AddScoped<IUserRepository, UserRepository>();
|
||||
//services.AddScoped<ICurrencyRepository, CurrencyRepository>();
|
||||
services.AddScoped<ICurrencyRepository, CurrencyRepository>();
|
||||
services.AddDbContext<BankDbContext>(x => x.UseSqlServer(connectionString: connectionString));
|
||||
services.AddSingleton<JwtService>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user