Merge pull request 'ddd-refactor' (#2) from ddd-refactor into main
Some checks failed
BuildApp / build-frontend (push) Successful in 1m54s
BuildApp / build-backend (push) Failing after 26s

Reviewed-on: #2
This commit is contained in:
2025-11-28 11:14:42 +01:00
202 changed files with 5571 additions and 800 deletions

View File

@@ -0,0 +1,130 @@
name: Build Docker Images
on:
push:
branches:
- ddd-refactor
workflow_dispatch: {}
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: false
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: https://github.com/actions/checkout@v4
- name: Setup .NET 10
uses: https://github.com/actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- name: Restore dependencies
working-directory: src/Backend
run: |
dotnet restore DiunaBI.API/DiunaBI.API.csproj
dotnet restore DiunaBI.UI.Web/DiunaBI.UI.Web.csproj
dotnet restore DiunaBI.Plugins.Morska/DiunaBI.Plugins.Morska.csproj
dotnet restore DiunaBI.Tests/DiunaBI.Tests.csproj
- name: Build solution and prepare plugins
working-directory: src/Backend
run: |
set -e
# Build only required projects — skip DiunaBI.UI.Mobile
dotnet build DiunaBI.API/DiunaBI.API.csproj --configuration Release
dotnet build DiunaBI.UI.Web/DiunaBI.UI.Web.csproj --configuration Release
dotnet build DiunaBI.Plugins.Morska/DiunaBI.Plugins.Morska.csproj --configuration Release
mkdir -p DiunaBI.Tests/bin/Release/net10.0/Plugins
cp DiunaBI.Plugins.Morska/bin/Release/net10.0/DiunaBI.Plugins.Morska.dll DiunaBI.Tests/bin/Release/net10.0/Plugins/ || true
ls -la DiunaBI.Tests/bin/Release/net10.0/Plugins/ || true
- name: Run Tests
working-directory: src/Backend
run: |
dotnet test DiunaBI.Tests/DiunaBI.Tests.csproj \
--configuration Release \
--no-restore \
--logger "trx;LogFileName=test-results.trx" \
--collect:"XPlat Code Coverage" \
--filter "Category!=LocalOnly" || true
- name: Publish Test Results
uses: https://github.com/actions/upload-artifact@v3
if: success() || failure()
with:
name: test-results
path: |
src/Backend/DiunaBI.Tests/TestResults/*.trx
src/Backend/DiunaBI.Tests/TestResults/**/coverage.cobertura.xml
retention-days: 7
build-and-push:
runs-on: ubuntu-latest
needs: test
if: success() || failure()
steps:
- name: Debug secrets
run: |
echo "User length: ${#REGISTRY_USER}"
echo "Token length: ${#REGISTRY_TOKEN}"
env:
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
- name: Checkout code
uses: https://github.com/actions/checkout@v4
- name: Set up Docker Buildx
uses: https://github.com/docker/setup-buildx-action@v3
- name: Log in to Gitea Container Registry
run: |
echo "${{ secrets.REGISTRY_TOKEN }}" | docker login code.bim-it.pl -u "${{ secrets.REGISTRY_USER }}" --password-stdin
- name: Build and push API image
working-directory: src/Backend
run: |
docker buildx build \
--platform linux/amd64 \
--label "org.opencontainers.image.source=https://code.bim-it.pl/mz/DiunaBI" \
-f DiunaBI.API/Dockerfile \
-t code.bim-it.pl/mz/diunabi-api:latest \
-t code.bim-it.pl/mz/diunabi-api:build-${{ github.run_id }} \
--push \
.
- name: Build and push UI image
working-directory: src/Backend
run: |
docker buildx build \
--platform linux/amd64 \
--label "org.opencontainers.image.source=https://code.bim-it.pl/mz/DiunaBI" \
-f DiunaBI.UI.Web/Dockerfile \
-t code.bim-it.pl/mz/diunabi-ui:latest \
-t code.bim-it.pl/mz/diunabi-ui:build-${{ github.run_id }} \
--push \
.
- name: Output build info
run: |
echo "## 🐳 Docker Images Built" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Build ID:** ${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Images pushed:" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "# Latest (for release)" >> $GITHUB_STEP_SUMMARY
echo "docker pull code.bim-it.pl/mz/diunabi-api:latest" >> $GITHUB_STEP_SUMMARY
echo "docker pull code.bim-it.pl/mz/diunabi-ui:latest" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "# Specific build (for rollback)" >> $GITHUB_STEP_SUMMARY
echo "docker pull code.bim-it.pl/mz/diunabi-api:build-${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY
echo "docker pull code.bim-it.pl/mz/diunabi-ui:build-${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY

2
.gitignore vendored
View File

@@ -484,6 +484,8 @@ yarn-error.log
## ##
**/appsettings.Development.json **/appsettings.Development.json
**/appsettings.Local.json **/appsettings.Local.json
**/client_secrets.Development.json
**/client
*.p12 *.p12
*.key *.key
*.pem *.pem

View File

@@ -15,23 +15,23 @@ DOCKER_BACKUP_PATH=${DOCKER_BACKUP_DIR}/${BACKUP_FILE}
#SERVER VARIABLES #SERVER VARIABLES
REMOTE_HOST="bim-it.pl" REMOTE_HOST="bim-it.pl"
REMOTE_USER="mz" REMOTE_USER="mz"
REMOTE_SA_PASSWORD="v](8Lc|RfG" REMOTE_SA_PASSWORD="9832&^*&huihj"
REMOTE_BACKUP_DIR="/tmp" REMOTE_BACKUP_DIR="/tmp"
ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo rm ${REMOTE_BACKUP_DIR}/${BACKUP_FILE}" ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo rm ${REMOTE_BACKUP_DIR}/${BACKUP_FILE}"
ssh ${REMOTE_USER}@${REMOTE_HOST} "/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P '${REMOTE_SA_PASSWORD}' -Q \"BACKUP DATABASE [${DB_NAME}] TO DISK = '${REMOTE_BACKUP_DIR}/${BACKUP_FILE}'\"" ssh ${REMOTE_USER}@${REMOTE_HOST} "/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P '${REMOTE_SA_PASSWORD}' -Q \"BACKUP DATABASE [${DB_NAME}] TO DISK = '${REMOTE_BACKUP_DIR}/${BACKUP_FILE}'\""
scp ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_BACKUP_DIR}/${BACKUP_FILE} ${LOCAL_BACKUP_DIR}/ scp ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_BACKUP_DIR}/${BACKUP_FILE} ${LOCAL_BACKUP_DIR}/
docker exec -i ${DOCKER_CONTAINER_NAME} mkdir -p ${DOCKER_BACKUP_DIR} podman exec -i ${DOCKER_CONTAINER_NAME} mkdir -p ${DOCKER_BACKUP_DIR}
docker cp "${LOCAL_BACKUP_PATH}" "${DOCKER_CONTAINER_NAME}:${DOCKER_BACKUP_PATH}" podman cp "${LOCAL_BACKUP_PATH}" "${DOCKER_CONTAINER_NAME}:${DOCKER_BACKUP_PATH}"
docker exec --user=root -i ${DOCKER_CONTAINER_NAME} chown mssql:mssql "$DOCKER_BACKUP_PATH" podman exec --user=root -i ${DOCKER_CONTAINER_NAME} chown mssql:mssql "$DOCKER_BACKUP_PATH"
LOGICAL_FILE_INFO=$(docker exec -i ${DOCKER_CONTAINER_NAME} ${DOCKER_SQLCMD} -C -S localhost -U SA -P "${DOCKER_SA_PASSWORD}" -Q "RESTORE FILELISTONLY FROM DISK = '${DOCKER_BACKUP_PATH}'" 2>&1) LOGICAL_FILE_INFO=$(podman exec -i ${DOCKER_CONTAINER_NAME} ${DOCKER_SQLCMD} -C -S localhost -U SA -P "${DOCKER_SA_PASSWORD}" -Q "RESTORE FILELISTONLY FROM DISK = '${DOCKER_BACKUP_PATH}'" 2>&1)
DATA_FILE=$(echo "$LOGICAL_FILE_INFO" | awk 'NR==3 {print $1}' | tr -d '[:space:]') DATA_FILE=$(echo "$LOGICAL_FILE_INFO" | awk 'NR==3 {print $1}' | tr -d '[:space:]')
LOG_FILE=$(echo "$LOGICAL_FILE_INFO" | awk 'NR==4 {print $1}' | tr -d '[:space:]') LOG_FILE=$(echo "$LOGICAL_FILE_INFO" | awk 'NR==4 {print $1}' | tr -d '[:space:]')
RESTORE_OUTPUT=$( RESTORE_OUTPUT=$(
docker exec -i ${DOCKER_CONTAINER_NAME} ${DOCKER_SQLCMD} -C -S localhost -U SA -P "${DOCKER_SA_PASSWORD}" -Q " podman exec -i ${DOCKER_CONTAINER_NAME} ${DOCKER_SQLCMD} -C -S localhost -U SA -P "${DOCKER_SA_PASSWORD}" -Q "
IF EXISTS (SELECT name FROM sys.databases WHERE name = '${DB_NAME}') IF EXISTS (SELECT name FROM sys.databases WHERE name = '${DB_NAME}')
BEGIN BEGIN
PRINT 'Database ${DB_NAME} exists. Dropping the database.'; PRINT 'Database ${DB_NAME} exists. Dropping the database.';

View File

@@ -1,6 +1,6 @@
{ {
"sdk": { "sdk": {
"version": "8.0.0", "version": "10.0.100",
"rollForward": "latestFeature" "rollForward": "latestFeature"
} }
} }

View File

@@ -0,0 +1,21 @@
{
"permissions": {
"allow": [
"Bash(dotnet --version:*)",
"Bash(dotnet restore:*)",
"Bash(dotnet build:*)",
"Bash(dotnet ef:*)",
"Bash(dotnet tool install:*)",
"Bash(dotnet sln:*)",
"Bash(dotnet workload:*)",
"Bash(xcode-select:*)",
"Bash(xattr -cr:*)",
"Bash(dotnet clean:*)",
"Bash(xcrun simctl:*)",
"Bash(cat:*)",
"Bash(git checkout:*)"
],
"deny": [],
"ask": []
}
}

47
src/Backend/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,47 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "API",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-api",
"program": "${workspaceFolder}/DiunaBI.API/bin/Debug/net10.0/DiunaBI.API.dll",
"args": [],
"cwd": "${workspaceFolder}/DiunaBI.API",
"stopAtEntry": false,
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
{
"name": "Web",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-web",
"program": "${workspaceFolder}/DiunaBI.UI.Web/bin/Debug/net10.0/DiunaBI.UI.Web.dll",
"args": [],
"cwd": "${workspaceFolder}/DiunaBI.UI.Web",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)",
"uriFormat": "%s"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"browser": [
{
"osx": "Google Chrome",
"linux": "chrome",
"windows": "chrome"
}
]
}
}
]
}

