MASTER PLAN — Pinbox24 Platform Compliance 2026

Ostatnia aktualizacja: 2026-07-07 Autor: p24-infra admin session

Jeden dokument do zarządzania trzema równoległymi ścieżkami i ich wzajemnymi zależnościami.


Cel nadrzędny

Platforma W3+W4 na bms-1 jest w pełni zgodna ze standardami gdy:

  1. Żaden credentials nie jest hardcoded — SOPS = jedyne źródło prawdy
  2. secrets-sync.yml = jedyny mechanizm dostarczania kluczy na serwery
  3. GitLab CI = jedyna ścieżka wdrożenia kodu — zero ręcznych deploy scripts
  4. Wszystkie eksponowane credentials zrotowane
  5. Docker-compose każdego stacku jest w git
  6. Monitoring: PM2 restart alerting + endpoint health w Prometheus
  7. monitoring.env.sops zawiera wyłącznie klucze observability stack (nie admin credentials)

Trzy ścieżki (Tracks)

TrackIssuePlanStatus
A — W3+W4 CI/CD compliance#3171docs/plans/w3-w4-cicd-full-deployment.md🟡 Zaplanowane, czeka na PR #3163
B — monitoring.env.sops reorg#3178docs/plans/monitoring-env-sops-reorganisation.md🟡 Zaplanowane, czeka na PR-D
C — artnet.pl elimination#3172GitHub issue + APPROVED plan review🟢 Worker dziś wieczór (20:00 UTC)

Zunifikowana kolejność PR (obie ścieżki, bez konfliktów)

[NATYCHMIAST — poza kolejką PR]
  v41-prod image → Wasabi backup (P0 risk, 2h)          ← NIE MA JESZCZE ISSUE
  wkhtml-v42-prod DNS fix (inna sesja diagnozuje)        ← NIE MA JESZCZE ISSUE

PR-A   Merge PR #3163 → main
       nginx round-robin fix + PM2 fork mode
       PREREQUISITE dla wszystkich track A fazach

