Donut-hover met percentages en werkende update-notificatie

- Donut: naadloze segmenten (donkere spleten weg), hover-tooltip per
  categorie met naam, bedrag en aandeel, middenwaarde schaalt mee
- Update-check via de eigen backend (/api/update-check) i.p.v. direct
  naar de Gitea API, die geen CORS-headers stuurt
- Semver-vergelijking, herhaalde check en release-notes in de melding
- release.ps1 maakt de Gitea-release aan (stap 4)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jordy Hoogeveen
2026-09-04 09:19:23 +02:00
co-authored by Claude Opus 5
parent e45d5b73fb
commit 3c67381de9
24 changed files with 506 additions and 241 deletions
+78 -4
View File
@@ -14,6 +14,8 @@
# - docker buildx builder actief: docker buildx create --use
# - Git geïnstalleerd en working directory is de repo root
# - root package.json bevat een schoon versienummer ZONDER -dev suffix
# - $env:GITEA_TOKEN gezet (token met release-rechten) — nodig voor stap 4,
# de Gitea-release waar de update-melding in de app op afgaat
param(
[switch]$NoBuild,
@@ -87,6 +89,27 @@ function Write-Step {
Write-Host "── $Label" -ForegroundColor Cyan
}
# Haalt de sectie van deze versie uit Changelog.md als release-notes.
function Get-ChangelogSection {
param([string]$Version)
$path = Join-Path $PSScriptRoot "Changelog.md"
if (-not (Test-Path $path)) { return "" }
$lines = Get-Content $path
$start = -1
$needle = "^##\s*\[" + [regex]::Escape($Version) + "\]"
for ($i = 0; $i -lt $lines.Count; $i++) {
if ($lines[$i] -match $needle) { $start = $i + 1; break }
}
if ($start -lt 0) { return "" }
$out = @()
for ($i = $start; $i -lt $lines.Count; $i++) {
if ($lines[$i] -match "^##\s*\[") { break }
if ($lines[$i] -match "^---\s*$") { continue }
$out += $lines[$i]
}
return (($out -join "`n").Trim())
}
# ── Samenvatting ───────────────────────────────────────────────────────────
Write-Host ""
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan
@@ -100,7 +123,7 @@ if ($Force) { Write-Host " Mode : FORCE (conflictcontrole overgeslagen)" -
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan
# ── Stap 1: Conflictcontrole ──────────────────────────────────────────────
Write-Step "[1/3] Conflictcontrole"
Write-Step "[1/4] Conflictcontrole"
if (-not $DryRun -and -not $Force) {
$localTag = git tag --list $gitTag
@@ -144,7 +167,7 @@ if (-not $DryRun -and -not $Force) {
# ── Stap 2: Bouwen en pushen ──────────────────────────────────────────────
if (-not $NoBuild) {
Write-Step "[2/3] Multi-platform bouwen en pushen"
Write-Step "[2/4] Multi-platform bouwen en pushen"
Write-Host "Backend bouwen en pushen..." -ForegroundColor White
Invoke-Cmd @(
@@ -169,11 +192,11 @@ if (-not $NoBuild) {
(Join-Path $PSScriptRoot "frontend")
)
} else {
Write-Step "[2/3] Bouwen overgeslagen (-NoBuild)"
Write-Step "[2/4] Bouwen overgeslagen (-NoBuild)"
}
# ── Stap 3: Git-tag aanmaken en pushen ────────────────────────────────────
Write-Step "[3/3] Git-tag aanmaken en pushen"
Write-Step "[3/4] Git-tag aanmaken en pushen"
if ($Force) {
Write-Host "Bestaande lokale tag verwijderen (indien aanwezig)..." -ForegroundColor Yellow
@@ -192,6 +215,57 @@ Invoke-Cmd @("git", "tag", "-a", $gitTag, "-m", "Release $gitTag")
Write-Host "Git-tag pushen naar origin" -ForegroundColor White
Invoke-Cmd @("git", "push", "origin", "refs/tags/$gitTag")
# ── Stap 4: Gitea-release aanmaken ────────────────────────────────────────
Write-Step "[4/4] Gitea-release aanmaken"
# De update-melding in de app leest /releases/latest. Een kale Git-tag komt
# daar niet in terug, dus er moet een echte release van gemaakt worden.
$repoUrl = ($rootPkg.repository -replace "/+$", "")
$releaseApi = $null
if ($repoUrl -match "^(https?://[^/]+)/([^/]+)/([^/]+)$") {
$releaseApi = "$($Matches[1])/api/v1/repos/$($Matches[2])/$($Matches[3])/releases"
}
$giteaToken = $env:GITEA_TOKEN
if (-not $releaseApi) {
Write-Host "Kon 'repository' niet parsen uit package.json — release overgeslagen." -ForegroundColor Yellow
} elseif (-not $giteaToken) {
Write-Host "Geen GITEA_TOKEN in de omgeving — release overgeslagen." -ForegroundColor Yellow
Write-Host " Zonder release ziet de app geen update-melding voor $appVersion." -ForegroundColor DarkGray
Write-Host ' Token met release-rechten zetten: $env:GITEA_TOKEN = "<token>"' -ForegroundColor DarkGray
} else {
$notes = Get-ChangelogSection $appVersion
if (-not $notes) { $notes = "Release $appVersion" }
$payload = @{
tag_name = $gitTag
name = "v$appVersion"
body = $notes
draft = $false
prerelease = $false
} | ConvertTo-Json -Depth 3
if ($DryRun) {
Write-Host "[DRY-RUN] POST $releaseApi" -ForegroundColor Yellow
Write-Host $payload -ForegroundColor DarkGray
} else {
Write-Host "Release publiceren: $releaseApi" -ForegroundColor White
try {
$rel = Invoke-RestMethod -Method Post -Uri $releaseApi -Body $payload `
-ContentType "application/json" `
-Headers @{ Authorization = "token $giteaToken" }
Write-Host "Release aangemaakt: $($rel.html_url)" -ForegroundColor Green
} catch {
$code = $_.Exception.Response.StatusCode.value__
if ($code -eq 409) {
Write-Host "Release voor $gitTag bestaat al — overgeslagen." -ForegroundColor Yellow
} else {
Write-Host "Release aanmaken mislukt ($code): $($_.Exception.Message)" -ForegroundColor Red
Write-Host "Tag en images staan al klaar; maak de release eventueel handmatig aan." -ForegroundColor DarkGray
}
}
}
}
# ── Klaar ─────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "════════════════════════════════════════" -ForegroundColor Cyan