114
src/Backend/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,114 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build-api",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DiunaBI.API/DiunaBI.API.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "build-web",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DiunaBI.UI.Web/DiunaBI.UI.Web.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish-api",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/DiunaBI.API/DiunaBI.API.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish-web",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/DiunaBI.UI.Web/DiunaBI.UI.Web.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch-api",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/DiunaBI.API/DiunaBI.API.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch-web",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/DiunaBI.UI.Web/DiunaBI.UI.Web.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "build-mobile-ios",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DiunaBI.UI.Mobile/DiunaBI.UI.Mobile.csproj",
"-f",
"net10.0-ios",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "run-mobile-ios",
"command": "dotnet",
"type": "shell",
"args": [
"build",
"${workspaceFolder}/DiunaBI.UI.Mobile/DiunaBI.UI.Mobile.csproj",
"-f",
"net10.0-ios",
"-t:Run",
"/p:_DeviceName=:v2:udid=B72F13ED-156F-481D-80EE-6A17494DBB70"
],
"problemMatcher": [],
"presentation": {
"reveal": "always",
"panel": "dedicated",
"focus": false
},
"group": {
"kind": "build",
"isDefault": false
}
}
]
}

View File

@@ -0,0 +1,51 @@
using DiunaBI.API.Services;
using DiunaBI.Domain.Entities;
using Microsoft.AspNetCore.Mvc;
namespace DiunaBI.API.Controllers;
[ApiController]
[Route("[controller]")]
public class AuthController(
GoogleAuthService googleAuthService,
JwtTokenService jwtTokenService,
ILogger<AuthController> logger)
: ControllerBase
{
[HttpPost("apiToken")]
public async Task<IActionResult> ApiToken([FromBody] string idToken)
{
try
{
if (string.IsNullOrEmpty(idToken))
{
logger.LogWarning("Empty idToken received");
return BadRequest("IdToken is required");
}
var (isValid, user, error) = await googleAuthService.ValidateGoogleTokenAsync(idToken);
if (!isValid || user == null)
{
logger.LogWarning("Google token validation failed: {Error}", error);
return Unauthorized();
}
var jwt = jwtTokenService.GenerateToken(user);
logger.LogInformation("User authenticated successfully: {Email}", user.Email);
return Ok(new
{
token = jwt,
id = user.Id,
expirationTime = DateTime.UtcNow.AddDays(7) // z JwtSettings
});
}
catch (Exception ex)
{
logger.LogError(ex, "Error during authentication");
return StatusCode(500, "Internal server error");
}
}
}

View File

