Compare commits
71 Commits
a4c8178bf2
...
ddd-refact
| Author | SHA1 | Date | |
|---|---|---|---|
| 091e33a75e | |||
| 908770f4e3 | |||
| 4965c3ecd7 | |||
| aa6c54a692 | |||
| bb41926a31 | |||
| 0a5382081f | |||
| 3514c022d6 | |||
| 3a9b8c7b27 | |||
| d289fbb274 | |||
| e83ab80dff | |||
| 1a84179586 | |||
| 0b665f238b | |||
| 6ed470a1b8 | |||
| 31c3b59411 | |||
| 8077826c46 | |||
| 951855074f | |||
| 7558bb80e3 | |||
| 090224b19f | |||
| e6b4563712 | |||
| 2ecfc5bfe5 | |||
| 3b03c52cd4 | |||
| 62cf71eaa8 | |||
| cfb0cdc2f7 | |||
| 66a9b975a5 | |||
| c0a1945465 | |||
| 5a5b70a5ed | |||
| 8e3210f0e6 | |||
| 58e5ad7f5b | |||
| f354874e3d | |||
| ec4b79bbc6 | |||
| ae5db26479 | |||
| f30a8a74ff | |||
| c6a777c245 | |||
|
|
a66e2a86da | ||
|
|
7cd69da0bd | ||
|
|
29aae21f97 | ||
|
|
eeae4b55a4 | ||
|
|
5a896f46b7 | ||
|
|
5d40af5446 | ||
|
|
fd39b72596 | ||
|
|
f7b9009215 | ||
|
|
95438efcbd | ||
|
|
337eab3b41 | ||
|
|
7f04cab0d9 | ||
|
|
5bee3912f1 | ||
|
|
b65ea7d17f | ||
|
|
fa3e380597 | ||
|
|
071396f126 | ||
|
|
66b650119b | ||
|
|
5d33a5a9a5 | ||
|
|
642850306a | ||
|
|
a3f00f8c47 | ||
|
|
1d59aec5a9 | ||
|
|
493cd748dc | ||
|
|
6feb20c85e | ||
|
|
504a331f9a | ||
|
|
9981b1c21b | ||
|
|
dcbbdc287a | ||
|
|
a4249728be | ||
|
|
b0e779947c | ||
|
|
687f5b2be3 | ||
|
|
e2e0e753f2 | ||
|
|
b73a037605 | ||
|
|
21cb4c44e8 | ||
|
|
ec8c8aef35 | ||
|
|
fc1325de58 | ||
|
|
8fcde802d7 | ||
|
|
f8bd0afb45 | ||
|
|
728ae32058 | ||
|
|
df2fa3319b | ||
|
|
142f2a28e7 |
@@ -1,89 +1,122 @@
|
|||||||
// .gitea/scripts/getLatestRunWithArtifacts.js
|
// .gitea/scripts/getLatestRunWithArtifacts.js
|
||||||
// Purpose: Find latest successful run that exposes all REQUIRED_ARTIFACTS via GUI URLs.
|
// Purpose: Find latest successful run that exposes all REQUIRED_ARTIFACTS via GUI URLs.
|
||||||
|
// Strategy:
|
||||||
|
// 1. Try to list runs via API (/actions/runs).
|
||||||
|
// 2. If not available (404), fallback to scraping HTML /actions page.
|
||||||
|
// 3. For each run (newest first, only "success"), check artifacts by probing GUI URLs.
|
||||||
// Outputs: sets `run_id` to GITHUB_OUTPUT and writes .gitea/.cache/run_id file.
|
// Outputs: sets `run_id` to GITHUB_OUTPUT and writes .gitea/.cache/run_id file.
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
(async () => {
|
const BASE = process.env.GITEA_BASE_URL;
|
||||||
// --- Config from environment ---
|
const OWNER = process.env.OWNER;
|
||||||
const BASE = process.env.GITEA_BASE_URL; // e.g. https://code.bim-it.pl
|
const REPO = process.env.REPO;
|
||||||
const OWNER = process.env.OWNER; // e.g. mz
|
const TOKEN = process.env.GITEA_PAT;
|
||||||
const REPO = process.env.REPO; // e.g. DiunaBI
|
const SCAN_LIMIT = Number(process.env.SCAN_LIMIT || "100");
|
||||||
const TOKEN = process.env.GITEA_PAT; // PAT
|
const REQUIRED_ARTIFACTS = (process.env.REQUIRED_ARTIFACTS || "frontend,webapi")
|
||||||
const SCAN_LIMIT = Number(process.env.SCAN_LIMIT || "100");
|
.split(",").map(s => s.trim()).filter(Boolean);
|
||||||
const REQUIRED_ARTIFACTS = (process.env.REQUIRED_ARTIFACTS || "frontend,webapi")
|
|
||||||
.split(",")
|
|
||||||
.map(s => s.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
if (!BASE || !OWNER || !REPO) {
|
if (!BASE || !OWNER || !REPO) {
|
||||||
console.error("Missing one of: GITEA_BASE_URL, OWNER, REPO");
|
console.error("Missing one of: GITEA_BASE_URL, OWNER, REPO");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
if (!TOKEN) {
|
if (!TOKEN) {
|
||||||
console.error("Missing GITEA_PAT");
|
console.error("Missing GITEA_PAT");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheDir = path.join(".gitea", ".cache");
|
||||||
|
fs.mkdirSync(cacheDir, { recursive: true });
|
||||||
|
|
||||||
|
async function http(url, opts = {}) {
|
||||||
|
return fetch(url, {
|
||||||
|
...opts,
|
||||||
|
headers: { Authorization: `token ${TOKEN}`, ...(opts.headers || {}) },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function apiJSON(url) {
|
||||||
|
const res = await http(url);
|
||||||
|
if (!res.ok) {
|
||||||
|
const text = await res.text().catch(() => "");
|
||||||
|
const err = new Error(`API ${res.status} ${res.statusText} for ${url}\n${text}`);
|
||||||
|
err.status = res.status;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Run listing ----
|
||||||
|
function normalizeRunList(resp) {
|
||||||
|
if (Array.isArray(resp)) return resp;
|
||||||
|
return resp?.runs || resp?.workflow_runs || resp?.data || resp?.items || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tryApiListRuns() {
|
||||||
|
const url = `${BASE}/api/v1/repos/${OWNER}/${REPO}/actions/runs?limit=${SCAN_LIMIT}`;
|
||||||
|
try {
|
||||||
|
const resp = await apiJSON(url);
|
||||||
|
return normalizeRunList(resp);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.status === 404) return null;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function listRunsFromHtml() {
|
||||||
|
const url = `${BASE}/${OWNER}/${REPO}/actions`;
|
||||||
|
const res = await http(url, { headers: { Accept: "text/html" } });
|
||||||
|
if (!res.ok) {
|
||||||
|
const t = await res.text().catch(() => "");
|
||||||
|
throw new Error(`HTML ${res.status} for ${url}\n${t}`);
|
||||||
|
}
|
||||||
|
const html = await res.text();
|
||||||
|
const runIds = Array.from(html.matchAll(/\/actions\/runs\/(\d+)/g))
|
||||||
|
.map(m => Number(m[1]))
|
||||||
|
.filter(n => Number.isFinite(n));
|
||||||
|
const unique = [...new Set(runIds)].sort((a, b) => b - a);
|
||||||
|
return unique.slice(0, SCAN_LIMIT).map(id => ({ id, status: "success" })); // HTML doesn’t give status, assume ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Artifact check via GUI URL ----
|
||||||
|
async function headOk(url) {
|
||||||
|
let res = await http(url, { method: "HEAD", redirect: "follow" });
|
||||||
|
if (res.ok) return true;
|
||||||
|
res = await http(url, { method: "GET", redirect: "manual" });
|
||||||
|
return res.status >= 200 && res.status < 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
let runs = await tryApiListRuns();
|
||||||
|
if (!runs) {
|
||||||
|
console.log("Runs API not available on this Gitea – falling back to HTML scraping.");
|
||||||
|
runs = await listRunsFromHtml();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!runs.length) {
|
||||||
|
console.error("No workflow runs found.");
|
||||||
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure cache dir exists
|
// newest first
|
||||||
const cacheDir = path.join(".gitea", ".cache");
|
|
||||||
fs.mkdirSync(cacheDir, { recursive: true });
|
|
||||||
|
|
||||||
// Helpers
|
|
||||||
const api = async (url) => {
|
|
||||||
const res = await fetch(url, {
|
|
||||||
headers: { Authorization: `token ${TOKEN}` }
|
|
||||||
});
|
|
||||||
if (!res.ok) {
|
|
||||||
const text = await res.text().catch(() => "");
|
|
||||||
throw new Error(`API ${res.status} ${res.statusText} for ${url}\n${text}`);
|
|
||||||
}
|
|
||||||
return res.json();
|
|
||||||
};
|
|
||||||
|
|
||||||
const headOk = async (url) => {
|
|
||||||
// Try HEAD first; some instances may require GET for redirects
|
|
||||||
let res = await fetch(url, {
|
|
||||||
method: "HEAD",
|
|
||||||
redirect: "follow",
|
|
||||||
headers: { Authorization: `token ${TOKEN}` }
|
|
||||||
});
|
|
||||||
if (res.ok) return true;
|
|
||||||
|
|
||||||
// Fallback to GET (no download) just to test availability
|
|
||||||
res = await fetch(url, {
|
|
||||||
method: "GET",
|
|
||||||
redirect: "manual",
|
|
||||||
headers: { Authorization: `token ${TOKEN}` }
|
|
||||||
});
|
|
||||||
// Accept 200 OK, or 3xx redirect to a signed download URL
|
|
||||||
return res.status >= 200 && res.status < 400;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 1) Get recent workflow runs (a.k.a. tasks) via REST
|
|
||||||
const listUrl = `${BASE}/api/v1/repos/${OWNER}/${REPO}/actions/tasks?limit=${SCAN_LIMIT}`;
|
|
||||||
const resp = await api(listUrl);
|
|
||||||
|
|
||||||
// 2) Build candidate list: only status == "success", newest first by id
|
|
||||||
const runs = Array.isArray(resp.workflow_runs) ? resp.workflow_runs : [];
|
|
||||||
const candidates = runs
|
const candidates = runs
|
||||||
.filter(r => r && r.status === "success")
|
.filter(r => r && r.id != null)
|
||||||
.sort((a, b) => (b.id ?? 0) - (a.id ?? 0));
|
.sort((a, b) => (b.id ?? 0) - (a.id ?? 0))
|
||||||
|
.filter(r => (r.status || "").toLowerCase() === "success" || !r.status); // HTML case: no status info
|
||||||
|
|
||||||
if (!candidates.length) {
|
if (!candidates.length) {
|
||||||
console.error("No successful runs found.");
|
console.error("No successful runs found.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Scanning ${candidates.length} successful runs for artifacts: ${REQUIRED_ARTIFACTS.join(", ")}`);
|
console.log(`Scanning ${candidates.length} runs for artifacts: ${REQUIRED_ARTIFACTS.join(", ")}`);
|
||||||
|
|
||||||
// 3) Find the first run that exposes all required artifacts via GUI URLs
|
|
||||||
let picked = null;
|
let picked = null;
|
||||||
for (const r of candidates) {
|
for (const r of candidates) {
|
||||||
const runId = r.id;
|
const runId = r.id;
|
||||||
const urls = REQUIRED_ARTIFACTS.map(name =>
|
const urls = REQUIRED_ARTIFACTS.map(
|
||||||
`${BASE}/${OWNER}/${REPO}/actions/runs/${runId}/artifacts/${encodeURIComponent(name)}`
|
name => `${BASE}/${OWNER}/${REPO}/actions/runs/${runId}/artifacts/${encodeURIComponent(name)}`
|
||||||
);
|
);
|
||||||
|
|
||||||
let allPresent = true;
|
let allPresent = true;
|
||||||
@@ -95,6 +128,7 @@ const path = require("path");
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allPresent) {
|
if (allPresent) {
|
||||||
picked = { id: runId };
|
picked = { id: runId };
|
||||||
console.log(`Picked run_id=${runId}`);
|
console.log(`Picked run_id=${runId}`);
|
||||||
@@ -103,21 +137,16 @@ const path = require("path");
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!picked) {
|
if (!picked) {
|
||||||
console.error("No run exposes all required artifacts. Consider increasing SCAN_LIMIT or verify artifact names.");
|
console.error("No run exposes all required artifacts.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) Write outputs
|
|
||||||
const runIdStr = String(picked.id);
|
const runIdStr = String(picked.id);
|
||||||
// Write to cache (handy for debugging)
|
|
||||||
fs.writeFileSync(path.join(cacheDir, "run_id"), runIdStr, "utf8");
|
fs.writeFileSync(path.join(cacheDir, "run_id"), runIdStr, "utf8");
|
||||||
|
|
||||||
// Export as GitHub-style output (supported by Gitea runners)
|
if (process.env.GITHUB_OUTPUT) {
|
||||||
const outFile = process.env.GITHUB_OUTPUT;
|
fs.appendFileSync(process.env.GITHUB_OUTPUT, `run_id=${runIdStr}\n`);
|
||||||
if (outFile) {
|
|
||||||
fs.appendFileSync(outFile, `run_id=${runIdStr}\n`);
|
|
||||||
} else {
|
} else {
|
||||||
// Fallback: also print for visibility
|
|
||||||
console.log(`::set-output name=run_id::${runIdStr}`);
|
console.log(`::set-output name=run_id::${runIdStr}`);
|
||||||
}
|
}
|
||||||
})().catch(err => {
|
})().catch(err => {
|
||||||
|
|||||||
91
.gitea/scripts/replaceTokens.js
Normal file
91
.gitea/scripts/replaceTokens.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// .gitea/scripts/replaceTokens.js
|
||||||
|
// Skanuje:
|
||||||
|
// - artifacts/frontend/**/*.js
|
||||||
|
// - artifacts/webapi/appsettings.json (jeśli jest)
|
||||||
|
// - artifacts/webapi/client_secrets.json (jeśli jest)
|
||||||
|
// Tokeny: #{NAME}# -> wartość z VARIABLES/SECRETS (NAME: uppercased, '-'->'_')
|
||||||
|
// Dodatkowo: #{BUILDID}# -> RUN_ID (z ENV)
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
function walk(dir, predicate) {
|
||||||
|
const out = [];
|
||||||
|
if (!fs.existsSync(dir)) return out;
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) out.push(...walk(full, predicate));
|
||||||
|
else if (predicate(full)) out.push(full);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceInFile(file, mapToken) {
|
||||||
|
let data = fs.readFileSync(file, 'utf8');
|
||||||
|
const re = /#\{(.*?)\}#/g;
|
||||||
|
let changed = false;
|
||||||
|
data = data.replace(re, (_, raw) => {
|
||||||
|
const token = (raw || '').replace(/-/g, '_').toUpperCase();
|
||||||
|
const val = mapToken(token);
|
||||||
|
if (val == null || val === '') return `#{${raw}}#`; // zostaw bez zmian, podbijemy błąd później
|
||||||
|
changed = true;
|
||||||
|
return String(val);
|
||||||
|
});
|
||||||
|
fs.writeFileSync(file, data, 'utf8');
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const secrets = JSON.parse(process.env.SECRETS || '{}');
|
||||||
|
const variables = JSON.parse(process.env.VARIABLES || '{}');
|
||||||
|
const RUN_ID = process.env.RUN_ID || process.env.GITHUB_RUN_ID || '';
|
||||||
|
|
||||||
|
const mapToken = (token) => {
|
||||||
|
if (token === 'BUILDID') return RUN_ID;
|
||||||
|
return (variables[token] != null ? variables[token] : secrets[token]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 1) Frontend: wszystkie .js
|
||||||
|
const feRoot = path.resolve('artifacts/frontend');
|
||||||
|
const feFiles = walk(feRoot, (f) => f.endsWith('.js'));
|
||||||
|
|
||||||
|
// 2) Backend: wybrane pliki jeśli istnieją
|
||||||
|
const beRoot = path.resolve('artifacts/webapi');
|
||||||
|
const beFiles = []
|
||||||
|
;['appsettings.json', 'client_secrets.json'].forEach((name) => {
|
||||||
|
const p = path.join(beRoot, name);
|
||||||
|
if (fs.existsSync(p)) beFiles.push(p);
|
||||||
|
});
|
||||||
|
|
||||||
|
const files = [...feFiles, ...beFiles];
|
||||||
|
|
||||||
|
if (files.length === 0) {
|
||||||
|
console.error('❌ No candidate files found to tokenize (frontend .js / backend json).');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`🔎 Tokenizing ${files.length} file(s)`);
|
||||||
|
const missing = new Set();
|
||||||
|
|
||||||
|
// drugi przebieg: wypisz brakujące tokeny, jeśli jakieś zostały w plikach
|
||||||
|
for (const file of files) {
|
||||||
|
// pierwsze podejście: podstaw wartości
|
||||||
|
replaceInFile(file, mapToken);
|
||||||
|
}
|
||||||
|
for (const file of files) {
|
||||||
|
const content = fs.readFileSync(file, 'utf8');
|
||||||
|
const reLeft = /#\{(.*?)\}#/g;
|
||||||
|
let m;
|
||||||
|
while ((m = reLeft.exec(content))) {
|
||||||
|
const token = (m[1] || '').replace(/-/g, '_').toUpperCase();
|
||||||
|
missing.add(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missing.size > 0) {
|
||||||
|
console.error(`❌ Missing values for tokens: ${Array.from(missing).join(', ')}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('✅ Tokenization complete.');
|
||||||
|
})();
|
||||||
@@ -2,6 +2,9 @@ name: BuildApp
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: build-${{ github.ref }}
|
group: build-${{ github.ref }}
|
||||||
|
|||||||
130
.gitea/workflows/buildContainers.yml
Normal file
130
.gitea/workflows/buildContainers.yml
Normal 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
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
name: _debug-mount
|
|
||||||
on: { workflow_dispatch: {} }
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Who/where
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
echo "uname -a:"; uname -a || true
|
|
||||||
echo "--- cgroup ---"; cat /proc/1/cgroup || true
|
|
||||||
- name: Show docker image info
|
|
||||||
run: |
|
|
||||||
cat /etc/os-release || true
|
|
||||||
- name: Mounts & write marker
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
echo "== grep mount =="
|
|
||||||
mount | grep -E 'runner-cache|ci-keys' || true
|
|
||||||
echo "== ls /runner-cache =="
|
|
||||||
ls -la /runner-cache || true
|
|
||||||
echo "MARKER $(date -Iseconds)" | tee /runner-cache/__ok.txt
|
|
||||||
echo "OK"
|
|
||||||
@@ -10,9 +10,7 @@ jobs:
|
|||||||
GITEA_BASE_URL: https://code.bim-it.pl
|
GITEA_BASE_URL: https://code.bim-it.pl
|
||||||
OWNER: mz
|
OWNER: mz
|
||||||
REPO: DiunaBI
|
REPO: DiunaBI
|
||||||
# Comma-separated artifact names that must exist
|
|
||||||
REQUIRED_ARTIFACTS: frontend,webapi
|
REQUIRED_ARTIFACTS: frontend,webapi
|
||||||
# How many recent successful runs to scan
|
|
||||||
SCAN_LIMIT: "100"
|
SCAN_LIMIT: "100"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -36,6 +34,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
node .gitea/scripts/getLatestRunWithArtifacts.js
|
node .gitea/scripts/getLatestRunWithArtifacts.js
|
||||||
echo "Resolved run_id: $(cat .gitea/.cache/run_id)"
|
echo "Resolved run_id: $(cat .gitea/.cache/run_id)"
|
||||||
|
echo "run_id=$(cat .gitea/.cache/run_id)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Download frontend artifact
|
- name: Download frontend artifact
|
||||||
env:
|
env:
|
||||||
@@ -64,51 +63,60 @@ jobs:
|
|||||||
ls -laR artifacts/webapi || true
|
ls -laR artifacts/webapi || true
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
# 3) Package artifacts as ZIPs for transfer
|
- name: Tokenize (replace #{...}# from secrets/vars)
|
||||||
|
env:
|
||||||
|
SECRETS: ${{ toJson(secrets) }}
|
||||||
|
VARIABLES: ${{ toJson(vars) }}
|
||||||
|
RUN_ID: ${{ steps.resolve.outputs.run_id }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
node .gitea/scripts/replaceTokens.js
|
||||||
|
|
||||||
- name: Package artifacts as ZIPs
|
- name: Package artifacts as ZIPs
|
||||||
run: |
|
run: |
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
(cd artifacts/frontend && zip -rq ../../build/DiunaBI-Morska-Frontend.zip .)
|
(cd artifacts/frontend && zip -rq ../../build/DiunaBI-Morska-Frontend.zip .)
|
||||||
(cd artifacts/webapi && zip -rq ../../build/DiunaBI-Morska-WebApi.zip .)
|
(cd artifacts/webapi && zip -rq ../../build/DiunaBI-Morska-WebApi.zip .)
|
||||||
ls -la build
|
ls -la build
|
||||||
- name: Debug SSH key
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.BIMIT_SSH_KEY }}
|
|
||||||
run: |
|
|
||||||
echo "== Początek klucza =="
|
|
||||||
echo "$SSH_PRIVATE_KEY" | head -n 5
|
|
||||||
echo "== Koniec klucza =="
|
|
||||||
echo "$SSH_PRIVATE_KEY" | tail -n 5
|
|
||||||
echo "== Liczba linii =="
|
|
||||||
echo "$SSH_PRIVATE_KEY" | wc -l
|
|
||||||
echo "== ssh-keygen sprawdzenie formatu =="
|
|
||||||
printf "%s" "$SSH_PRIVATE_KEY" > private_key
|
|
||||||
ssh-keygen -lf private_key || true
|
|
||||||
# 4) Upload ZIPs to remote server via SSH (using secret key)
|
|
||||||
- name: Upload artifacts to remote server
|
- name: Upload artifacts to remote server
|
||||||
env:
|
env:
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.BIMIT_SSH_KEY }}
|
SSH_PRIVATE_KEY: ${{ secrets.GITEARUNNER_SSH_KEY }}
|
||||||
SSH_USER: mz
|
SSH_USER: mz
|
||||||
SSH_HOST: bim-it.pl
|
SSH_HOST: bim-it.pl
|
||||||
REMOTE_DIR: deployment
|
REMOTE_DIR: deployment
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Prepare key
|
|
||||||
umask 077
|
umask 077
|
||||||
echo "$SSH_PRIVATE_KEY" > private_key
|
echo "$SSH_PRIVATE_KEY" > private_key
|
||||||
chmod 600 private_key
|
chmod 600 private_key
|
||||||
|
|
||||||
# Preload known_hosts (safer than StrictHostKeyChecking=no)
|
|
||||||
mkdir -p ~/.ssh
|
mkdir -p ~/.ssh
|
||||||
ssh-keyscan -H "$SSH_HOST" >> ~/.ssh/known_hosts
|
ssh-keyscan -H "$SSH_HOST" >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
# Ensure remote dir exists
|
|
||||||
ssh -i private_key "$SSH_USER@$SSH_HOST" "mkdir -p ~/$REMOTE_DIR"
|
ssh -i private_key "$SSH_USER@$SSH_HOST" "mkdir -p ~/$REMOTE_DIR"
|
||||||
|
|
||||||
# Upload files
|
|
||||||
scp -i private_key build/DiunaBI-Morska-Frontend.zip "$SSH_USER@$SSH_HOST:~/$REMOTE_DIR/"
|
scp -i private_key build/DiunaBI-Morska-Frontend.zip "$SSH_USER@$SSH_HOST:~/$REMOTE_DIR/"
|
||||||
scp -i private_key build/DiunaBI-Morska-WebApi.zip "$SSH_USER@$SSH_HOST:~/$REMOTE_DIR/"
|
scp -i private_key build/DiunaBI-Morska-WebApi.zip "$SSH_USER@$SSH_HOST:~/$REMOTE_DIR/"
|
||||||
|
|
||||||
# Cleanup
|
shred -u private_key
|
||||||
|
|
||||||
|
- name: Run release script on remote server
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.GITEARUNNER_SSH_KEY }}
|
||||||
|
SSH_USER: mz
|
||||||
|
SSH_HOST: bim-it.pl
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
umask 077
|
||||||
|
echo "$SSH_PRIVATE_KEY" > private_key
|
||||||
|
chmod 600 private_key
|
||||||
|
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
ssh-keyscan -H "$SSH_HOST" >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
ssh -i private_key "$SSH_USER@$SSH_HOST" "./deployment/DiunaBI-Morska.Release.sh"
|
||||||
|
|
||||||
shred -u private_key
|
shred -u private_key
|
||||||
113
.github/workflows/build.yml
vendored
113
.github/workflows/build.yml
vendored
@@ -1,113 +0,0 @@
|
|||||||
name: BuildApp
|
|
||||||
on:
|
|
||||||
#push:
|
|
||||||
# branches:
|
|
||||||
# - main
|
|
||||||
#pull_request:
|
|
||||||
# branches:
|
|
||||||
# - main
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-frontend:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Use Node.js 20
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
|
|
||||||
- name: Install Angular CLI
|
|
||||||
run: npm install -g @angular/cli
|
|
||||||
|
|
||||||
- name: Install PNPM
|
|
||||||
run: npm install -g pnpm
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
working-directory: src/Frontend
|
|
||||||
run: pnpm install
|
|
||||||
|
|
||||||
- name: Build Angular
|
|
||||||
working-directory: src/Frontend
|
|
||||||
run: ng build --configuration=production
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: frontend
|
|
||||||
path: src/Frontend/dist
|
|
||||||
|
|
||||||
build-backend:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup .NET 8
|
|
||||||
uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
|
||||||
dotnet-version: 8.0.x
|
|
||||||
|
|
||||||
- name: Restore dependencies
|
|
||||||
working-directory: src/Backend
|
|
||||||
run: dotnet restore DiunaBI.sln
|
|
||||||
|
|
||||||
- name: Build solution and prepare plugins
|
|
||||||
working-directory: src/Backend
|
|
||||||
run: |
|
|
||||||
dotnet build DiunaBI.sln --configuration Release
|
|
||||||
dotnet build DiunaBI.Plugins.Morska/DiunaBI.Plugins.Morska.csproj --configuration Release
|
|
||||||
# Przygotuj katalog dla testów
|
|
||||||
mkdir -p DiunaBI.Tests/bin/Release/net8.0/Plugins
|
|
||||||
cp DiunaBI.Plugins.Morska/bin/Release/net8.0/DiunaBI.Plugins.Morska.dll DiunaBI.Tests/bin/Release/net8.0/Plugins/
|
|
||||||
cp DiunaBI.Plugins.Morska/bin/Release/net8.0/DiunaBI.Core.dll DiunaBI.Tests/bin/Release/net8.0/Plugins/
|
|
||||||
echo "✅ Plugins copied to test directory:"
|
|
||||||
ls -la DiunaBI.Tests/bin/Release/net8.0/Plugins/
|
|
||||||
|
|
||||||
- name: Run Tests
|
|
||||||
working-directory: src/Backend
|
|
||||||
run: |
|
|
||||||
dotnet add DiunaBI.Tests/DiunaBI.Tests.csproj package coverlet.collector
|
|
||||||
dotnet test DiunaBI.Tests/DiunaBI.Tests.csproj \
|
|
||||||
--configuration Release \
|
|
||||||
--no-restore \
|
|
||||||
--logger "trx;LogFileName=test-results.trx" \
|
|
||||||
--collect:"XPlat Code Coverage" \
|
|
||||||
--filter "Category!=LocalOnly"
|
|
||||||
|
|
||||||
- name: Publish Test Results
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: success() || failure()
|
|
||||||
with:
|
|
||||||
name: test-results
|
|
||||||
path: |
|
|
||||||
src/Backend/DiunaBI.Tests/TestResults/*.trx
|
|
||||||
src/Backend/DiunaBI.Tests/TestResults/**/coverage.cobertura.xml
|
|
||||||
|
|
||||||
- name: Publish WebAPI
|
|
||||||
if: success()
|
|
||||||
working-directory: src/Backend
|
|
||||||
run: |
|
|
||||||
dotnet publish DiunaBI.WebAPI/DiunaBI.WebAPI.csproj \
|
|
||||||
--configuration Release \
|
|
||||||
--framework net8.0 \
|
|
||||||
--self-contained false \
|
|
||||||
--output ../../build/webapi
|
|
||||||
# Kopiuj pluginy do katalogu webapi
|
|
||||||
mkdir -p ../../build/webapi/Plugins
|
|
||||||
cp DiunaBI.Plugins.Morska/bin/Release/net8.0/DiunaBI.Plugins.Morska.dll ../../build/webapi/Plugins/
|
|
||||||
echo "✅ Plugins copied to webapi:"
|
|
||||||
ls -la ../../build/webapi/Plugins/
|
|
||||||
|
|
||||||
- name: Clean up sensitive files
|
|
||||||
working-directory: build/webapi
|
|
||||||
run: |
|
|
||||||
rm -f appsettings.Development.json
|
|
||||||
rm -f client_secrets.Development.json
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: webapi
|
|
||||||
path: build/webapi
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
module.exports = async ({ github, context, core, jobId, name }) => {
|
|
||||||
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
run_id: jobId,
|
|
||||||
});
|
|
||||||
if (artifacts.data.total_count === 0) {
|
|
||||||
core.setFailed("No artifacts found for jobID: " + jobId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const artifact = artifacts.data.artifacts.find(
|
|
||||||
(artifact) => artifact.name === name
|
|
||||||
);
|
|
||||||
if (!artifact) {
|
|
||||||
core.setFailed(`${name} not found in artifacts`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const response = await github.rest.actions.downloadArtifact({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
artifact_id: artifact.id,
|
|
||||||
archive_format: "zip"
|
|
||||||
});
|
|
||||||
require('fs').writeFileSync(`${name}.zip`, Buffer.from(response.data));
|
|
||||||
require('fs').mkdirSync(`./${jobId}/${name}`, { recursive: true });
|
|
||||||
require('child_process').execSync(`unzip -o ${name}.zip -d ./${jobId}/${name}`);
|
|
||||||
};
|
|
||||||
11
.github/workflows/buildScripts/getLastBuildId.js
vendored
11
.github/workflows/buildScripts/getLastBuildId.js
vendored
@@ -1,11 +0,0 @@
|
|||||||
module.exports = async ({ github, context }) => {
|
|
||||||
const { data: runs } = await github.rest.actions.listWorkflowRuns({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
workflow_id: "build.yml",
|
|
||||||
branch: "main",
|
|
||||||
status: "success",
|
|
||||||
per_page: 1,
|
|
||||||
});
|
|
||||||
return runs.workflow_runs[0].id;
|
|
||||||
};
|
|
||||||
38
.github/workflows/buildScripts/replaceTokens.js
vendored
38
.github/workflows/buildScripts/replaceTokens.js
vendored
@@ -1,38 +0,0 @@
|
|||||||
module.exports = async ({ github, context, core, jobId }) => {
|
|
||||||
|
|
||||||
const frontendPath = `./${jobId}/frontend/diunaBI/browser/`;
|
|
||||||
const files = (require('fs').readdirSync(frontendPath).filter(file => file.endsWith('.js')))
|
|
||||||
.map(file => `${frontendPath}${file}`);
|
|
||||||
if (files.length === 0) {
|
|
||||||
core.setFailed("Frontend JS files not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
files.push(`./${jobId}/webapi/appsettings.json`);
|
|
||||||
files.push(`./${jobId}/webapi/client_secrets.json`);
|
|
||||||
|
|
||||||
files.forEach(file => {
|
|
||||||
let data = require('fs').readFileSync(file, 'utf8');
|
|
||||||
const regex = /#{(.*?)}#/g;
|
|
||||||
let match;
|
|
||||||
while (match = regex.exec(data)) {
|
|
||||||
const original = match[0];
|
|
||||||
const token = match[1].replace(/-/g, '_').toUpperCase();
|
|
||||||
const value = getValue(token, jobId);
|
|
||||||
console.log(`Replacing ${original} with ${value} for ${token}`);
|
|
||||||
if (!value) {
|
|
||||||
core.setFailed(`Token ${token} not found`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
data = data.replace(new RegExp(original, 'g'), value);
|
|
||||||
}
|
|
||||||
require('fs').writeFileSync(file, data, 'utf8');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getValue(token, jobId) {
|
|
||||||
if (token == 'BUILDID') { return jobId; }
|
|
||||||
const secrets = JSON.parse(process.env.SECRETS);
|
|
||||||
const variables = JSON.parse(process.env.VARIABLES);
|
|
||||||
return variables[token] || secrets[token];
|
|
||||||
}
|
|
||||||
109
.github/workflows/release-morska.yml
vendored
109
.github/workflows/release-morska.yml
vendored
@@ -1,109 +0,0 @@
|
|||||||
name: Morska Release
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
job_id:
|
|
||||||
description: 'Job ID of the build to release'
|
|
||||||
required: false
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
environment: Morska
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Assign run ID if provided
|
|
||||||
if: ${{ github.event.inputs.job_id != '' }}
|
|
||||||
run: echo "job_id=${{ github.event.inputs.job_id }}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Get last build ID
|
|
||||||
id: get-build-id
|
|
||||||
if: ${{ github.event.inputs.job_id == '' }}
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const script = require('./.github/workflows/buildScripts/getLastBuildId.js');
|
|
||||||
const jobId = await script({github, context});
|
|
||||||
core.setOutput("job_id", jobId);
|
|
||||||
|
|
||||||
- name: Set job_id
|
|
||||||
if: ${{ github.event.inputs.job_id == '' }}
|
|
||||||
run: echo "job_id=${{ steps.get-build-id.outputs.job_id }}" >> $GITHUB_ENV
|
|
||||||
- name: Check job_id
|
|
||||||
run: |
|
|
||||||
if [ -z "${{ env.job_id }}" ]; then
|
|
||||||
echo "Error: job_id is empty"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Download frontend artifacts
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const script = require('./.github/workflows/buildScripts/downloadArtifacts.js');
|
|
||||||
await script({github, context, core, jobId: ${{env.job_id}}, name: 'frontend'});
|
|
||||||
|
|
||||||
- name: Download backend artifacts
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const script = require('./.github/workflows/buildScripts/downloadArtifacts.js');
|
|
||||||
await script({github, context, core, jobId: ${{env.job_id}}, name: 'webapi'});
|
|
||||||
|
|
||||||
- name: Tokenize
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
env:
|
|
||||||
SECRETS: ${{ toJson(secrets) }}
|
|
||||||
VARIABLES: ${{ toJson(vars) }}
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const script = require('./.github/workflows/buildScripts/replaceTokens.js');
|
|
||||||
await script({github, context, core, jobId: ${{env.job_id}} });
|
|
||||||
|
|
||||||
- name: Archive frontend artifacts
|
|
||||||
run: |
|
|
||||||
cd ${{env.job_id}}/frontend
|
|
||||||
zip -r ../DiunaBI-Morska-Frontend.zip .
|
|
||||||
|
|
||||||
- name: Archive backend artifacts
|
|
||||||
run: |
|
|
||||||
cd ${{env.job_id}}/webapi
|
|
||||||
zip -r ../DiunaBI-Morska-WebApi.zip .
|
|
||||||
|
|
||||||
- name: List artifacts
|
|
||||||
run: ls -la .
|
|
||||||
|
|
||||||
- name: Send frontend archive to remote server
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.PROD_SRV_PRIVATE_KEY }}
|
|
||||||
run: |
|
|
||||||
echo "${SSH_PRIVATE_KEY}" > private_key
|
|
||||||
chmod 600 private_key
|
|
||||||
scp -i private_key -o StrictHostKeyChecking=no ./${{env.job_id}}/DiunaBI-Morska-Frontend.zip mz@bim-it.pl:./deployment/
|
|
||||||
rm private_key
|
|
||||||
|
|
||||||
- name: Send frontend archive to remote server
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.PROD_SRV_PRIVATE_KEY }}
|
|
||||||
run: |
|
|
||||||
echo "${SSH_PRIVATE_KEY}" > private_key
|
|
||||||
chmod 600 private_key
|
|
||||||
scp -i private_key -o StrictHostKeyChecking=no ./${{env.job_id}}/DiunaBI-Morska-WebApi.zip mz@bim-it.pl:./deployment/
|
|
||||||
rm private_key
|
|
||||||
|
|
||||||
- name: Run SSH commands on remote server
|
|
||||||
env:
|
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.PROD_SRV_PRIVATE_KEY }}
|
|
||||||
run: |
|
|
||||||
echo "${SSH_PRIVATE_KEY}" > private_key
|
|
||||||
chmod 600 private_key
|
|
||||||
ssh -i private_key -o StrictHostKeyChecking=no mz@bim-it.pl << 'EOF'
|
|
||||||
./deployment/DiunaBI-Morska.Release.sh
|
|
||||||
EOF
|
|
||||||
rm private_key
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -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
|
||||||
|
|||||||
@@ -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.';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "8.0.0",
|
"version": "10.0.100",
|
||||||
"rollForward": "latestFeature"
|
"rollForward": "latestFeature"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
21
src/Backend/.claude/settings.local.json
Normal file
21
src/Backend/.claude/settings.local.json
Normal 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
47
src/Backend/.vscode/launch.json
vendored
Normal 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
114
src/Backend/.vscode/tasks.json
vendored
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
51
src/Backend/DiunaBI.API/Controllers/AuthController.cs
Normal file
51
src/Backend/DiunaBI.API/Controllers/AuthController.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
50
src/Backend/DiunaBI.API/Controllers/TestsController.cs
Normal file
50
src/Backend/DiunaBI.API/Controllers/TestsController.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using DiunaBI.Infrastructure.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace DiunaBI.API.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
public class TestsController : Controller
|
||||||
|
{
|
||||||
|
private readonly PluginManager _pluginManager;
|
||||||
|
private readonly ILogger<LayersController> _logger;
|
||||||
|
public TestsController(
|
||||||
|
PluginManager pluginManager,
|
||||||
|
ILogger<LayersController> logger)
|
||||||
|
{
|
||||||
|
_pluginManager = pluginManager;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("Ping")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public IActionResult Ping()
|
||||||
|
{
|
||||||
|
var tmp = new
|
||||||
|
{
|
||||||
|
a = 2,
|
||||||
|
b = "test"
|
||||||
|
};
|
||||||
|
var tmp2 = new
|
||||||
|
{
|
||||||
|
a = 2,
|
||||||
|
b = "test"
|
||||||
|
};
|
||||||
|
var user = User.Identity;
|
||||||
|
_logger.LogInformation("LogTest: OldValue {tmp}, NewValue {tmp2}, ChangedBy: {user}", tmp, tmp2, user?.Name);
|
||||||
|
return Ok("Pong");
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("Plugins")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public IActionResult GetPlugins()
|
||||||
|
{
|
||||||
|
var plugins = _pluginManager.GetPluginsCount();
|
||||||
|
return Ok(plugins);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
58
src/Backend/DiunaBI.API/Dockerfile
Normal file
58
src/Backend/DiunaBI.API/Dockerfile
Normal 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"]
|
||||||
@@ -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();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -48,6 +48,11 @@ builder.Services.AddCors(options =>
|
|||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
.AllowAnyHeader()
|
.AllowAnyHeader()
|
||||||
.AllowCredentials();
|
.AllowCredentials();
|
||||||
|
|
||||||
|
corsPolicyBuilder.WithOrigins("https://morska.diunabi.com")
|
||||||
|
.AllowAnyMethod()
|
||||||
|
.AllowAnyHeader()
|
||||||
|
.AllowCredentials();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -66,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>();
|
||||||
@@ -91,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 =>
|
||||||
@@ -155,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())
|
||||||
60
src/Backend/DiunaBI.API/Services/GoogleAuthService.cs
Normal file
60
src/Backend/DiunaBI.API/Services/GoogleAuthService.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
src/Backend/DiunaBI.API/Services/JwtTokenService.cs
Normal file
84
src/Backend/DiunaBI.API/Services/JwtTokenService.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
{
|
{
|
||||||
"PONG": "#{PING}#",
|
|
||||||
"app-version": "#{buildId}#",
|
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
@@ -34,36 +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": "#{instance-name}#",
|
|
||||||
"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}#",
|
|
||||||
"appLogsFile": "#{app-logs-file}#",
|
|
||||||
"apiLocalUrl": "#{api-local-url}#",
|
|
||||||
"Kestrel": {
|
"Kestrel": {
|
||||||
"Endpoints": {
|
"Endpoints": {
|
||||||
"Http": {
|
"Http": {
|
||||||
"Url": "http://#{api-local-url}#"
|
"Url": "http://0.0.0.0:7142"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
32
src/Backend/DiunaBI.API/appsettings.json
Normal file
32
src/Backend/DiunaBI.API/appsettings.json
Normal 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": "*"
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
37
src/Backend/DiunaBI.Application/DTOModels/LayerDto.cs
Normal file
37
src/Backend/DiunaBI.Application/DTOModels/LayerDto.cs
Normal 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;
|
||||||
|
}
|
||||||
50
src/Backend/DiunaBI.Application/DTOModels/RecordDto.cs
Normal file
50
src/Backend/DiunaBI.Application/DTOModels/RecordDto.cs
Normal 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; }
|
||||||
|
}
|
||||||
8
src/Backend/DiunaBI.Application/DTOModels/UserDto.cs
Normal file
8
src/Backend/DiunaBI.Application/DTOModels/UserDto.cs
Normal 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; }
|
||||||
|
}
|
||||||
19
src/Backend/DiunaBI.Application/DiunaBI.Application.csproj
Normal file
19
src/Backend/DiunaBI.Application/DiunaBI.Application.csproj
Normal 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>
|
||||||
@@ -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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10
src/Backend/DiunaBI.Domain/DiunaBI.Domain.csproj
Normal file
10
src/Backend/DiunaBI.Domain/DiunaBI.Domain.csproj
Normal 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>
|
||||||
@@ -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
|
||||||
@@ -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; }
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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; }
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
199
src/Backend/DiunaBI.Infrastructure/Data/AppDbContext.cs
Normal file
199
src/Backend/DiunaBI.Infrastructure/Data/AppDbContext.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
@@ -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>
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace DiunaBI.Core.Interfaces;
|
namespace DiunaBI.Infrastructure.Interfaces;
|
||||||
|
|
||||||
public interface IPlugin
|
public interface IPlugin
|
||||||
{
|
{
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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",
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
428
src/Backend/DiunaBI.Infrastructure/Migrations/20251119110709_UpdateModel.Designer.cs
generated
Normal file
428
src/Backend/DiunaBI.Infrastructure/Migrations/20251119110709_UpdateModel.Designer.cs
generated
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
430
src/Backend/DiunaBI.Infrastructure/Migrations/20251120193110_FixLayerDefaultValues.Designer.cs
generated
Normal file
430
src/Backend/DiunaBI.Infrastructure/Migrations/20251120193110_FixLayerDefaultValues.Designer.cs
generated
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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");
|
||||||
});
|
});
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user