Files
solution-erp/scripts/tien-kiem-cua.ps1
2026-08-07 17:37:03 +07:00

123 lines
4.5 KiB
PowerShell

# tien-kiem-cua.ps1 - GD-3 khoan (iv): tien kiem chi phi ~0 o DAU MOI CUA.
#
# Chi DOC. KHONG ghi. LUON exit 0 - day la lop INFORM, KHONG phai cong chan.
# Cong chan bang ma loi = W3b (khoan C3-04 + thang 4 trang thai), dang cho owner (P1).
# Ai sua file nay de tra ma != 0 la da doi lop, phai qua W3b truoc.
#
# Vi sao KHONG tin mtime cua he dieu hanh:
# hook 'wal:' cham tep o bien moi luot, va 'git checkout' viet lai mtime hang loat.
# mtime tra loi "tep bi cham luc nao", KHONG tra loi "cua dong luc nao".
# => chon cua bang DAU THOI GIAN GHI TRONG TEP (hub: phu-luc GD-3 khoan (iv)).
#
# Guard vang tep = VI TU MAY (khoan (vii)): Test-Path roi bo qua VA KHAI.
# CAM dung menh de "cai do chua lam" - menh de do sai ngay giay tep kia ha canh.
#
# A2 (mat ca tap): het nguon => in co THIEU-TAP RIENG, KHONG in "ok".
# So 0 khong duoc phep doc thanh "sach".
#
# Dung: powershell -NoProfile -ExecutionPolicy Bypass -File scripts/tien-kiem-cua.ps1
# -Cua adap-apply (ten cua dang mo - chi de in kem, khong doi hanh vi)
# -RepoRoot <path> (fault-inject tren cay tam)
param(
[string]$Cua = '',
[string]$RepoRoot = ''
)
$ErrorActionPreference = 'Stop'
function Get-RepoRoot {
param([string]$Explicit)
if ($Explicit -and $Explicit.Trim().Length -gt 0) { return $Explicit }
return (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
}
# Rut dau thoi gian GHI TRONG TEP cua WAL (cua dung: /pause, /snapshot, hook wal:).
# Khuon: "updated: YYYY-MM-DD | session: S<n> ..."
function Read-WalStamp {
param([string]$Root)
$p = Join-Path $Root '.claude/WAL.md'
if (-not (Test-Path -LiteralPath $p)) { return $null }
# chi doc 10 dong dau - re, va moc luon nam o dau tep
$head = Get-Content -LiteralPath $p -TotalCount 10 -ErrorAction Stop
foreach ($line in $head) {
$m = [regex]::Match($line, 'updated:\s*(\d{4}-\d{2}-\d{2})')
if ($m.Success) {
$s = [regex]::Match($line, 'session:\s*(S\d+)')
return [pscustomobject]@{
Nguon = 'WAL'
Ngay = $m.Groups[1].Value
Phien = $(if ($s.Success) { $s.Groups[1].Value } else { '?' })
}
}
}
return $null
}
# Rut dau thoi gian GHI TRONG TEP cua so dem phien (cua dung: /session-start, /session-end).
function Read-CounterStamp {
param([string]$Root)
$p = Join-Path $Root '.claude/governance/.session-counter.json'
if (-not (Test-Path -LiteralPath $p)) { return $null }
$raw = Get-Content -LiteralPath $p -Raw -ErrorAction Stop
$j = $raw | ConvertFrom-Json
$ngay = $j.last_ticked_at
if (-not $ngay) { return $null }
if ($ngay -notmatch '^\d{4}-\d{2}-\d{2}$') { return $null }
$phien = $j.last_ticked_session
if (-not $phien) { $phien = '?' }
return [pscustomobject]@{
Nguon = 'counter'
Ngay = $ngay
Phien = "$phien"
}
}
try {
$root = Get-RepoRoot -Explicit $RepoRoot
$nhan = ''
if ($Cua -and $Cua.Trim().Length -gt 0) { $nhan = " cua=$Cua" }
$nguon = @()
$hong = @()
foreach ($fn in @('Read-WalStamp', 'Read-CounterStamp')) {
$r = $null
try { $r = & $fn -Root $root } catch { $r = $null }
if ($null -ne $r) { $nguon += $r } else { $hong += $fn }
}
# A2 - mat CA TAP: khong con nguon nao doc duoc.
# In co RIENG, tuyet doi khong in "ok". So 0 mat quyen doc thanh "sach".
if ($nguon.Count -eq 0) {
Write-Output "TIEN-KIEM:$nhan THIEU-TAP - 0/2 nguon moc doc duoc (WAL.md + .session-counter.json) | KHONG ket luan duoc gi | (khong chan)"
exit 0
}
# chon cua dong GAN NHAT theo dau thoi gian TRONG TEP (khong phai mtime)
$moi = $nguon | Sort-Object -Property Ngay -Descending | Select-Object -First 1
$co = @()
if ($hong.Count -gt 0) {
$ten = ($hong -join ',') -replace 'Read-|Stamp', ''
$co += "NGUON-HONG:$ten"
}
# lech phien giua 2 nguon = dau hieu mot dau cua khong dong
if ($nguon.Count -ge 2) {
$pset = @($nguon | ForEach-Object { $_.Phien } | Sort-Object -Unique)
if ($pset.Count -gt 1) { $co += ("LECH-PHIEN:" + ($pset -join '/')) }
}
$trangthai = $(if ($co.Count -eq 0) { 'ok' } else { ($co -join ' ') })
Write-Output ("TIEN-KIEM:$nhan cua-dong-gan-nhat={0} moc-trong-tep={1} phien={2} | nguon {3}/2 | {4}" -f `
$moi.Nguon, $moi.Ngay, $moi.Phien, $nguon.Count, $trangthai)
exit 0
}
catch {
# fail-soft, y nguyen khuon nhip-no-probe: mot buoc MOI khong bao gio duoc lam hong nghi thuc dang chay tot
Write-Output "tien-kiem loi (khong chan)"
exit 0
}