@@ -2,14 +2,13 @@ using System.Text;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using DiunaBI.Infrastructure.Data;
using DiunaBI.Core.Database.Context; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Models;
namespace DiunaBI.WebAPI.Controllers; namespace DiunaBI.API.Controllers;
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("[controller]")]
public class DataInboxController : Controller public class DataInboxController : Controller
{ {
private readonly AppDbContext _db; private readonly AppDbContext _db;
@@ -55,7 +54,7 @@ public class DataInboxController : Controller
var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1])); var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1]));
var username = authValue.Split(':')[0]; var username = authValue.Split(':')[0];
var password = authValue.Split(':')[1]; var password = authValue.Split(':')[1];
if (username != _configuration["morska-user"] || password != _configuration["morska-pass"]) if (username != _configuration["apiUser"] || password != _configuration["apiPass"])
{ {
_logger.LogWarning("DataInbox: Unauthorized request - bad credentials for source {Source}", dataInbox.Source); _logger.LogWarning("DataInbox: Unauthorized request - bad credentials for source {Source}", dataInbox.Source);
return Unauthorized(); return Unauthorized();
@@ -78,7 +77,6 @@ public class DataInboxController : Controller
if (dataInbox.Name == "morska.d3.importer") if (dataInbox.Name == "morska.d3.importer")
{ {
_logger.LogDebug("DataInbox: Detected morska.d3.importer - processing will be handled by AutoImport"); _logger.LogDebug("DataInbox: Detected morska.d3.importer - processing will be handled by AutoImport");
// AutoImport będzie obsługiwać ten typ danych
} }
return Ok(); return Ok();

View File

@@ -4,15 +4,16 @@ using Google.Apis.Sheets.v4;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using DiunaBI.Core.Models; using DiunaBI.Application.DTOModels;
using DiunaBI.Core.Database.Context; using DiunaBI.Application.DTOModels.Common;
using DiunaBI.Core.Services; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Interfaces; using DiunaBI.Infrastructure.Data;
using DiunaBI.Infrastructure.Services;
namespace DiunaBI.WebAPI.Controllers; namespace DiunaBI.API.Controllers;
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("[controller]")]
public class LayersController : Controller public class LayersController : Controller
{ {
private readonly AppDbContext _db; private readonly AppDbContext _db;
@@ -40,29 +41,58 @@ public class LayersController : Controller
} }
[HttpGet] [HttpGet]
public IActionResult GetAll(int start, int limit, string? name, LayerType? type) [Route("")]
public IActionResult GetAll([FromQuery] int start, [FromQuery] int limit, [FromQuery] string? name, [FromQuery] Domain.Entities.LayerType? type)
{ {
try try
{ {
var response = _db.Layers.Where(x => !x.IsDeleted); var query = _db.Layers.Where(x => !x.IsDeleted);
if (name != null) if (name != null)
{ {
response = response.Where(x => x.Name != null && x.Name.Contains(name)); query = query.Where(x => x.Name != null && x.Name.Contains(name));
} }
if (type != null) if (type.HasValue)
{ {
response = response.Where(x => x.Type == type); query = query.Where(x => x.Type == type.Value);
} }
var result = response var totalCount = query.Count();
var items = query
.OrderByDescending(x => x.Number) .OrderByDescending(x => x.Number)
.Skip(start).Take(limit).AsNoTracking().ToList(); .Skip(start)
.Take(limit)
.AsNoTracking()
.Select(x => new LayerDto
{
Id = x.Id,
Number = x.Number,
Name = x.Name,
Type = (Application.DTOModels.LayerType)x.Type,
CreatedAt = x.CreatedAt,
ModifiedAt = x.ModifiedAt,
CreatedById = x.CreatedById,
ModifiedById = x.ModifiedById,
IsDeleted = x.IsDeleted,
IsCancelled = x.IsCancelled,
ParentId = x.ParentId
})
.ToList();
_logger.LogDebug("GetAll: Retrieved {Count} layers with filter name={Name}, type={Type}", var pagedResult = new PagedResult<LayerDto>
result.Count, name, type); {
Items = items,
TotalCount = totalCount,
Page = (start / limit) + 1,
PageSize = limit
};
return Ok(result); _logger.LogDebug("GetAll: Retrieved {Count} of {TotalCount} layers (page {Page}) with filter name={Name}, type={Type}",
items.Count, totalCount, pagedResult.Page, name, type);
return Ok(pagedResult);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -91,55 +121,8 @@ public class LayersController : Controller
} }
} }
[HttpGet] [HttpGet]
[Route("getForPowerBI/{apiKey}/{number:int}")]
public IActionResult GetByNumber(string apiKey, int number)
{
if (apiKey != _configuration["apiKey"])
{
_logger.LogWarning("PowerBI: Unauthorized request - wrong apiKey for layer {LayerNumber}", number);
return Unauthorized();
}
try
{
if (!Request.Headers.TryGetValue("Authorization", out var authHeader))
{
_logger.LogWarning("PowerBI: Unauthorized request - no authorization header for layer {LayerNumber}", number);
return Unauthorized();
}
var credentialsArr = authHeader.ToString().Split(" ");
if (credentialsArr.Length != 2)
{
_logger.LogWarning("PowerBI: Unauthorized request - wrong auth header format for layer {LayerNumber}", number);
return Unauthorized();
}
var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1]));
var username = authValue.Split(':')[0];
var password = authValue.Split(':')[1];
if (username != _configuration["powerBI-user"] || password != _configuration["powerBI-pass"])
{
_logger.LogWarning("PowerBI: Unauthorized request - bad credentials for layer {LayerNumber}", number);
return Unauthorized();
}
_logger.LogInformation("PowerBI: Sending data for layer {LayerNumber}", number);
var layer = _db.Layers
.Include(x => x.CreatedBy)
.Include(x => x.Records).AsNoTracking().First(x => x.Number == number && !x.IsDeleted);
return Ok(layer);
}
catch (Exception e)
{
_logger.LogError(e, "PowerBI: Error occurred while processing layer {LayerNumber}", number);
return BadRequest(e.ToString());
}
}
[HttpGet]
[Route("getConfiguration/{apiKey}/{number:int}")] [Route("getConfiguration/{apiKey}/{number:int}")]
[AllowAnonymous]
public IActionResult GetConfigurationByNumber(string apiKey, int number) public IActionResult GetConfigurationByNumber(string apiKey, int number)
{ {
if (apiKey != _configuration["apiKey"]) if (apiKey != _configuration["apiKey"])
@@ -166,7 +149,7 @@ public class LayersController : Controller
var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1])); var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1]));
var username = authValue.Split(':')[0]; var username = authValue.Split(':')[0];
var password = authValue.Split(':')[1]; var password = authValue.Split(':')[1];
if (username != _configuration["morska-user"] || password != _configuration["morska-pass"]) if (username != _configuration["apiUser"] || password != _configuration["apiPass"])
{ {
_logger.LogWarning("Configuration: Unauthorized request - bad credentials for layer {LayerNumber}", number); _logger.LogWarning("Configuration: Unauthorized request - bad credentials for layer {LayerNumber}", number);
return Unauthorized(); return Unauthorized();
@@ -253,7 +236,7 @@ public class LayersController : Controller
[AllowAnonymous] [AllowAnonymous]
public IActionResult AutoImport(string apiKey, string nameFilter) public IActionResult AutoImport(string apiKey, string nameFilter)
{ {
if (Request.Host.Value != _configuration["apiLocalUrl"] || apiKey != _configuration["apiKey"]) if (apiKey != _configuration["apiKey"])
{ {
_logger.LogWarning("AutoImport: Unauthorized request with apiKey {ApiKey}", apiKey); _logger.LogWarning("AutoImport: Unauthorized request with apiKey {ApiKey}", apiKey);
return Unauthorized(); return Unauthorized();
@@ -420,9 +403,9 @@ public class LayersController : Controller
[AllowAnonymous] [AllowAnonymous]
public IActionResult AutoProcess(string apiKey) public IActionResult AutoProcess(string apiKey)
{ {
if (Request.Host.Value != _configuration["apiLocalUrl"] || apiKey != _configuration["apiKey"]) if (apiKey != _configuration["apiKey"])
{ {
_logger.LogWarning("AutoProcess: Unauthorized request with apiKey {ApiKey}", apiKey); _logger.LogWarning("AutoImport: Unauthorized request with apiKey {ApiKey}", apiKey);
return Unauthorized(); return Unauthorized();
} }

View File

@@ -1,11 +1,11 @@
using DiunaBI.Core.Services; using DiunaBI.Infrastructure.Services;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace DiunaBI.WebAPI.Controllers; namespace DiunaBI.API.Controllers;
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("[controller]")]
[Authorize] [Authorize]
public class TestsController : Controller public class TestsController : Controller
{ {

View File

@@ -1,26 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>DiunaBI.WebAPI</RootNamespace>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Google.Cloud.Firestore" Version="3.4.0" /> <PackageReference Include="Google.Cloud.Firestore" Version="3.4.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
<PackageReference Include="Google.Apis.Auth" Version="1.68.0" /> <PackageReference Include="Google.Apis.Auth" Version="1.68.0" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.68.0.3627" /> <PackageReference Include="Google.Apis.Drive.v3" Version="1.68.0.3627" />
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.68.0.3624" /> <PackageReference Include="Google.Apis.Sheets.v4" Version="1.68.0.3624" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" /> <PackageReference Include="Serilog.Enrichers.Environment" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" /> <PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="10.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\DiunaBI.Core\DiunaBI.Core.csproj" /> <ProjectReference Include="..\DiunaBI.Infrastructure\DiunaBI.Infrastructure.csproj" />
<ProjectReference Include="..\DiunaBI.Application\DiunaBI.Application.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -0,0 +1,58 @@
# Stage 1: Build
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src/Backend
# Copy solution and all project files for restore
COPY DiunaBI.sln ./
COPY DiunaBI.API/DiunaBI.API.csproj DiunaBI.API/
COPY DiunaBI.Domain/DiunaBI.Domain.csproj DiunaBI.Domain/
COPY DiunaBI.Application/DiunaBI.Application.csproj DiunaBI.Application/
COPY DiunaBI.Infrastructure/DiunaBI.Infrastructure.csproj DiunaBI.Infrastructure/
COPY DiunaBI.Plugins.Morska/DiunaBI.Plugins.Morska.csproj DiunaBI.Plugins.Morska/
# Restore dependencies
RUN dotnet restore DiunaBI.API/DiunaBI.API.csproj
# Copy all source code
COPY . .
# Build plugin first
WORKDIR /src/Backend/DiunaBI.Plugins.Morska
RUN dotnet build -c Release
# Build and publish API
WORKDIR /src/Backend/DiunaBI.API
RUN dotnet publish -c Release -o /app/publish --no-restore
# Copy plugin DLL to publish output
RUN mkdir -p /app/publish/Plugins && \
cp /src/Backend/DiunaBI.Plugins.Morska/bin/Release/net10.0/DiunaBI.Plugins.Morska.dll /app/publish/Plugins/
# Stage 2: Runtime
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app
# Install wget for health checks
RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/*
# Set timezone
ENV TZ=Europe/Warsaw
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# Copy published files
COPY --from=build /app/publish .
# Set environment variables (can be overridden)
ENV ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_URLS=http://0.0.0.0:7142
# Expose port (default, can be remapped in docker-compose)
EXPOSE 7142
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:7142/health || exit 1
# Run the application
ENTRYPOINT ["dotnet", "DiunaBI.API.dll"]

View File

@@ -4,11 +4,11 @@ using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using DiunaBI.Core.Database.Context; using DiunaBI.API.Services;
using DiunaBI.Core.Services; using DiunaBI.Infrastructure.Data;
using DiunaBI.Infrastructure.Services;
using Google.Apis.Sheets.v4; using Google.Apis.Sheets.v4;
using Serilog; using Serilog;
using DiunaBI.Core.Interfaces;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@@ -31,7 +31,7 @@ var connectionString = builder.Configuration.GetConnectionString("SQLDatabase");
builder.Services.AddDbContext<AppDbContext>(x => builder.Services.AddDbContext<AppDbContext>(x =>
{ {
x.UseSqlServer(connectionString); x.UseSqlServer(connectionString, sqlOptions => sqlOptions.MigrationsAssembly("DiunaBI.Infrastructure"));
x.EnableSensitiveDataLogging(); x.EnableSensitiveDataLogging();
}); });
@@ -71,10 +71,13 @@ builder.Services.AddAuthentication(options =>
ValidateAudience = false, ValidateAudience = false,
ValidateLifetime = true, ValidateLifetime = true,
ValidateIssuerSigningKey = true, ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Secret"]!)) IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtSettings:SecurityKey"]!))
}; };
}); });
builder.Services.AddScoped<GoogleAuthService>();
builder.Services.AddScoped<JwtTokenService>();
// Google Sheets dependencies // Google Sheets dependencies
Console.WriteLine("Adding Google Sheets dependencies..."); Console.WriteLine("Adding Google Sheets dependencies...");
builder.Services.AddSingleton<GoogleSheetsHelper>(); builder.Services.AddSingleton<GoogleSheetsHelper>();
@@ -96,6 +99,42 @@ builder.Services.AddSingleton<PluginManager>();
var app = builder.Build(); var app = builder.Build();
// Auto-apply migrations on startup
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5));
try
{
await db.Database.OpenConnectionAsync();
await db.Database.ExecuteSqlRawAsync(
"EXEC sp_getapplock @Resource = N'DiunaBI_Migrations', @LockMode = 'Exclusive', @LockTimeout = 60000;");
logger.LogInformation("Ensuring database is up to date...");
await db.Database.MigrateAsync();
logger.LogInformation("Database is up to date.");
}
catch (Exception ex)
{
logger.LogCritical(ex, "Migration failed - application will not start.");
throw;
}
finally
{
try
{
await db.Database.ExecuteSqlRawAsync(
"EXEC sp_releaseapplock @Resource = N'DiunaBI_Migrations';");
}
catch { /* ignore */ }
await db.Database.CloseConnectionAsync();
}
}
if (app.Environment.IsProduction()) if (app.Environment.IsProduction())
{ {
app.UseSerilogRequestLogging(options => app.UseSerilogRequestLogging(options =>
@@ -160,6 +199,9 @@ app.UseAuthorization();
app.MapControllers(); app.MapControllers();
app.MapGet("/health", () => Results.Ok(new { status = "OK", timestamp = DateTime.UtcNow }))
.AllowAnonymous();
app.Run(); app.Run();
if (app.Environment.IsProduction()) if (app.Environment.IsProduction())

View File

@@ -0,0 +1,60 @@
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
using Google.Apis.Auth;
using Microsoft.EntityFrameworkCore;
namespace DiunaBI.API.Services;
public class GoogleAuthService(AppDbContext context, IConfiguration configuration, ILogger<GoogleAuthService> logger)
{
private readonly AppDbContext _context = context;
private readonly IConfiguration _configuration = configuration;
private readonly ILogger<GoogleAuthService> _logger = logger;
public async Task<(bool IsValid, User? user, string? error)> ValidateGoogleTokenAsync(string idToken)
{
try
{
var clientId = _configuration["GoogleAuth:ClientId"];
if (string.IsNullOrEmpty(clientId))
{
_logger.LogError("Google Auth Client Id is not configured");
return (false, null, "Google Auth Client Id is not configured");
}
var payload = await GoogleJsonWebSignature.ValidateAsync(idToken,
new GoogleJsonWebSignature.ValidationSettings
{
Audience = new[] { clientId }
});
_logger.LogInformation("Google token validated for user: {Email}", payload.Email);
var user = await _context.Users
.FirstOrDefaultAsync(x => x.Email == payload.Email);
if (user == null)
{
_logger.LogError("User not found in DiunaBI database: {Email}", payload.Email);
return (false, null, "User not found in DiunaBI database");
}
user.UserName = payload.Name;
await _context.SaveChangesAsync();
_logger.LogInformation("User logged in: {Email}", payload.Email);
return (true, user, null);
}
catch (InvalidJwtException ex)
{
_logger.LogError(ex, "Invalid JWT token");
return (false, null, "Invalid JWT token");
} catch (Exception ex)
{
_logger.LogError(ex, "Error validating Google token");
return (false, null, "Error validating Google token");
}
}
}

View File

@@ -0,0 +1,84 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using DiunaBI.Domain.Entities;
using Microsoft.IdentityModel.Tokens;
namespace DiunaBI.API.Services;
public class JwtTokenService(IConfiguration configuration, ILogger<JwtTokenService> logger)
{
private readonly IConfiguration _configuration = configuration;
private readonly ILogger<JwtTokenService> _logger = logger;
public string GenerateToken(User user)
{
var jwtSettings = _configuration.GetSection("JwtSettings");
var securityKey = jwtSettings["SecurityKey"];
var issuer = jwtSettings["Issuer"];
var audience = jwtSettings["Audience"];
var expiryDays = int.Parse(jwtSettings["ExpiryDays"] ?? "7");
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString(),
ClaimValueTypes.Integer64)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: issuer,
audience: audience,
claims: claims,
expires: DateTime.UtcNow.AddDays(expiryDays),
signingCredentials: creds
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(token);
_logger.LogInformation("Generated JWT token for user: {Email}", user.Email);
return tokenString;
}
public ClaimsPrincipal? ValidateToken(string token)
{
try
{
var jwtSettings = _configuration.GetSection("JwtSettings");
var secretKey = jwtSettings["SecretKey"];
var issuer = jwtSettings["Issuer"];
var audience = jwtSettings["Audience"];
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(secretKey);
var validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = issuer,
ValidAudience = audience,
IssuerSigningKey = new SymmetricSecurityKey(key),
ClockSkew = TimeSpan.Zero
};
var principal = tokenHandler.ValidateToken(token, validationParameters, out _);
return principal;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error validating JWT token");
return null;
}
}
}

View File

@@ -1,6 +1,4 @@
{ {
"PONG": "#{PING}#",
"app-version": "#{buildId}#",
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
@@ -34,35 +32,15 @@
"retainedFileCountLimit": 30, "retainedFileCountLimit": 30,
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext} {Message:lj} {Properties:j}{NewLine}{Exception}" "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext} {Message:lj} {Properties:j}{NewLine}{Exception}"
} }
},
{
"Name": "Seq",
"Args": {
"serverUrl": "http://localhost:5341",
"restrictedToMinimumLevel": "Information"
}
} }
], ],
"Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"] "Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"]
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"ConnectionStrings": {
"SQLDatabase": "#{db-connection-string}#"
},
"InstanceName": "#{app-environment}#",
"GoogleClientId": "#{google-backend-login-client-id}#",
"Secret": "#{google-backend-login-secret}#",
"apiKey": "#{api-key}#",
"powerBI-user": "#{powerBI-user}#",
"powerBI-pass": "#{powerBI-pass}#",
"morska-user": "#{morska-user}#",
"morska-pass": "#{morska-pass}#",
"exportDirectory": "#{export-directory}#",
"apiLocalUrl": "#{api-local-url}#",
"Kestrel": { "Kestrel": {
"Endpoints": { "Endpoints": {
"Http": { "Http": {
"Url": "http://#{api-local-url}#" "Url": "http://0.0.0.0:7142"
} }
} }
} }

View File

@@ -0,0 +1,32 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning",
"Microsoft.EntityFrameworkCore.Infrastructure": "Warning",
"System.Net.Http.HttpClient": "Warning",
"Google.Apis": "Warning",
"DiunaBI.Core.Services.PluginManager": "Information"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"]
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,12 @@
namespace DiunaBI.Application.DTOModels.Common;
public class PagedResult<T>
{
public List<T> Items { get; set; } = new();
public int TotalCount { get; set; }
public int PageSize { get; set; }
public int Page { get; set; }
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
public bool HasPreviousPage => Page > 1;
public bool HasNextPage => Page < TotalPages;
}

View File