PR-B   SOPS-only, parallel:
       Track A Faza 0: SOPS gaps (pinbox24-backends, w4, w3)
         + v42-notify-prod env audit → SOPS
       Track B Step 1: ATRAX_AUTH_STRING/SCOPE/WEBAPP_INSTANCE_ID → n8n-bms4.env.sops

       Track C (#3172): artnet elimination (wieczór) ← autonomiczny, nie blokuje PR-B

PR-C   Track A Faza 1: mailgun + s3-v2 GitLab CI
       (bez zmian w secrets-sync.yml)

PR-D   COMBINED secrets-sync.yml (JEDEN PR, oba tracks):
       Track A: sync-bms-1 extension (bms1-all target)
       Track B: +sync-worker-queue, +sync-cloudflare, +sync-traccar, +sync-whatsup
                modify sync-vps-h1 (remove "Extract worker keys" step)
                modify sync-bms-4 (remove copy to /home/claude-runner/.env)
       Shared: target enum + exclusion list updates (line 15, line 26)

PR-E   Track B: nowe SOPS pliki (worker-queue, cloudflare, traccar)
       Triggery sync jobs z PR-D automatycznie

PR-F   Track A Faza 2: secrets-sync bms1-all verify
       Wszystkie W3/W4 env files na bms-1 z SOPS

PR-G   Track B: shrink monitoring.env.sops (89 → ~42 keys, 7 sub-steps)
       PREREQUISITE: PR-E merged i workers na bms-4/vps-h1 działają

PR-H   Track A Fazy 3A+3B: deploy scripts cleanup W4+W3
       PREREQUISITE: #3172 zakończone (te same scripts)
       + docker-compose W4+W3 → git (Gap 3)
       + git-deploy-v42-prod decyzja (Gap 4)

PR-I   Track A Fazy 3C+3D: Image CI/CD W4+W3 (GitLab)
       + redis-v42 depends_on (Gap 5)
       + GOOGLE_APPLICATION_CREDENTIALS management (Gap 7)
       + persistent patches strategy (Gap 8)
       + wkhtml health check (jeśli Gap 1 rozwiązany)
       + nocne-deploy policy dla WebSocket (Gap 9)

PR-J   Track A Faza 4: Credential rotations
       (po audycie dead credentials: Jabber/Twilio/OneSignal — Gap 11)

PR-K   Track A Faza 5: PM2 monitoring + Prometheus health checks

PR-L   Track B Faza 2: Service accounts
       (human action: Supabase monitoring_reader, MongoDB p24-monitoring)
       Background: Wasabi IAM scope verification

Reguły nienaruszalne:

  • PR-D = JEDEN PR dla WSZYSTKICH zmian secrets-sync.yml (zero merge konfliktów)
  • PR-E SOPS files dopiero po PR-D (sync jobs muszą istnieć)
  • #3172 zakończone przed PR-H (te same deploy scripts)
  • PR-G dopiero po PR-E (klucze muszą być w nowych SOPS przed usunięciem z monitoring)

Gap Analysis — Luki NIE pokryte żadnym aktywnym issueм

Luki P0 (krytyczne — blokują lub zagrożenie danych)

LukaProblemAkcjaIssue
v41-prod untagged imageAngular W4 frontend nieodtwarzalny po restarcie bms-1docker save v41-prod | gzip → Wasabi, TERAZ❌ brak issue
wkhtml DNS EAI_AGAINPDF generation broken w v42-prodDiagnoza (inna sesja) + fix przed PR-I❌ brak issue
docker-compose nie w gitKonfiguracja kontenerów tylko w RAM bms-1PR-H: docker inspectdocs/bms-1/pokryte PR-H

Luki P1 (ważne — adresować w PR-H/PR-I)

LukaProblemAkcjaIssue
git-deploy-v42-prodStary deploy trigger — bezpieczny?Audyt + decyzja D5 przed PR-H❌ brak issue
redis-v42 startup orderingbms-1 reboot → RabbitMQ crashPR-I: depends_on: service_healthypokryte PR-I
pdf-gen-v42-prodNiezidentyfikowany kontenerdocker inspect → określ rolę❌ brak issue
GOOGLE_APPLICATION_CREDENTIALSJSON credentials poza SOPSPR-I: volume managedpokryte PR-I
Persistent patchesVolume mounts jako code patchesPR-I: bake in image lub config volumepokryte PR-I
WebSocket restartSocket.IO dropp przy deployNocne deploye + runbookpokryte PR-I
v42-notify-prod SOPS gapEnv vars niezweryfikowaneFaza 0 Track A (PR-B)pokryte PR-B

Luki P2 (niskie ryzyko)

LukaProblemAkcja
Dead credentialsJabber/XMPP, Twilio, OneSignal aktywne?Audyt przed PR-J
W3 frontendStatus lokalnego image nieznanyAudyt bms-1 przed PR-I

Rozbieżności między planami (wykryte 2026-07-07)

#RozbieżnośćŹródło AŹródło BRozwiązanie
R1secrets-sync.yml changes — szczegóły rozdzielonew3-w4-cicd mówi “PR-D combined” bez detalimonitoring-reorg ma pełne detaleReferencja: PR-D details = monitoring-env-sops-reorganisation.md §secrets-sync.yml Changes
R2”PR-F: verify bms1-all” w monitoring reorgTraktowany jako standalone stepW w3-w4-cicd to Faza 2 (#3171)Ujednolicono: PR-F = Track A Faza 2, nie Track B krok
R3Redis startup dependency nie w monitoring reorgJest w w3-w4-cicd (Gap 5)Brak wzmianki w monitoring planBez konfliktu — redis dotyczy tylko Track A; monitoring plan nie musi go uwzględniać
R4#3172 scope vs #3171 Phase 3A/3Bmonitoring plan nie wspomina #3172 prerequisitew3-w4-cicd ma ordering noteUjednolicono: PR-H ma prerequisite #3172 done (ten dokument = master)
R5wkhtml/pdf-gen gapsW w3-w4-cicd (Gap 1, 6)Brak w monitoring reorgBez konfliktu — infrastructure gaps tylko Track A
R6QUEUE_API_KEY/URL w monitoring.env.sopsmonitoring reorg KEEP w monitoring (monitoring-watchdog read)w3-w4-cicd mówi te klucze → worker-queueWyjaśnienie: W monitoring = read-only monitoring-watchdog; W worker-queue = worker process. Oba są uzasadnione — DWA różne klucze o różnych scopach, nie duplikaty

Otwarte decyzje (wymagane przed wykonaniem)

D#PytaniePrzedKto
D5git-deploy-v42-prod — wyłączyć czy zachować?PR-HWorker po audycie
D6WebSocket restart — nocne deploye (Opcja A) czy nginx upstream (Opcja B)?PR-IWłaściciel produktu
D7pdf-gen-v42-prod — co to jest?PR-IWorker po docker inspect
D8Jabber/Twilio/OneSignal — aktywne?PR-JSprawdzenie logów
D9W3 frontend — lokalny untagged image jak v41-prod?PR-IAudyt bms-1

Issues — co zamknąć, co utrzymać

UTRZYMAJ OTWARTE

IssueDlaczego
#3171Orchestrator 5-fazowy, nie zaimplementowany — główny tracker Track A
#3172Uruchamiany dziś wieczór — nie zamykaj przed zakończeniem workera
#3178Track B nie zaimplementowany — główny tracker Track B

UTWÓRZ NOWE (brakujące issues)

OpisPriorytetTrack
v41-prod image backup → Wasabi (P0 risk, 2h pracy)P0infra / sys-admin
wkhtml-v42-prod DNS fix — root cause + playbookP0Czeka na diagnozę tamtej sesji
pdf-gen-v42-prod audit — co to jest, czy potrzebnyP1dev

POTENCJALNIE ZAMKNIJ (po weryfikacji)

IssueWarunek zamknięcia
#2855 (audyt bms-1 — jeśli otwarty)Plan #3171 absorbuje wszystkie findings — zamknij z referencją
#2877 (referenced in #3171)Zamknąć po Fazie 2 (#3171 track A) — jak określono w #3171
Wszelkie stare issues o hardcoded credentialsZamknąć po PR-J (rotacje)

Playbooki do napisania (po wykonaniu)

  • docs/playbooks/pinbox24-wkhtml-troubleshooting.md — po diagnozie DNS
  • docs/playbooks/bms-1-full-deployment-runbook.md — pełny deploy runbook W3+W4
  • docs/playbooks/pinbox24-cicd-rollback.md — rollback per faza
  • docs/playbooks/v41-prod-recovery.md — odtworzenie W4 frontend z Wasabi backup

Faza Close — Zamknięcie issues i porządkowanie backlogu

Uruchom tę fazę po zakończeniu WSZYSTKICH PR-A do PR-L. Jeden worker może wykonać masowe zamknięcie używając command block na końcu tej sekcji.

Kryterium zakończenia planu

Plan jest KOMPLETNY gdy:

  • Cele 1–7 z §“Cel nadrzędny” weryfikowalnie spełnione (patrz checklist poniżej)
  • Tracking issues #3171, #3172, #3178 zamknięte
  • Wszystkie issues z closure map poniżej zamknięte z referencją

Issue closure map — co zamknąć po każdym PR

IssueTytuł (skrót)Zamknij poPowód
#3161nginx round-robin s3-v42PR-AZamknięte przez PR #3163 automatycznie
#2048mailgun inbound email + rotationPR-Cmailgun GitLab CI pipeline aktywny
#2052mailgun hardcoded prod credsPR-Cmailgun deploy scripts → SOPS
#2697mailgun docker-deploy hardcodedPR-Cmailgun deploy scripts → SOPS
#2826v32-prod not on prod-v-3-netPR-FCI deploy naprawia sieć automatycznie
#28772855-decisions (3 human decisions)PR-FWszystkie decyzje zaimplementowane w Fazie 2
#2921kontenery bez restart policyPR-Hdocker-compose z restart policies w git
#2394artnet legacy containers#3172 doneartnet containers usunięte przez Track C
#3191GitLab hardcoded artnet.pl URIs#3172 doneHardcoded URI usunięte ze źródeł
#3186UPDATE V42_v3MongoUrl artnet→bms-2#3172 doneMongoDB URL zaktualizowane przez worker
#2569s3v2-prod hardcoded Wasabi credsPR-Hs3-v2 credentials w SOPS, deploy scripts clean
#2763docker-deploy-prod.sh hardcoded credsPR-HW4 deploy scripts → SOPS
#3063W3 docker-deploy hardcoded credsPR-HW3 deploy scripts → SOPS
#3066s3-v32-prod logs MongoDB URI w PM2PR-HMongoDB URI w SOPS, nie w PM2 stdout
#2855bms-1 deploy scripts bypass SOPSPR-HRoot audit absorbed into #3171 — wszystkie scripts clean
#2685Deploy GitLab MR !778 (JWT fix)PR-IDelivered via GitLab CI pipeline
#2686Deploy GitLab MR !779 (AMQP fix)PR-IDelivered via GitLab CI pipeline
#2690GitLab runner broken — bms-1PR-IRunner re-registered w Fazie 3C
#2055Plaintext secrets in monitoring.env.sopsPR-GGod-file eliminated — admin keys usunięte
#2257SUPABASE_DB_PASSWORD stale monitoringPR-G + PR-JKey moved + rotated
#2673monitoring.env.sops exposure incidentPR-GGod-file eliminated — ryzyko zlikwidowane
#2734Rotate stale SUPABASE_DB_PASSWORDPR-JZrotowane w Fazie 4
#2046Revoke stale DO Spaces keyPR-JRevoked w Fazie 4 rotations
#2047Revoke stale AWS IAM keyPR-JRevoked w Fazie 4 rotations
#2567PM2 restarts metric → mezmo-exporterPR-Kpinbox24_pm2_restarts_total live w Prometheus
#3026Pinbox24 no logs bms-1PR-KPM2 + Loki/Mezmo logging aktywne
#2547SSL cert + endpoint health monitoringPR-Kblackbox scraping bms-1 endpoints
#2731Split pinbox24-backends.env.sopsPR-LSplit complete — W3/W4 credential isolation
#3178monitoring.env.sops reorganisationPR-LTrack B kompletny
#3172artnet.pl eliminationWorker callbackTrack C kompletny — zweryfikuj callback comment
#3171W3+W4 pełna zgodnośćWSZYSTKIE PROstatni — zamknij po zamknięciu wszystkich powyżej

Issues do triażu — powiązane ale poza zakresem planu

Issues które mogą stać się nieaktualne jako efekt uboczny naszego planu. Sprawdź i zamknij/zaktualizuj:

IssueDlaczego może być nieaktualnyAkcja
#2542 v42-prod memory leakPM2 fork mode (PR-A) może eliminować crash loopWeryfikuj po 72h uptime po PR-A; zamknij jeśli brak nowych restartów
#2977 secrets-sync failingMoże być resolved przez PR-A + SSH key fixesSprawdź gh run list --workflow=secrets-sync.yml; zamknij jeśli green
#2827 SUPABASE_ACCESS_TOKEN missingPR #3079 może to adresowaćSprawdź stan PR #3079 + czy key jest w monitoring.env.sops po PR-G
#3096 GUS WSDL crash loopNiezwiązany z planem, ale blokuje v42 stabilnośćSprawdź czy nadal aktywny po PR-I; jeśli nie — oddzielny fix issue
#3122 EndpointDown api.w3.pinbox24.comAlert firing — rozwiązany przez CI/CD stabilizacjęZamknij jeśli alert nie firing po PR-F
#3137 Pinbox24ErrorSpikeError spike — może być resolved przez PM2 fork modeZamknij jeśli error rate normal po PR-A + PR-K
#3153 EndpointSlow api.w3 >2sLatency alert — może być resolved przez CI/CDZamknij jeśli endpoint P50 < 2s po PR-F
#3193 wkhtml Network Isolation incidentGap 1 w naszym planie — diagnoza w osobnej sesjiMerge fix do PR-I gdy diagnoza gotowa

Polecenie do przeszukania stale issues po tagu:

$REPO = "radieu/p24-infra"
gh issue list --repo $REPO --state open --label "bug" -L 200 --json number,title,updatedAt |
  ConvertFrom-Json |
  Where-Object { [datetime]$_.updatedAt -lt (Get-Date).AddDays(-30) } |
  Select-Object number,title | Sort-Object number

Dokumentacja — aktualizacje post-plan

DokumentCo zaktualizowaćPo którym PR
CLAUDE.md §Secrets Management SOPS file mapDodaj worker-queue, cloudflare, traccar; zaktualizuj monitoring (~42 keys)PR-G
docs/playbooks/secret-manager.mdDeployment paths dla nowych SOPS plików + nowe sync jobsPR-E
docs/priorities.mdUsuń W3/W4 CI/CD compliance + monitoring god-file z P0/P1; dodaj new risks jeśliPo PR-L
CHANGELOG.md [Unreleased]/update-changelog --pr N po każdym mergeKażdy PR
Ten plik (MASTER-pinbox24-platform-2026.md)Oznacz każdy PR jako done [x] w PR sequenceKażdy PR
docs/infrastructure-overview.mdZaktualizuj SOPS architecture diagram jeśli zmienionyPR-G

Compliance verification checklist

Po zakończeniu wszystkich PRs, weryfikuj każdy cel z §“Cel nadrzędny”:

$REPO = "radieu/p24-infra"
 
# Cel 1 — zero hardcoded credentials w deploy scripts
Write-Host "=== Cel 1: hardcoded creds ==="
$hits = Get-ChildItem -Recurse -Include "*.sh","*.js","*.yml" infra-src/pinbox24/ |
  Select-String -Pattern "(WASABI|MONGODB_URL|_PASSWORD|_SECRET)=['\`"][^$\{]" -List
Write-Host "Hits: $($hits.Count) (expected: 0)"
 
# Cel 2 — wszystkie secrets-sync.yml sync jobs istnieją
Write-Host "=== Cel 2: secrets-sync jobs ==="
$jobs = (Select-String "^\s+sync-" .github/workflows/secrets-sync.yml).Count
Write-Host "Sync jobs: $jobs (expected: 10+)"
 
# Cel 3 — GitLab CI działało w ostatnich 7 dniach
Write-Host "=== Cel 3: GitLab CI builds — sprawdź ręcznie w GitLab ==="
Write-Host "gitlab.com/pinbox24/p24-back-ts → Pipelines (W4)"
Write-Host "gitlab.com/pinbox24/p24-v-3.2 → Pipelines (W3)"
 
# Cel 5 — docker-compose w git
Write-Host "=== Cel 5: docker-compose files in git ==="
$composeFiles = Get-ChildItem -Recurse -Filter "docker-compose*.yml" docs/bms-1/ 2>$null
Write-Host "Compose files: $($composeFiles.Count) (expected: 2+)"
 
# Cel 7 — monitoring.env.sops shrunk
Write-Host "=== Cel 7: monitoring.env.sops key count ==="
$env:SOPS_AGE_KEY_FILE = "C:\Users\konar\.age\p24-infra-keys.txt"
$keyCount = (sops --decrypt --input-type dotenv --output-type dotenv secrets\monitoring.env.sops |
  Where-Object { $_ -match "^[A-Z]" }).Count
Write-Host "Keys: $keyCount (expected: ~42, was: 89)"

Cele 4 i 6 wymagają weryfikacji przez sys-admin na bms-1 + Grafana dashboard.


Worker command block — masowe zamykanie issues

Uruchom po pełnej weryfikacji checklista powyżej. Grupowanie po milestone PR:

$REPO = "radieu/p24-infra"
 
# === PO PR-C (mailgun GitLab CI) ===
@(2048, 2052, 2697) | ForEach-Object {
  gh issue close $_ --repo $REPO -c "Resolved by #3171 Faza 1 — mailgun GitLab CI pipeline active, deploy scripts use SOPS"
}
 
# === PO PR-F (bms1-all env delivery) ===
gh issue close 2826 --repo $REPO -c "Resolved by #3171 Faza 2 — v32-prod on prod-v-3-net via CI deploy"
gh issue close 2877 --repo $REPO -c "Resolved by #3171 Faza 2 — all 3 CI/CD decisions implemented"
 
# === PO #3172 (artnet elimination) ===
@(2394, 3186, 3191) | ForEach-Object {
  gh issue close $_ --repo $REPO -c "Resolved by #3172 — artnet.pl elimination complete"
}
gh issue close 3172 --repo $REPO -c "Track C complete — artnet.pl eliminated from W3+W4"
 
# === PO PR-H (deploy scripts clean) ===
@(2569, 2763, 2855, 2921, 3063, 3066) | ForEach-Object {
  gh issue close $_ --repo $REPO -c "Resolved by #3171 Faza 3A/3B — deploy scripts use SOPS, docker-compose in git"
}
 
# === PO PR-I (GitLab CI builds) ===
@(2685, 2686, 2690) | ForEach-Object {
  gh issue close $_ --repo $REPO -c "Resolved by #3171 Faza 3C/3D — GitLab CI pipeline active on bms-1"
}
 
# === PO PR-G (monitoring shrink) ===
@(2055, 2257, 2673) | ForEach-Object {
  gh issue close $_ --repo $REPO -c "Resolved by #3178 PR-G — monitoring.env.sops god-file eliminated (~42 keys)"
}
 
# === PO PR-J (rotations) ===
@(2046, 2047, 2734) | ForEach-Object {
  gh issue close $_ --repo $REPO -c "Resolved by #3171 Faza 4 — credentials rotated"
}
 
# === PO PR-K (PM2 monitoring) ===
@(2547, 2567, 3026) | ForEach-Object {
  gh issue close $_ --repo $REPO -c "Resolved by #3171 Faza 5 — PM2 monitoring + endpoint health in Prometheus"
}
 
# === PO PR-L (Track B Faza 2) ===
gh issue close 2731 --repo $REPO -c "Resolved by #3178 PR-L — pinbox24-backends.env.sops split complete"
gh issue close 3178 --repo $REPO -c "Track B complete — monitoring.env.sops reorganisation done (89 → ~42 keys)"
 
# === OSTATNI — orchestrator ===
gh issue close 3171 --repo $REPO -c "MASTER PLAN COMPLETE — W3+W4 pełna zgodność osiągnięta. Cele 1-7 zweryfikowane."

Uwaga: przed uruchomieniem command block, zweryfikuj completion checklist powyżej. Zamykanie issues bez weryfikacji ukrywa regresje.