{
  "name": "Bug & Pitfall Wiki",
  "count": 16,
  "generated": "2026-05-25T16:26:00.176Z",
  "bugs": [
    {
      "title": "AI agent smazal zdrojové soubory projektu (jen build zůstal)",
      "description": "AI agent s přístupem na produkční filesystem smazal src/, prisma/, package.json i .env; zůstaly jen build artefakty. Bez git remote byla ztráta nevratná z VCS.",
      "category": "ai-agents",
      "tags": [
        "ai-agent",
        "filesystem",
        "data-loss",
        "git",
        "backup",
        "env"
      ],
      "severity": "critical",
      "status": "mitigated",
      "stack": [
        "node",
        "nextjs",
        "prisma"
      ],
      "prevention": "AI agent nikdy nesmí sahat na produkční filesystem projektu — jen přes API. Projekt měj na git remote (deploy = git pull, ne rsync --delete) a .env drž mimo strom projektu.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/ai-agents/ai-agent-deleted-source-files/"
    },
    {
      "title": "Reset hesla nefunguje — špatný klient a fake SMTP",
      "description": "Tři bugy najednou — kód volal neexistující serverový klient, redirect mířil na 404 a spoléhal na vestavěné SMTP nakonfigurované jako fake.",
      "category": "auth",
      "tags": [
        "auth",
        "password-reset",
        "email",
        "smtp"
      ],
      "severity": "high",
      "status": "resolved",
      "stack": [
        "auth",
        "email"
      ],
      "prevention": "Reset-password flow vždy otestuj E2E s reálným e-mailem. Neimplikuj, že vestavěné SMTP providera funguje.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/auth/reset-password-wrong-client-and-fake-smtp/"
    },
    {
      "title": "NOT IN s tisíci hodnotami přesáhne limit délky URL",
      "description": "REST/PostgREST filtr NOT IN(...) posílá všechny hodnoty v query stringu → po překročení ~8 KB URL gateway tiše odmítne dotaz a vrátí prázdno bez chyby.",
      "category": "database",
      "tags": [
        "postgrest",
        "sql",
        "url",
        "scaling",
        "silent-failure"
      ],
      "severity": "critical",
      "status": "resolved",
      "stack": [
        "postgrest",
        "sql"
      ],
      "prevention": "Nikdy IN/NOT IN s dynamickým seznamem >50 hodnot v REST query. Použij JOIN s filtrem nebo RPC s array parametrem.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/database/postgrest-url-length-not-in-limit/"
    },
    {
      "title": "Hard delete entity zničí navázanou historii objednávek",
      "description": "Fyzické smazání + nullování FK kaskádově zlikviduje auditní stopu v order_items — historie objednávek zmizí.",
      "category": "database",
      "tags": [
        "sql",
        "data-modeling",
        "soft-delete",
        "audit"
      ],
      "severity": "high",
      "status": "resolved",
      "stack": [
        "sql",
        "data-modeling"
      ],
      "prevention": "Entity navázané na objednávky/faktury vždy soft-deletuj (deleted_at). Hard-delete jen u ephemeral dat (cart, session).",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/database/soft-delete-preserve-history/"
    },
    {
      "title": "INSERT triggery zdvojnásobí počítadla při restore",
      "description": "Při bulk obnově ze zálohy se spustí INSERT triggery a přičtou k už správným hodnotám → denormalizovaná počítadla jsou dvojnásobná.",
      "category": "database",
      "tags": [
        "postgres",
        "triggers",
        "restore",
        "denormalization"
      ],
      "severity": "medium",
      "status": "resolved",
      "stack": [
        "postgres",
        "triggers"
      ],
      "prevention": "Bulk import/restore vždy s vypnutými triggery (session_replication_role = replica), pak RESET.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/database/trigger-double-counts-on-restore/"
    },
    {
      "title": "Build projde lokálně, ale lint shodí produkční build (502)",
      "description": "Dev server přeskočí lint/typecheck; produkční build na nich selže → nasazení skončí 502.",
      "category": "deploy",
      "tags": [
        "deploy",
        "build",
        "lint",
        "ci"
      ],
      "severity": "high",
      "status": "resolved",
      "stack": [
        "nextjs",
        "deploy",
        "eslint"
      ],
      "prevention": "Před deploy spusť plný production build lokálně (ne dev) + smoke test klíčových stránek + kontrola stavu procesu.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/deploy/build-passes-locally-lint-fails-production/"
    },
    {
      "title": "git clean smaže uživatelské uploady (untracked soubory v repu)",
      "description": "Uživatelské nahrané soubory ležely v git working tree a nebyly gitignored — git clean -fdx je smazal. Zachránila jen additivní offsite záloha.",
      "category": "deploy",
      "tags": [
        "git",
        "uploads",
        "data-loss",
        "backup",
        "rsync",
        "monitoring"
      ],
      "severity": "critical",
      "status": "resolved",
      "stack": [
        "git",
        "rsync",
        "node",
        "nextjs"
      ],
      "prevention": "Uživatelské uploady drž MIMO git working tree a zároveň je gitignoruj; zálohuj offsite rsyncem BEZ --delete a hlídej propad počtu souborů cronem s alertem.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/deploy/git-clean-wipes-untracked-uploads/"
    },
    {
      "title": "CSS columns koliduje s grid layoutem",
      "description": "Vlastnost columns (multi-column) na rodiči přebíjí display:grid → mřížka produktů se rozsype.",
      "category": "frontend",
      "tags": [
        "css",
        "layout",
        "grid"
      ],
      "severity": "low",
      "status": "resolved",
      "stack": [
        "css"
      ],
      "prevention": "Pro mřížky používej výhradně display:grid. Nikdy nemíchej multi-column (columns:N) a grid na stejném/rodičovském elementu.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/frontend/css-columns-vs-grid-conflict/"
    },
    {
      "title": "preventDefault přeskočí HTML5 validaci formuláře",
      "description": "Submit handler s e.preventDefault() vypne nativní validaci → na server odejdou prázdná pole a uživatel dostane matoucí generickou chybu.",
      "category": "frontend",
      "tags": [
        "forms",
        "validation",
        "ux",
        "javascript"
      ],
      "severity": "medium",
      "status": "resolved",
      "stack": [
        "vanilla-js",
        "forms"
      ],
      "prevention": "U každého submit handleru s preventDefault přidej explicitní validaci (checkValidity nebo vlastní) předtím, než pošleš fetch.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/frontend/preventdefault-skips-html5-validation/"
    },
    {
      "title": "Refaktor view tiše vypustí funkci",
      "description": "Přepis SELECT/render řetězce zahodí kus logiky (zvýraznění, řazení) bez chyby — feature prostě zmizí.",
      "category": "frontend",
      "tags": [
        "refactoring",
        "frontend",
        "regression"
      ],
      "severity": "medium",
      "status": "resolved",
      "stack": [
        "refactoring",
        "frontend"
      ],
      "prevention": "Kritické view chování zafixuj „display contract\" dokumentem + E2E smoke testem na přítomnost klíčových tříd/řazení.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/frontend/refactor-silently-drops-feature/"
    },
    {
      "title": "DigiSign e-podpis — envelope flow, popup blokace a zrušení obálky",
      "description": "Kompletní integrace elektronického podpisu přes DigiSign REST API — pořadí volání, embed popup (blokace prohlížečem) a past, kdy zrušení obálky jen lokálně nechá obálku živou na straně poskytovatele.",
      "category": "integrations",
      "tags": [
        "e-signature",
        "digisign",
        "rest-api",
        "popup",
        "webhook",
        "envelope"
      ],
      "severity": "high",
      "status": "resolved",
      "stack": [
        "nextjs",
        "rest-api"
      ],
      "prevention": "Embed popup vždy otevírej v reakci na klik a loading state resetuj ve finally; zrušení/storno obálky musí volat API poskytovatele, ne jen smazat lokální referenci.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/integrations/digisign-envelope-signing-flow/"
    },
    {
      "title": "E-mail helper tiše zahodí přílohy",
      "description": "Helper sendRawEmail ignoroval options.attachments a připojoval jen logo → faktura odešla bez PDF přílohy.",
      "category": "integrations",
      "tags": [
        "email",
        "nodemailer",
        "attachments"
      ],
      "severity": "low",
      "status": "resolved",
      "stack": [
        "email",
        "nodemailer"
      ],
      "prevention": "U e-mail helperů otestuj všechny větve options (attachments, cc, reply-to), ne jen happy path. Ověř, že příloha reálně dorazí.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/integrations/email-helper-ignored-attachments/"
    },
    {
      "title": "Pád externí API shodí celý flow",
      "description": "Selhání 3rd party (účetní/fakturační API vrátí 503) propadne do hlavní transakce a shodí ji, místo aby bylo izolované.",
      "category": "integrations",
      "tags": [
        "integrations",
        "webhooks",
        "resilience",
        "retry"
      ],
      "severity": "medium",
      "status": "resolved",
      "stack": [
        "integrations",
        "webhooks"
      ],
      "prevention": "Žádná 3rd party závislost nesmí blokovat core flow. Izoluj try/catch, loguj, retry asynchronně. Webhook vrať 200 i při selhání navázané akce.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/integrations/third-party-api-503-non-blocking/"
    },
    {
      "title": "Peněžní částky nezaokrouhlené na 2 desetinná místa",
      "description": "Doklady a příjmy počítané ve float bez zaokrouhlení na 2 místa → součty a DPH se rozcházejí o haléře napříč nabídkou, fakturou a účetnictvím.",
      "category": "payments",
      "tags": [
        "money",
        "rounding",
        "vat",
        "dph",
        "invoicing",
        "float"
      ],
      "severity": "high",
      "status": "resolved",
      "stack": [
        "javascript",
        "invoicing"
      ],
      "prevention": "Všechny peněžní částky a příjmy zaokrouhluj na 2 desetinná místa v jednom centrálním helperu. DPH počítej konzistentně ze stejného základu napříč nabídkou i dokladem.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/payments/money-rounding-2-decimals/"
    },
    {
      "title": "Nová verze Stripe API přesunula cestu k subscription ve webhooku",
      "description": "Po bumpu API verze se reference na subscription přesunula z invoice.subscription do invoice.parent.subscription_details.subscription → webhook čte null a neaktivuje účet.",
      "category": "payments",
      "tags": [
        "stripe",
        "webhooks",
        "api-version",
        "subscription"
      ],
      "severity": "high",
      "status": "resolved",
      "stack": [
        "stripe",
        "webhooks"
      ],
      "prevention": "Po bumpu verze platební brány projdi changelog migrací, otestuj webhook na testovacím eventu a měj fallback na starou i novou cestu během přechodu.",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/payments/stripe-api-version-subscription-path-moved/"
    },
    {
      "title": "Start trialu generuje faktury na nulu",
      "description": "Brána pošle invoice.paid i pro subscription_create (start trialu) s amount_paid 0 → webhook vystaví reálnou fakturu na 0.",
      "category": "payments",
      "tags": [
        "stripe",
        "webhooks",
        "invoicing",
        "billing-reason"
      ],
      "severity": "medium",
      "status": "resolved",
      "stack": [
        "stripe",
        "webhooks",
        "invoicing"
      ],
      "prevention": "Rozlišuj billing_reason a amount_paid. Trial start ≠ platba — fakturu vystav až u reálného stržení (subscription_cycle).",
      "date": "2026-05-25",
      "url": "https://bugwiki.cz/payments/stripe-trial-create-zero-amount-invoices/"
    }
  ]
}