@@ -0,0 +1,37 @@
namespace DiunaBI.Application.DTOModels;
public class LayerDto
{
public Guid Id { get; set; }
public int Number { get; set; }
public string? Name { get; set; }
public LayerType Type { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ModifiedAt { get; set; }
public Guid CreatedById { get; set; }
public Guid ModifiedById { get; set; }
public bool IsDeleted { get; set; }
public bool IsCancelled { get; set; }
public Guid? ParentId { get; set; }
// Navigation properties
public List<RecordDto>? Records { get; set; }
public UserDto? CreatedBy { get; set; }
public UserDto? ModifiedBy { get; set; }
}
public enum LayerType
{
Import,
Processed,
Administration,
Dictionary
}
public class LayerFilterRequest
{
public string? Search { get; set; }
public LayerType? Type { get; set; }
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 50;
}

View File

@@ -0,0 +1,50 @@
namespace DiunaBI.Application.DTOModels;
public class RecordDto
{
public Guid Id { get; set; }
public string? Code { get; set; }
public double? Value1 { get; set; }
public double? Value2 { get; set; }
public double? Value3 { get; set; }
public double? Value4 { get; set; }
public double? Value5 { get; set; }
public double? Value6 { get; set; }
public double? Value7 { get; set; }
public double? Value8 { get; set; }
public double? Value9 { get; set; }
public double? Value10 { get; set; }
public double? Value11 { get; set; }
public double? Value12 { get; set; }
public double? Value13 { get; set; }
public double? Value14 { get; set; }
public double? Value15 { get; set; }
public double? Value16 { get; set; }
public double? Value17 { get; set; }
public double? Value18 { get; set; }
public double? Value19 { get; set; }
public double? Value20 { get; set; }
public double? Value21 { get; set; }
public double? Value22 { get; set; }
public double? Value23 { get; set; }
public double? Value24 { get; set; }
public double? Value25 { get; set; }
public double? Value26 { get; set; }
public double? Value27 { get; set; }
public double? Value28 { get; set; }
public double? Value29 { get; set; }
public double? Value30 { get; set; }
public double? Value31 { get; set; }
public double? Value32 { get; set; }
public string? Desc1 { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ModifiedAt { get; set; }
public bool IsDeleted { get; set; }
public Guid CreatedById { get; set; }
public Guid ModifiedById { get; set; }
public Guid LayerId { get; set; }
}

View File

@@ -0,0 +1,8 @@
namespace DiunaBI.Application.DTOModels;
public class UserDto
{
public Guid Id { get; set; }
public string? Username { get; set; }
public string? Email { get; set; }
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>13.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DiunaBI.Domain\DiunaBI.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AngouriMath" Version="1.4.0-preview.3" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
</ItemGroup>
</Project>

View File

@@ -1,24 +0,0 @@
using Microsoft.EntityFrameworkCore;
using DiunaBI.Core.Models;
using Microsoft.Extensions.Logging;
namespace DiunaBI.Core.Database.Context;
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
{
public DbSet<User> Users { get; init; }
public DbSet<Layer> Layers { get; init; }
public DbSet<Record> Records { get; init; }
public DbSet<ProcessSource> ProcessSources { get; init; }
public DbSet<DataInbox> DataInbox { get; init; }
public DbSet<QueueJob> QueueJobs { get; init; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ProcessSource>().HasKey(x => new
{
x.LayerId,
x.SourceId
});
}
}

View File

@@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.68.0.3490" />
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.68.0.3525" />
<PackageReference Include="Google.Apis.Auth" Version="1.68.0" />
<PackageReference Include="AngouriMath" Version="1.4.0-preview.3" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -1,36 +0,0 @@
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Sheets.v4;
using System.IO;
namespace DiunaBI.Core.Services;
public class GoogleSheetsHelper
{
public SheetsService? Service { get; private set; }
private const string ApplicationName = "Diuna";
private static readonly string[] Scopes = [SheetsService.Scope.Spreadsheets];
public GoogleSheetsHelper()
{
InitializeService();
}
private void InitializeService()
{
var credential = GetCredentialsFromFile();
Service = new SheetsService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
}
private static GoogleCredential GetCredentialsFromFile()
{
var fileName = "client_secrets.json";
#if DEBUG
fileName = "client_secrets.Development.json";
#endif
using var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
var credential = GoogleCredential.FromStream(stream).CreateScoped(Scopes);
return credential;
}
}

View File

@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>13.0</LangVersion>
</PropertyGroup>
</Project>

View File

@@ -1,18 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace DiunaBI.Core.Models; namespace DiunaBI.Domain.Entities;
public class DataInbox public class DataInbox
{ {
#region Properties #region Properties
[Key]
public Guid Id { get; set; } public Guid Id { get; set; }
[StringLength(50)]
public required string Name { get; init; } public required string Name { get; init; }
[StringLength(50)]
public required string Source { get; set; } public required string Source { get; set; }
[StringLength(int.MaxValue)]
public required string Data { get; init; } public required string Data { get; init; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
#endregion #endregion

View File

@@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace DiunaBI.Core.Models; namespace DiunaBI.Domain.Entities;
public enum LayerType public enum LayerType
{ {
@@ -14,30 +14,19 @@ public enum LayerType
public class Layer public class Layer
{ {
#region Properties #region Properties
[Key]
public Guid Id { get; init; } public Guid Id { get; init; }
[Required]
public int Number { get; init; } public int Number { get; init; }
[Required]
[MaxLength(50)]
public string? Name { get; set; } public string? Name { get; set; }
[Required]
public LayerType Type { get; init; } public LayerType Type { get; init; }
[Required]
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
[Required]
public DateTime ModifiedAt { get; set; } public DateTime ModifiedAt { get; set; }
[Required]
public bool IsDeleted { get; init; } = false; public bool IsDeleted { get; init; } = false;
[Required]
public bool IsCancelled { get; init; } = false; public bool IsCancelled { get; init; } = false;
#endregion #endregion
#region Relations #region Relations
public ICollection<Record>? Records { get; init; } public ICollection<Record>? Records { get; init; }
[Required]
public Guid CreatedById { get; set; } public Guid CreatedById { get; set; }
public User? CreatedBy { get; init; } public User? CreatedBy { get; init; }
[Required]
public Guid ModifiedById { get; set; } public Guid ModifiedById { get; set; }
public User? ModifiedBy { get; init; } public User? ModifiedBy { get; init; }
public Guid? ParentId { get; init; } public Guid? ParentId { get; init; }

View File

@@ -1,14 +1,12 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace DiunaBI.Core.Models; namespace DiunaBI.Domain.Entities;
public class ProcessSource public class ProcessSource
{ {
#region Relations #region Relations
[Required]
public Guid LayerId { get; init; } public Guid LayerId { get; init; }
[Required]
public Guid SourceId { get; init; } public Guid SourceId { get; init; }
public Layer? Source { get; init; } public Layer? Source { get; init; }
#endregion #endregion

View File

@@ -1,56 +1,26 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace DiunaBI.Core.Models; namespace DiunaBI.Domain.Entities;
public class QueueJob public class QueueJob
{ {
[Key]
public Guid Id { get; set; } = Guid.NewGuid(); public Guid Id { get; set; } = Guid.NewGuid();
[Required]
public Guid LayerId { get; set; } public Guid LayerId { get; set; }
[Required]
[MaxLength(200)]
public string LayerName { get; set; } = string.Empty; public string LayerName { get; set; } = string.Empty;
[Required]
[MaxLength(100)]
public string PluginName { get; set; } = string.Empty; public string PluginName { get; set; } = string.Empty;
[Required]
public JobType JobType { get; set; } public JobType JobType { get; set; }
public int Priority { get; set; } = 0; // 0 = highest priority public int Priority { get; set; } = 0; // 0 = highest priority
[Required]
public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public int RetryCount { get; set; } = 0; public int RetryCount { get; set; } = 0;
public int MaxRetries { get; set; } = 5; public int MaxRetries { get; set; } = 5;
[Required]
public JobStatus Status { get; set; } = JobStatus.Pending; public JobStatus Status { get; set; } = JobStatus.Pending;
[MaxLength(1000)]
public string? LastError { get; set; } public string? LastError { get; set; }
public DateTime? LastAttemptAt { get; set; } public DateTime? LastAttemptAt { get; set; }
public DateTime? CompletedAt { get; set; } public DateTime? CompletedAt { get; set; }
[Required]
public Guid CreatedById { get; set; } public Guid CreatedById { get; set; }
[Required]
public DateTime CreatedAtUtc { get; set; } = DateTime.UtcNow; public DateTime CreatedAtUtc { get; set; } = DateTime.UtcNow;
[Required]
public Guid ModifiedById { get; set; } public Guid ModifiedById { get; set; }
[Required]
public DateTime ModifiedAtUtc { get; set; } = DateTime.UtcNow; public DateTime ModifiedAtUtc { get; set; } = DateTime.UtcNow;
} }

View File

@@ -1,15 +1,12 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace DiunaBI.Core.Models; namespace DiunaBI.Domain.Entities;
public class Record public class Record
{ {
#region Properties #region Properties
[Key]
public Guid Id { get; set; } public Guid Id { get; set; }
[Required]
[StringLength(50)]
public string? Code { get; init; } public string? Code { get; init; }
public double? Value1 { get; set; } public double? Value1 { get; set; }
public double? Value2 { get; set; } public double? Value2 { get; set; }
@@ -43,18 +40,14 @@ public class Record
public double? Value30 { get; set; } public double? Value30 { get; set; }
public double? Value31 { get; set; } public double? Value31 { get; set; }
public double? Value32 { get; set; } public double? Value32 { get; set; }
//Description fields
[StringLength(10000)]
public string? Desc1 { get; set; } public string? Desc1 { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public DateTime ModifiedAt { get; set; } public DateTime ModifiedAt { get; set; }
public bool IsDeleted { get; init; } public bool IsDeleted { get; init; }
#endregion #endregion
#region Relations #region Relations
[Required]
public Guid CreatedById { get; set; } public Guid CreatedById { get; set; }
public User? CreatedBy { get; init; } public User? CreatedBy { get; init; }
[Required]
public Guid ModifiedById { get; set; } public Guid ModifiedById { get; set; }
public User? ModifiedBy { get; init; } public User? ModifiedBy { get; init; }
public Guid LayerId { get; set; } public Guid LayerId { get; set; }

View File

@@ -1,17 +1,14 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace DiunaBI.Core.Models; namespace DiunaBI.Domain.Entities;
public class User public class User
{ {
#region Properties #region Properties
[Key]
public Guid Id { get; init; } public Guid Id { get; init; }
[StringLength(50)]
public string? Email { get; init; } public string? Email { get; init; }
[StringLength(50)] public string? UserName { get; set; }
public string? UserName { get; init; }
public DateTime CreatedAt { get; init; } public DateTime CreatedAt { get; init; }
#endregion #endregion
} }

View File

@@ -0,0 +1,199 @@
using Microsoft.EntityFrameworkCore;
using DiunaBI.Domain.Entities;
namespace DiunaBI.Infrastructure.Data;
public class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
{
public DbSet<User> Users { get; init; }
public DbSet<Layer> Layers { get; init; }
public DbSet<Record> Records { get; init; }
public DbSet<ProcessSource> ProcessSources { get; init; }
public DbSet<DataInbox> DataInbox { get; init; }
public DbSet<QueueJob> QueueJobs { get; init; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasKey(x => x.Id);
modelBuilder.Entity<User>().Property(x => x.Email).HasMaxLength(50);
modelBuilder.Entity<User>().Property(x => x.UserName).HasMaxLength(50);
modelBuilder.Entity<Layer>().HasKey(x => x.Id);
modelBuilder.Entity<Layer>().Property(x => x.Number).IsRequired();
modelBuilder.Entity<Layer>().Property(x => x.Name).IsRequired().HasMaxLength(50);
modelBuilder.Entity<Layer>().Property(x => x.Type).IsRequired().HasConversion<int>();
modelBuilder.Entity<Layer>().Property(x => x.CreatedAt).IsRequired();
modelBuilder.Entity<Layer>().Property(x => x.ModifiedAt).IsRequired();
modelBuilder.Entity<Layer>().Property(x => x.IsDeleted).IsRequired().HasDefaultValue(false);
modelBuilder.Entity<Layer>().Property(x => x.IsCancelled).IsRequired().HasDefaultValue(false);
modelBuilder.Entity<Layer>().Property(x => x.CreatedById).IsRequired();
modelBuilder.Entity<Layer>().Property(x => x.ModifiedById).IsRequired();
modelBuilder.Entity<Layer>()
.HasOne(x => x.CreatedBy)
.WithMany()
.HasForeignKey(x => x.CreatedById)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Layer>()
.HasOne(x => x.ModifiedBy)
.WithMany()
.HasForeignKey(x => x.ModifiedById)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Layer>()
.HasMany(x => x.Records)
.WithOne()
.HasForeignKey(r => r.LayerId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Record>().HasKey(x => x.Id);
modelBuilder.Entity<Record>().Property(x => x.Code).IsRequired().HasMaxLength(50);
modelBuilder.Entity<Record>().Property(x => x.Desc1).HasMaxLength(10000);
modelBuilder.Entity<Record>().Property(x => x.CreatedAt);
modelBuilder.Entity<Record>().Property(x => x.ModifiedAt);
modelBuilder.Entity<Record>().Property(x => x.IsDeleted);
modelBuilder.Entity<Record>().Property(x => x.CreatedById).IsRequired();
modelBuilder.Entity<Record>().Property(x => x.ModifiedById).IsRequired();
modelBuilder.Entity<Record>().Property(x => x.LayerId).IsRequired();
modelBuilder.Entity<Record>()
.HasOne(x => x.CreatedBy)
.WithMany()
.HasForeignKey(x => x.CreatedById)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Record>()
.HasOne(x => x.ModifiedBy)
.WithMany()
.HasForeignKey(x => x.ModifiedById)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Record>()
.HasOne<Layer>()
.WithMany(l => l.Records!)
.HasForeignKey(x => x.LayerId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ProcessSource>().HasKey(x => new { x.LayerId, x.SourceId });
modelBuilder.Entity<ProcessSource>().Property(x => x.LayerId).IsRequired();
modelBuilder.Entity<ProcessSource>().Property(x => x.SourceId).IsRequired();
modelBuilder.Entity<ProcessSource>()
.HasOne<Layer>()
.WithMany()
.HasForeignKey(x => x.LayerId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ProcessSource>()
.HasOne(x => x.Source)
.WithMany()
.HasForeignKey(x => x.SourceId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<DataInbox>().HasKey(x => x.Id);
modelBuilder.Entity<DataInbox>().Property(x => x.Name).IsRequired().HasMaxLength(50);
modelBuilder.Entity<DataInbox>().Property(x => x.Source).IsRequired().HasMaxLength(50);
modelBuilder.Entity<DataInbox>().Property(x => x.Data).IsRequired();
modelBuilder.Entity<DataInbox>().Property(x => x.CreatedAt);
modelBuilder.Entity<QueueJob>().HasKey(x => x.Id);
modelBuilder.Entity<QueueJob>().Property(x => x.LayerId).IsRequired();
modelBuilder.Entity<QueueJob>().Property(x => x.LayerName).IsRequired().HasMaxLength(200);
modelBuilder.Entity<QueueJob>().Property(x => x.PluginName).IsRequired().HasMaxLength(100);
modelBuilder.Entity<QueueJob>().Property(x => x.JobType).IsRequired().HasConversion<int>();
modelBuilder.Entity<QueueJob>().Property(x => x.Priority);
modelBuilder.Entity<QueueJob>().Property(x => x.CreatedAt).IsRequired();
modelBuilder.Entity<QueueJob>().Property(x => x.RetryCount);
modelBuilder.Entity<QueueJob>().Property(x => x.MaxRetries);
modelBuilder.Entity<QueueJob>().Property(x => x.Status).IsRequired().HasConversion<int>();
modelBuilder.Entity<QueueJob>().Property(x => x.LastError).HasMaxLength(1000);
modelBuilder.Entity<QueueJob>().Property(x => x.LastAttemptAt);
modelBuilder.Entity<QueueJob>().Property(x => x.CompletedAt);
modelBuilder.Entity<QueueJob>().Property(x => x.CreatedById).IsRequired();
modelBuilder.Entity<QueueJob>().Property(x => x.CreatedAtUtc).IsRequired();
modelBuilder.Entity<QueueJob>().Property(x => x.ModifiedById).IsRequired();
modelBuilder.Entity<QueueJob>().Property(x => x.ModifiedAtUtc).IsRequired();
// Configure automatic timestamps for entities with CreatedAt/ModifiedAt
ConfigureTimestamps(modelBuilder);
}
private void ConfigureTimestamps(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
// Check if entity has CreatedAt property
var createdAtProperty = entityType.FindProperty("CreatedAt");
if (createdAtProperty != null)
{
modelBuilder.Entity(entityType.ClrType)
.Property("CreatedAt")
.HasDefaultValueSql("GETUTCDATE()");
}
// Check if entity has ModifiedAt property
var modifiedAtProperty = entityType.FindProperty("ModifiedAt");
if (modifiedAtProperty != null)
{
modelBuilder.Entity(entityType.ClrType)
.Property("ModifiedAt")
.HasDefaultValueSql("GETUTCDATE()");
}
}
}
public override int SaveChanges()
{
UpdateTimestamps();
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
UpdateTimestamps();
return base.SaveChangesAsync(cancellationToken);
}
private void UpdateTimestamps()
{
var entities = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);
foreach (var entity in entities)
{
// Try to set CreatedAt for new entities
if (entity.State == EntityState.Added)
{
var createdAtProperty = entity.Properties.FirstOrDefault(p => p.Metadata.Name == "CreatedAt");
if (createdAtProperty != null)
{
createdAtProperty.CurrentValue = DateTime.UtcNow;
}
// Ensure IsDeleted and IsCancelled have default values for Layer entities
if (entity.Entity is Layer)
{
var isDeletedProperty = entity.Properties.FirstOrDefault(p => p.Metadata.Name == "IsDeleted");
if (isDeletedProperty != null && isDeletedProperty.CurrentValue == null)
{
isDeletedProperty.CurrentValue = false;
}
var isCancelledProperty = entity.Properties.FirstOrDefault(p => p.Metadata.Name == "IsCancelled");
if (isCancelledProperty != null && isCancelledProperty.CurrentValue == null)
{
isCancelledProperty.CurrentValue = false;
}
}
}
// Always update ModifiedAt
var modifiedAtProperty = entity.Properties.FirstOrDefault(p => p.Metadata.Name == "ModifiedAt");
if (modifiedAtProperty != null)
{
modifiedAtProperty.CurrentValue = DateTime.UtcNow;
}
}
}
}

View File

@@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
namespace DiunaBI.Core.Database.Context; namespace DiunaBI.Infrastructure.Data;
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<AppDbContext> public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{ {
public AppDbContext CreateDbContext(string[] args) public AppDbContext CreateDbContext(string[] args)
{ {
var configuration = new ConfigurationBuilder() var configuration = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../DiunaBI.WebAPI")) .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../DiunaBI.API"))
.AddJsonFile("appsettings.json", optional: false) .AddJsonFile("appsettings.json", optional: false)
.AddJsonFile("appsettings.Development.json", optional: true) .AddJsonFile("appsettings.Development.json", optional: true)
.Build(); .Build();

View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>13.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DiunaBI.Domain\DiunaBI.Domain.csproj" />
<ProjectReference Include="..\DiunaBI.Application\DiunaBI.Application.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.0" />
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.68.0.3525" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.68.0.3490" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,6 @@
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
namespace DiunaBI.Core.Interfaces; namespace DiunaBI.Infrastructure.Interfaces;
public interface IDataExporter public interface IDataExporter
{ {

View File

@@ -1,6 +1,6 @@
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
namespace DiunaBI.Core.Interfaces; namespace DiunaBI.Infrastructure.Interfaces;
public interface IDataImporter public interface IDataImporter
{ {

View File

@@ -1,6 +1,6 @@
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
namespace DiunaBI.Core.Interfaces; namespace DiunaBI.Infrastructure.Interfaces;
public interface IDataProcessor public interface IDataProcessor
{ {

View File

@@ -1,4 +1,4 @@
namespace DiunaBI.Core.Interfaces; namespace DiunaBI.Infrastructure.Interfaces;
public interface IPlugin public interface IPlugin
{ {

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20221205190148_Initial")] [Migration("20221205190148_Initial")]
partial class Initial partial class Initial
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class Initial : Migration public partial class Initial : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20221211210507_DataSetsAndDataRows")] [Migration("20221211210507_DataSetsAndDataRows")]
partial class DataSetsAndDataRows partial class DataSetsAndDataRows
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class DataSetsAndDataRows : Migration public partial class DataSetsAndDataRows : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20221219163620_RenameFields")] [Migration("20221219163620_RenameFields")]
partial class RenameFields partial class RenameFields
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class RenameFields : Migration public partial class RenameFields : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20221221165749_DataSetIdOnDataRow")] [Migration("20221221165749_DataSetIdOnDataRow")]
partial class DataSetIdOnDataRow partial class DataSetIdOnDataRow
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class DataSetIdOnDataRow : Migration public partial class DataSetIdOnDataRow : Migration
@@ -15,6 +15,11 @@ namespace DiunaBI.Core.Migrations
name: "FK_DataRows_DataSets_DataSetId", name: "FK_DataRows_DataSets_DataSetId",
table: "DataRows"); table: "DataRows");
// DODAJ: Usuń index przed zmianą kolumny
migrationBuilder.DropIndex(
name: "IX_DataRows_DataSetId",
table: "DataRows");
migrationBuilder.AlterColumn<Guid>( migrationBuilder.AlterColumn<Guid>(
name: "DataSetId", name: "DataSetId",
table: "DataRows", table: "DataRows",
@@ -25,6 +30,12 @@ namespace DiunaBI.Core.Migrations
oldType: "uniqueidentifier", oldType: "uniqueidentifier",
oldNullable: true); oldNullable: true);
// DODAJ: Odtwórz index po zmianie kolumny
migrationBuilder.CreateIndex(
name: "IX_DataRows_DataSetId",
table: "DataRows",
column: "DataSetId");
migrationBuilder.AddForeignKey( migrationBuilder.AddForeignKey(
name: "FK_DataRows_DataSets_DataSetId", name: "FK_DataRows_DataSets_DataSetId",
table: "DataRows", table: "DataRows",
@@ -41,6 +52,10 @@ namespace DiunaBI.Core.Migrations
name: "FK_DataRows_DataSets_DataSetId", name: "FK_DataRows_DataSets_DataSetId",
table: "DataRows"); table: "DataRows");
migrationBuilder.DropIndex(
name: "IX_DataRows_DataSetId",
table: "DataRows");
migrationBuilder.AlterColumn<Guid>( migrationBuilder.AlterColumn<Guid>(
name: "DataSetId", name: "DataSetId",
table: "DataRows", table: "DataRows",
@@ -49,6 +64,11 @@ namespace DiunaBI.Core.Migrations
oldClrType: typeof(Guid), oldClrType: typeof(Guid),
oldType: "uniqueidentifier"); oldType: "uniqueidentifier");
migrationBuilder.CreateIndex(
name: "IX_DataRows_DataSetId",
table: "DataRows",
column: "DataSetId");
migrationBuilder.AddForeignKey( migrationBuilder.AddForeignKey(
name: "FK_DataRows_DataSets_DataSetId", name: "FK_DataRows_DataSets_DataSetId",
table: "DataRows", table: "DataRows",

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20230106095427_RenameModels")] [Migration("20230106095427_RenameModels")]
partial class RenameModels partial class RenameModels
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class RenameModels : Migration public partial class RenameModels : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20230626171614_LayerType")] [Migration("20230626171614_LayerType")]
partial class LayerType partial class LayerType
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class LayerType : Migration public partial class LayerType : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20230821105757_Record.Values")] [Migration("20230821105757_Record.Values")]
partial class RecordValues partial class RecordValues
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class RecordValues : Migration public partial class RecordValues : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20230917110252_Layer.parent")] [Migration("20230917110252_Layer.parent")]
partial class Layerparent partial class Layerparent
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class Layerparent : Migration public partial class Layerparent : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20230918090621_ProcessSource")] [Migration("20230918090621_ProcessSource")]
partial class ProcessSource partial class ProcessSource
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class ProcessSource : Migration public partial class ProcessSource : Migration

View File

@@ -6,19 +6,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20230918093055_TypeO")] [Migration("20230918093055_TypeO")]
partial class TypeO partial class TypeO
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class TypeO : Migration public partial class TypeO : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20231030142419_Record.Value32")] [Migration("20231030142419_Record.Value32")]
partial class RecordValue32 partial class RecordValue32
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class RecordValue32 : Migration public partial class RecordValue32 : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20240309075645_Change record value type")] [Migration("20240309075645_Change record value type")]
partial class Changerecordvaluetype partial class Changerecordvaluetype
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class Changerecordvaluetype : Migration public partial class Changerecordvaluetype : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20240703171630_AfterCodeRefactor")] [Migration("20240703171630_AfterCodeRefactor")]
partial class AfterCodeRefactor partial class AfterCodeRefactor
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class AfterCodeRefactor : Migration public partial class AfterCodeRefactor : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20240703173337_DataInboxModel")] [Migration("20240703173337_DataInboxModel")]
partial class DataInboxModel partial class DataInboxModel
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class DataInboxModel : Migration public partial class DataInboxModel : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20240825144443_QueueJobs")] [Migration("20240825144443_QueueJobs")]
partial class QueueJobs partial class QueueJobs
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class QueueJobs : Migration public partial class QueueJobs : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20250317114722_LongerDesc1")] [Migration("20250317114722_LongerDesc1")]
partial class LongerDesc1 partial class LongerDesc1
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class LongerDesc1 : Migration public partial class LongerDesc1 : Migration

View File

@@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20250529093632_LayersIsCancelled")] [Migration("20250529093632_LayersIsCancelled")]
partial class LayersIsCancelled partial class LayersIsCancelled
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -2,7 +2,7 @@
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class LayersIsCancelled : Migration public partial class LayersIsCancelled : Migration

View File

@@ -1,22 +1,23 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using DiunaBI.Core.Database.Context;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20250607084540_QueueJobRefactor")] [Migration("20250607084540_QueueJobRefactor")]
partial class QueueJobRefactor partial class QueueJobRefactor
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class QueueJobRefactor : Migration public partial class QueueJobRefactor : Migration

View File

@@ -1,22 +1,23 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using DiunaBI.Core.Database.Context;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20250725133501_DataInbox.LayerId")] [Migration("20250725133501_DataInbox.LayerId")]
partial class DataInboxLayerId partial class DataInboxLayerId
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class DataInboxLayerId : Migration public partial class DataInboxLayerId : Migration

View File

@@ -1,22 +1,23 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using DiunaBI.Core.Database.Context;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
[Migration("20250726091001_Remove DataInbox.LayerId")] [Migration("20250726091001_Remove DataInbox.LayerId")]
partial class RemoveDataInboxLayerId partial class RemoveDataInboxLayerId
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class RemoveDataInboxLayerId : Migration public partial class RemoveDataInboxLayerId : Migration

View File

@@ -0,0 +1,428 @@
// <auto-generated />
using System;
using DiunaBI.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DiunaBI.Infrastructure.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20251119110709_UpdateModel")]
partial class UpdateModel
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DiunaBI.Domain.Entities.DataInbox", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Source")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("DataInbox");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsCancelled")
.HasColumnType("bit");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTime>("ModifiedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<int>("Number")
.HasColumnType("int");
b.Property<Guid?>("ParentId")
.HasColumnType("uniqueidentifier");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("ModifiedById");
b.ToTable("Layers");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.ProcessSource", b =>
{
b.Property<Guid>("LayerId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("SourceId")
.HasColumnType("uniqueidentifier");
b.HasKey("LayerId", "SourceId");
b.HasIndex("SourceId");
b.ToTable("ProcessSources");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.QueueJob", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("datetime2");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<DateTime>("CreatedAtUtc")
.HasColumnType("datetime2");
b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier");
b.Property<int>("JobType")
.HasColumnType("int");
b.Property<DateTime?>("LastAttemptAt")
.HasColumnType("datetime2");
b.Property<string>("LastError")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<Guid>("LayerId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LayerName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<int>("MaxRetries")
.HasColumnType("int");
b.Property<DateTime>("ModifiedAtUtc")
.HasColumnType("datetime2");
b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier");
b.Property<string>("PluginName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("Priority")
.HasColumnType("int");
b.Property<int>("RetryCount")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("QueueJobs");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Record", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier");
b.Property<string>("Desc1")
.HasMaxLength(10000)
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<Guid>("LayerId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("ModifiedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier");
b.Property<double?>("Value1")
.HasColumnType("float");
b.Property<double?>("Value10")
.HasColumnType("float");
b.Property<double?>("Value11")
.HasColumnType("float");
b.Property<double?>("Value12")
.HasColumnType("float");
b.Property<double?>("Value13")
.HasColumnType("float");
b.Property<double?>("Value14")
.HasColumnType("float");
b.Property<double?>("Value15")
.HasColumnType("float");
b.Property<double?>("Value16")
.HasColumnType("float");
b.Property<double?>("Value17")
.HasColumnType("float");
b.Property<double?>("Value18")
.HasColumnType("float");
b.Property<double?>("Value19")
.HasColumnType("float");
b.Property<double?>("Value2")
.HasColumnType("float");
b.Property<double?>("Value20")
.HasColumnType("float");
b.Property<double?>("Value21")
.HasColumnType("float");
b.Property<double?>("Value22")
.HasColumnType("float");
b.Property<double?>("Value23")
.HasColumnType("float");
b.Property<double?>("Value24")
.HasColumnType("float");
b.Property<double?>("Value25")
.HasColumnType("float");
b.Property<double?>("Value26")
.HasColumnType("float");
b.Property<double?>("Value27")
.HasColumnType("float");
b.Property<double?>("Value28")
.HasColumnType("float");
b.Property<double?>("Value29")
.HasColumnType("float");
b.Property<double?>("Value3")
.HasColumnType("float");
b.Property<double?>("Value30")
.HasColumnType("float");
b.Property<double?>("Value31")
.HasColumnType("float");
b.Property<double?>("Value32")
.HasColumnType("float");
b.Property<double?>("Value4")
.HasColumnType("float");
b.Property<double?>("Value5")
.HasColumnType("float");
b.Property<double?>("Value6")
.HasColumnType("float");
b.Property<double?>("Value7")
.HasColumnType("float");
b.Property<double?>("Value8")
.HasColumnType("float");
b.Property<double?>("Value9")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("LayerId");
b.HasIndex("ModifiedById");
b.ToTable("Records");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Email")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("UserName")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{
b.HasOne("DiunaBI.Domain.Entities.User", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.User", "ModifiedBy")
.WithMany()
.HasForeignKey("ModifiedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("CreatedBy");
b.Navigation("ModifiedBy");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.ProcessSource", b =>
{
b.HasOne("DiunaBI.Domain.Entities.Layer", null)
.WithMany()
.HasForeignKey("LayerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.Layer", "Source")
.WithMany()
.HasForeignKey("SourceId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Source");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Record", b =>
{
b.HasOne("DiunaBI.Domain.Entities.User", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.Layer", null)
.WithMany("Records")
.HasForeignKey("LayerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.User", "ModifiedBy")
.WithMany()
.HasForeignKey("ModifiedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("CreatedBy");
b.Navigation("ModifiedBy");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{
b.Navigation("Records");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,295 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DiunaBI.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class UpdateModel : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Layers_Users_CreatedById",
table: "Layers");
migrationBuilder.DropForeignKey(
name: "FK_Layers_Users_ModifiedById",
table: "Layers");
migrationBuilder.DropForeignKey(
name: "FK_ProcessSources_Layers_SourceId",
table: "ProcessSources");
migrationBuilder.DropForeignKey(
name: "FK_Records_Users_CreatedById",
table: "Records");
migrationBuilder.DropForeignKey(
name: "FK_Records_Users_ModifiedById",
table: "Records");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "Users",
type: "datetime2",
nullable: false,
defaultValueSql: "GETUTCDATE()",
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "ModifiedAt",
table: "Records",
type: "datetime2",
nullable: false,
defaultValueSql: "GETUTCDATE()",
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "Records",
type: "datetime2",
nullable: false,
defaultValueSql: "GETUTCDATE()",
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "QueueJobs",
type: "datetime2",
nullable: false,
defaultValueSql: "GETUTCDATE()",
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "ModifiedAt",
table: "Layers",
type: "datetime2",
nullable: false,
defaultValueSql: "GETUTCDATE()",
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<bool>(
name: "IsDeleted",
table: "Layers",
type: "bit",
nullable: false,
defaultValue: false,
oldClrType: typeof(bool),
oldType: "bit");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "Layers",
type: "datetime2",
nullable: false,
defaultValueSql: "GETUTCDATE()",
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "DataInbox",
type: "datetime2",
nullable: false,
defaultValueSql: "GETUTCDATE()",
oldClrType: typeof(DateTime),
oldType: "datetime2");
migrationBuilder.AddForeignKey(
name: "FK_Layers_Users_CreatedById",
table: "Layers",
column: "CreatedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
migrationBuilder.AddForeignKey(
name: "FK_Layers_Users_ModifiedById",
table: "Layers",
column: "ModifiedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
migrationBuilder.AddForeignKey(
name: "FK_ProcessSources_Layers_LayerId",
table: "ProcessSources",
column: "LayerId",
principalTable: "Layers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_ProcessSources_Layers_SourceId",
table: "ProcessSources",
column: "SourceId",
principalTable: "Layers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
migrationBuilder.AddForeignKey(
name: "FK_Records_Users_CreatedById",
table: "Records",
column: "CreatedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
migrationBuilder.AddForeignKey(
name: "FK_Records_Users_ModifiedById",
table: "Records",
column: "ModifiedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Layers_Users_CreatedById",
table: "Layers");
migrationBuilder.DropForeignKey(
name: "FK_Layers_Users_ModifiedById",
table: "Layers");
migrationBuilder.DropForeignKey(
name: "FK_ProcessSources_Layers_LayerId",
table: "ProcessSources");
migrationBuilder.DropForeignKey(
name: "FK_ProcessSources_Layers_SourceId",
table: "ProcessSources");
migrationBuilder.DropForeignKey(
name: "FK_Records_Users_CreatedById",
table: "Records");
migrationBuilder.DropForeignKey(
name: "FK_Records_Users_ModifiedById",
table: "Records");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "Users",
type: "datetime2",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldDefaultValueSql: "GETUTCDATE()");
migrationBuilder.AlterColumn<DateTime>(
name: "ModifiedAt",
table: "Records",
type: "datetime2",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldDefaultValueSql: "GETUTCDATE()");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "Records",
type: "datetime2",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldDefaultValueSql: "GETUTCDATE()");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "QueueJobs",
type: "datetime2",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldDefaultValueSql: "GETUTCDATE()");
migrationBuilder.AlterColumn<DateTime>(
name: "ModifiedAt",
table: "Layers",
type: "datetime2",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldDefaultValueSql: "GETUTCDATE()");
migrationBuilder.AlterColumn<bool>(
name: "IsDeleted",
table: "Layers",
type: "bit",
nullable: false,
oldClrType: typeof(bool),
oldType: "bit",
oldDefaultValue: false);
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "Layers",
type: "datetime2",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldDefaultValueSql: "GETUTCDATE()");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "DataInbox",
type: "datetime2",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldDefaultValueSql: "GETUTCDATE()");
migrationBuilder.AddForeignKey(
name: "FK_Layers_Users_CreatedById",
table: "Layers",
column: "CreatedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Layers_Users_ModifiedById",
table: "Layers",
column: "ModifiedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_ProcessSources_Layers_SourceId",
table: "ProcessSources",
column: "SourceId",
principalTable: "Layers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Records_Users_CreatedById",
table: "Records",
column: "CreatedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Records_Users_ModifiedById",
table: "Records",
column: "ModifiedById",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@@ -0,0 +1,430 @@
// <auto-generated />
using System;
using DiunaBI.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DiunaBI.Infrastructure.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20251120193110_FixLayerDefaultValues")]
partial class FixLayerDefaultValues
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DiunaBI.Domain.Entities.DataInbox", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("Source")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("DataInbox");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier");
b.Property<bool>("IsCancelled")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTime>("ModifiedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<int>("Number")
.HasColumnType("int");
b.Property<Guid?>("ParentId")
.HasColumnType("uniqueidentifier");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("ModifiedById");
b.ToTable("Layers");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.ProcessSource", b =>
{
b.Property<Guid>("LayerId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("SourceId")
.HasColumnType("uniqueidentifier");
b.HasKey("LayerId", "SourceId");
b.HasIndex("SourceId");
b.ToTable("ProcessSources");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.QueueJob", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("datetime2");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<DateTime>("CreatedAtUtc")
.HasColumnType("datetime2");
b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier");
b.Property<int>("JobType")
.HasColumnType("int");
b.Property<DateTime?>("LastAttemptAt")
.HasColumnType("datetime2");
b.Property<string>("LastError")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<Guid>("LayerId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LayerName")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("nvarchar(200)");
b.Property<int>("MaxRetries")
.HasColumnType("int");
b.Property<DateTime>("ModifiedAtUtc")
.HasColumnType("datetime2");
b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier");
b.Property<string>("PluginName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("nvarchar(100)");
b.Property<int>("Priority")
.HasColumnType("int");
b.Property<int>("RetryCount")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("QueueJobs");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Record", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier");
b.Property<string>("Desc1")
.HasMaxLength(10000)
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.HasColumnType("bit");
b.Property<Guid>("LayerId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("ModifiedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier");
b.Property<double?>("Value1")
.HasColumnType("float");
b.Property<double?>("Value10")
.HasColumnType("float");
b.Property<double?>("Value11")
.HasColumnType("float");
b.Property<double?>("Value12")
.HasColumnType("float");
b.Property<double?>("Value13")
.HasColumnType("float");
b.Property<double?>("Value14")
.HasColumnType("float");
b.Property<double?>("Value15")
.HasColumnType("float");
b.Property<double?>("Value16")
.HasColumnType("float");
b.Property<double?>("Value17")
.HasColumnType("float");
b.Property<double?>("Value18")
.HasColumnType("float");
b.Property<double?>("Value19")
.HasColumnType("float");
b.Property<double?>("Value2")
.HasColumnType("float");
b.Property<double?>("Value20")
.HasColumnType("float");
b.Property<double?>("Value21")
.HasColumnType("float");
b.Property<double?>("Value22")
.HasColumnType("float");
b.Property<double?>("Value23")
.HasColumnType("float");
b.Property<double?>("Value24")
.HasColumnType("float");
b.Property<double?>("Value25")
.HasColumnType("float");
b.Property<double?>("Value26")
.HasColumnType("float");
b.Property<double?>("Value27")
.HasColumnType("float");
b.Property<double?>("Value28")
.HasColumnType("float");
b.Property<double?>("Value29")
.HasColumnType("float");
b.Property<double?>("Value3")
.HasColumnType("float");
b.Property<double?>("Value30")
.HasColumnType("float");
b.Property<double?>("Value31")
.HasColumnType("float");
b.Property<double?>("Value32")
.HasColumnType("float");
b.Property<double?>("Value4")
.HasColumnType("float");
b.Property<double?>("Value5")
.HasColumnType("float");
b.Property<double?>("Value6")
.HasColumnType("float");
b.Property<double?>("Value7")
.HasColumnType("float");
b.Property<double?>("Value8")
.HasColumnType("float");
b.Property<double?>("Value9")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("CreatedById");
b.HasIndex("LayerId");
b.HasIndex("ModifiedById");
b.ToTable("Records");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Email")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.Property<string>("UserName")
.HasMaxLength(50)
.HasColumnType("nvarchar(50)");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{
b.HasOne("DiunaBI.Domain.Entities.User", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.User", "ModifiedBy")
.WithMany()
.HasForeignKey("ModifiedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("CreatedBy");
b.Navigation("ModifiedBy");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.ProcessSource", b =>
{
b.HasOne("DiunaBI.Domain.Entities.Layer", null)
.WithMany()
.HasForeignKey("LayerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.Layer", "Source")
.WithMany()
.HasForeignKey("SourceId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Source");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Record", b =>
{
b.HasOne("DiunaBI.Domain.Entities.User", "CreatedBy")
.WithMany()
.HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.Layer", null)
.WithMany("Records")
.HasForeignKey("LayerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.User", "ModifiedBy")
.WithMany()
.HasForeignKey("ModifiedById")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("CreatedBy");
b.Navigation("ModifiedBy");
});
modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{
b.Navigation("Records");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,47 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DiunaBI.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class FixLayerDefaultValues : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
// Ensure IsDeleted has default constraint (in case previous migration didn't apply it correctly)
migrationBuilder.Sql(@"
IF NOT EXISTS (SELECT 1 FROM sys.default_constraints
WHERE parent_object_id = OBJECT_ID('Layers')
AND COL_NAME(parent_object_id, parent_column_id) = 'IsDeleted')
BEGIN
ALTER TABLE [Layers] ADD CONSTRAINT [DF_Layers_IsDeleted] DEFAULT 0 FOR [IsDeleted];
END
");
// Add default constraint for IsCancelled
migrationBuilder.AlterColumn<bool>(
name: "IsCancelled",
table: "Layers",
type: "bit",
nullable: false,
defaultValue: false,
oldClrType: typeof(bool),
oldType: "bit");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<bool>(
name: "IsCancelled",
table: "Layers",
type: "bit",
nullable: false,
oldClrType: typeof(bool),
oldType: "bit",
oldDefaultValue: false);
}
}
}

View File

@@ -1,6 +1,6 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using DiunaBI.Core.Database.Context; using DiunaBI.Infrastructure.Data;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
@@ -8,7 +8,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable #nullable disable
namespace DiunaBI.Core.Migrations namespace DiunaBI.Infrastructure.Migrations
{ {
[DbContext(typeof(AppDbContext))] [DbContext(typeof(AppDbContext))]
partial class AppDbContextModelSnapshot : ModelSnapshot partial class AppDbContextModelSnapshot : ModelSnapshot
@@ -17,23 +17,24 @@ namespace DiunaBI.Core.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "8.0.0") .HasAnnotation("ProductVersion", "10.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128); .HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DiunaBI.Core.Models.DataInbox", b => modelBuilder.Entity("DiunaBI.Domain.Entities.DataInbox", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt") b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2"); .ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Data") b.Property<string>("Data")
.IsRequired() .IsRequired()
.HasMaxLength(2147483647)
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<string>("Name") b.Property<string>("Name")
@@ -51,26 +52,34 @@ namespace DiunaBI.Core.Migrations
b.ToTable("DataInbox"); b.ToTable("DataInbox");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.Layer", b => modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt") b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2"); .ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("CreatedById") b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<bool>("IsCancelled") b.Property<bool>("IsCancelled")
.HasColumnType("bit"); .ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<bool>("IsDeleted") b.Property<bool>("IsDeleted")
.HasColumnType("bit"); .ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTime>("ModifiedAt") b.Property<DateTime>("ModifiedAt")
.HasColumnType("datetime2"); .ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("ModifiedById") b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
@@ -98,7 +107,7 @@ namespace DiunaBI.Core.Migrations
b.ToTable("Layers"); b.ToTable("Layers");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.ProcessSource", b => modelBuilder.Entity("DiunaBI.Domain.Entities.ProcessSource", b =>
{ {
b.Property<Guid>("LayerId") b.Property<Guid>("LayerId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
@@ -113,7 +122,7 @@ namespace DiunaBI.Core.Migrations
b.ToTable("ProcessSources"); b.ToTable("ProcessSources");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.QueueJob", b => modelBuilder.Entity("DiunaBI.Domain.Entities.QueueJob", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
@@ -123,7 +132,9 @@ namespace DiunaBI.Core.Migrations
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<DateTime>("CreatedAt") b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2"); .ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<DateTime>("CreatedAtUtc") b.Property<DateTime>("CreatedAtUtc")
.HasColumnType("datetime2"); .HasColumnType("datetime2");
@@ -177,7 +188,7 @@ namespace DiunaBI.Core.Migrations
b.ToTable("QueueJobs"); b.ToTable("QueueJobs");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.Record", b => modelBuilder.Entity("DiunaBI.Domain.Entities.Record", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
@@ -189,7 +200,9 @@ namespace DiunaBI.Core.Migrations
.HasColumnType("nvarchar(50)"); .HasColumnType("nvarchar(50)");
b.Property<DateTime>("CreatedAt") b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2"); .ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("CreatedById") b.Property<Guid>("CreatedById")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
@@ -205,7 +218,9 @@ namespace DiunaBI.Core.Migrations
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<DateTime>("ModifiedAt") b.Property<DateTime>("ModifiedAt")
.HasColumnType("datetime2"); .ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<Guid>("ModifiedById") b.Property<Guid>("ModifiedById")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
@@ -317,14 +332,16 @@ namespace DiunaBI.Core.Migrations
b.ToTable("Records"); b.ToTable("Records");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.User", b => modelBuilder.Entity("DiunaBI.Domain.Entities.User", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreatedAt") b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime2"); .ValueGeneratedOnAdd()
.HasColumnType("datetime2")
.HasDefaultValueSql("GETUTCDATE()");
b.Property<string>("Email") b.Property<string>("Email")
.HasMaxLength(50) .HasMaxLength(50)
@@ -339,18 +356,18 @@ namespace DiunaBI.Core.Migrations
b.ToTable("Users"); b.ToTable("Users");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.Layer", b => modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{ {
b.HasOne("DiunaBI.Core.Models.User", "CreatedBy") b.HasOne("DiunaBI.Domain.Entities.User", "CreatedBy")
.WithMany() .WithMany()
.HasForeignKey("CreatedById") .HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Restrict)
.IsRequired(); .IsRequired();
b.HasOne("DiunaBI.Core.Models.User", "ModifiedBy") b.HasOne("DiunaBI.Domain.Entities.User", "ModifiedBy")
.WithMany() .WithMany()
.HasForeignKey("ModifiedById") .HasForeignKey("ModifiedById")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Restrict)
.IsRequired(); .IsRequired();
b.Navigation("CreatedBy"); b.Navigation("CreatedBy");
@@ -358,35 +375,41 @@ namespace DiunaBI.Core.Migrations
b.Navigation("ModifiedBy"); b.Navigation("ModifiedBy");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.ProcessSource", b => modelBuilder.Entity("DiunaBI.Domain.Entities.ProcessSource", b =>
{ {
b.HasOne("DiunaBI.Core.Models.Layer", "Source") b.HasOne("DiunaBI.Domain.Entities.Layer", null)
.WithMany()
.HasForeignKey("LayerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("DiunaBI.Domain.Entities.Layer", "Source")
.WithMany() .WithMany()
.HasForeignKey("SourceId") .HasForeignKey("SourceId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Restrict)
.IsRequired(); .IsRequired();
b.Navigation("Source"); b.Navigation("Source");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.Record", b => modelBuilder.Entity("DiunaBI.Domain.Entities.Record", b =>
{ {
b.HasOne("DiunaBI.Core.Models.User", "CreatedBy") b.HasOne("DiunaBI.Domain.Entities.User", "CreatedBy")
.WithMany() .WithMany()
.HasForeignKey("CreatedById") .HasForeignKey("CreatedById")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Restrict)
.IsRequired(); .IsRequired();
b.HasOne("DiunaBI.Core.Models.Layer", null) b.HasOne("DiunaBI.Domain.Entities.Layer", null)
.WithMany("Records") .WithMany("Records")
.HasForeignKey("LayerId") .HasForeignKey("LayerId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.HasOne("DiunaBI.Core.Models.User", "ModifiedBy") b.HasOne("DiunaBI.Domain.Entities.User", "ModifiedBy")
.WithMany() .WithMany()
.HasForeignKey("ModifiedById") .HasForeignKey("ModifiedById")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Restrict)
.IsRequired(); .IsRequired();
b.Navigation("CreatedBy"); b.Navigation("CreatedBy");
@@ -394,7 +417,7 @@ namespace DiunaBI.Core.Migrations
b.Navigation("ModifiedBy"); b.Navigation("ModifiedBy");
}); });
modelBuilder.Entity("DiunaBI.Core.Models.Layer", b => modelBuilder.Entity("DiunaBI.Domain.Entities.Layer", b =>
{ {
b.Navigation("Records"); b.Navigation("Records");
}); });

View File

@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
using AngouriMath; using AngouriMath;
using DiunaBI.Core.Models; using DiunaBI.Domain.Entities;
namespace DiunaBI.Core.Services.Calculations; namespace DiunaBI.Infrastructure.Services.Calculations;
public class BaseCalc public class BaseCalc
{ {

View File

@@ -1,9 +1,8 @@
using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3; using Google.Apis.Drive.v3;
using Google.Apis.Services; using Google.Apis.Services;
using System.IO;
namespace DiunaBI.Core.Services; namespace DiunaBI.Infrastructure.Services;
public class GoogleDriveHelper public class GoogleDriveHelper
{ {
@@ -25,13 +24,15 @@ public class GoogleDriveHelper
} }
private static GoogleCredential GetCredentialsFromFile() private static GoogleCredential GetCredentialsFromFile()
{ {
// ReSharper disable once RedundantAssignment
var fileName = "client_secrets.json";
#if DEBUG #if DEBUG
fileName = "client_secrets.Development.json"; using var stream = new FileStream("client_secrets.Development.json", FileMode.Open, FileAccess.Read);
return GoogleCredential.FromStream(stream).CreateScoped(Scopes);
#else
var json = Environment.GetEnvironmentVariable("GOOGLE_SERVICE_ACCOUNT_JSON");
if (string.IsNullOrWhiteSpace(json))
throw new InvalidOperationException("GOOGLE_SERVICE_ACCOUNT_JSON environment variable is not set.");
json = json.Replace("\\n", "\n");
return GoogleCredential.FromJson(json).CreateScoped(Scopes);
#endif #endif
using var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
var credential = GoogleCredential.FromStream(stream).CreateScoped(Scopes);
return credential;
} }
} }

View File

@@ -0,0 +1,48 @@
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Sheets.v4;
namespace DiunaBI.Infrastructure.Services;
public class GoogleSheetsHelper
{
public SheetsService? Service { get; private set; }
private const string ApplicationName = "Diuna";
private static readonly string[] Scopes = [SheetsService.Scope.Spreadsheets];
public GoogleSheetsHelper()
{
InitializeService();
}
private void InitializeService()
{
var credential = GetCredentialsFromFile();
Service = new SheetsService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});
}
private static GoogleCredential GetCredentialsFromFile()
{
#if DEBUG
using var stream = new FileStream("client_secrets.Development.json", FileMode.Open, FileAccess.Read);
return GoogleCredential.FromStream(stream).CreateScoped(Scopes);
#else
var json = Environment.GetEnvironmentVariable("GOOGLE_SERVICE_ACCOUNT_JSON");
if (string.IsNullOrWhiteSpace(json))
throw new InvalidOperationException("GOOGLE_SERVICE_ACCOUNT_JSON environment variable is not set.");
Console.WriteLine($"[GoogleSheetsHelper] Loading credentials from environment variable (length: {json.Length})");
try
{
return GoogleCredential.FromJson(json).CreateScoped(Scopes);
}
catch (Exception ex)
{
Console.WriteLine($"[GoogleSheetsHelper] ERROR: Failed to parse credentials - {ex.Message}");
throw new InvalidOperationException("Failed to parse Google service account credentials. Ensure GOOGLE_SERVICE_ACCOUNT_JSON is properly formatted.", ex);
}
#endif
}
}

View File

@@ -1,13 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using DiunaBI.Core.Interfaces; using DiunaBI.Infrastructure.Interfaces;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace DiunaBI.Core.Services; namespace DiunaBI.Infrastructure.Services;
public class PluginManager public class PluginManager
{ {

View File

@@ -1,9 +1,7 @@
using System; using System.Text.RegularExpressions;
using System.Collections.Generic; using DiunaBI.Domain.Entities;
using System.Text.RegularExpressions;
using DiunaBI.Core.Models;
namespace DiunaBI.Core.Services; namespace DiunaBI.Infrastructure.Services;
public static class ProcessHelper public static class ProcessHelper
{ {

View File

@@ -1,16 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.68.0.3525" /> <PackageReference Include="Google.Apis.Sheets.v4" Version="1.68.0.3525" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\DiunaBI.Core\DiunaBI.Core.csproj" /> <ProjectReference Include="..\DiunaBI.Domain\DiunaBI.Domain.csproj" />
<ProjectReference Include="..\DiunaBI.Infrastructure\DiunaBI.Infrastructure.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,5 +1,5 @@
using DiunaBI.Core.Interfaces; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Models; using DiunaBI.Infrastructure.Interfaces;
namespace DiunaBI.Plugins.Morska.Exporters; namespace DiunaBI.Plugins.Morska.Exporters;

View File

@@ -1,11 +1,11 @@
using System.Globalization; using System.Globalization;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Services;
using Google.Apis.Sheets.v4; using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data; using Google.Apis.Sheets.v4.Data;
using DiunaBI.Core.Models;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using DiunaBI.Plugins.Morska.Exporters;
namespace DiunaBI.Core.Services.Exports; namespace DiunaBI.Plugins.Morska.Exporters;
public class GoogleSheetExport : MorskaBaseExporter public class GoogleSheetExport : MorskaBaseExporter
{ {

View File

@@ -1,5 +1,5 @@
using DiunaBI.Core.Interfaces; using DiunaBI.Domain.Entities;
using DiunaBI.Core.Models; using DiunaBI.Infrastructure.Interfaces;
namespace DiunaBI.Plugins.Morska.Importers; namespace DiunaBI.Plugins.Morska.Importers;

View File

@@ -1,9 +1,10 @@
using System.Globalization; using System.Globalization;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
using Google.Apis.Sheets.v4; using Google.Apis.Sheets.v4;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using DiunaBI.Core.Models;
using DiunaBI.Core.Database.Context;
namespace DiunaBI.Plugins.Morska.Importers; namespace DiunaBI.Plugins.Morska.Importers;

View File

@@ -1,11 +1,11 @@
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
using DiunaBI.Infrastructure.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using DiunaBI.Core.Models;
using DiunaBI.Core.Database.Context;
using DiunaBI.Core.Services;
using Google.Apis.Sheets.v4; using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data; using Google.Apis.Sheets.v4.Data;

View File

@@ -1,9 +1,9 @@
using System.Globalization; using System.Globalization;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
using Google.Apis.Sheets.v4; using Google.Apis.Sheets.v4;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using DiunaBI.Core.Models;
using DiunaBI.Core.Database.Context;
namespace DiunaBI.Plugins.Morska.Importers; namespace DiunaBI.Plugins.Morska.Importers;

View File

@@ -1,9 +1,10 @@
using System.Globalization; using System.Globalization;
using DiunaBI.Domain.Entities;
using DiunaBI.Infrastructure.Data;
using Google.Apis.Sheets.v4; using Google.Apis.Sheets.v4;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using DiunaBI.Core.Models;
using DiunaBI.Core.Database.Context;
namespace DiunaBI.Plugins.Morska.Importers; namespace DiunaBI.Plugins.Morska.Importers;

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