[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-10926":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":23,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":16,"starSnapshotCount":16,"syncStatus":29,"lastSyncTime":30,"discoverSource":31},10926,"myinvoice","radekhulan\u002Fmyinvoice","radekhulan","MyInvoice.cz - fakturační a účetní systém pro menší firmy","https:\u002F\u002Fmyinvoice.cz\u002F",null,"PHP",242,88,8,7,0,3,22,120,9,72.85,"MIT License",false,"master",[],"2026-06-12 04:00:52","# MyInvoice.cz\n\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg)](LICENSE)\n[![PHP 8.5+](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FPHP-8.5+-777BB4?logo=php&logoColor=white)](https:\u002F\u002Fwww.php.net\u002F)\n[![MariaDB 10.6+](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FMariaDB-10.6+-003545?logo=mariadb&logoColor=white)](https:\u002F\u002Fmariadb.org\u002F)\n[![Vue 3](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FVue-3-4FC08D?logo=vuedotjs&logoColor=white)](https:\u002F\u002Fvuejs.org\u002F)\n[![Docker](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDocker-multi--arch-2496ED?logo=docker&logoColor=white)](https:\u002F\u002Fgithub.com\u002Fradekhulan\u002Fmyinvoice\u002Fpkgs\u002Fcontainer\u002Fmyinvoice)\n[![GHCR](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fv\u002Ftag\u002Fradekhulan\u002Fmyinvoice?label=GHCR&color=2496ED&logo=docker&logoColor=white)](https:\u002F\u002Fgithub.com\u002Fradekhulan\u002Fmyinvoice\u002Fpkgs\u002Fcontainer\u002Fmyinvoice)\n\n> **Český fakturační systém pro freelancery, OSVČ a malé firmy.**\n> Rychlé vystavování opakovaných faktur, QR platby, výkaz víceprací,\n> import bankovních výpisů, exporty pro účetní software — vše na vlastním serveru.\n\nVyvíjí **[MyWebdesign.cz s.r.o.](https:\u002F\u002Fmywebdesign.cz\u002F)**\n\n🌐 **Projektový web: [MyInvoice.cz](https:\u002F\u002Fmyinvoice.cz\u002F)**\n\n📖 **Online dokumentace: [MyInvoice.cz\u002Fmanual](https:\u002F\u002Fmyinvoice.cz\u002Fmanual\u002F)**\n\n> ⚠️ **Než začneš fakturovat — přečti si [Fakturujeme — daňový průvodce](manual\u002F06_Fakturujeme.md).**\n> Vysvětluje, jak aplikace pracuje s plátci\u002Fneplátci DPH, sazbami, reverse charge,\n> kde má aplikace limitace (OSS, SK 23 %) a jak je obejít. **Správnost faktury\n> je vždy na uživateli — pro nestandardní situace konzultuj účetní.**\n\n![Přehled (dashboard)](manual\u002Fimg\u002F01_dashboard.webp)\n\n---\n\n## Proč MyInvoice.cz?\n\nVětšina českých online fakturačních služeb je SaaS s měsíčními poplatky a vašimi\nfakturačními daty mimo váš dosah. **MyInvoice.cz je open-source, self-hosted**\nalternativa s důrazem na:\n\n- **Tvoji databázi, tvoje data** — vše běží na vlastním (nebo pronajatém) serveru, žádný cloud.\n- **Multi-supplier od první verze** — fakturuj za více firem \u002F IČ z jedné instalace, snadný přepínač v UI.\n- **Český kontext první** — ARES + VIES lookup, SPAYD QR (ČR) i SEPA EPC QR (EU),\n  ISDOC + Pohoda XML exporty, mod-11 validace bankovních účtů, GPC import výpisů.\n- **Nulové měsíční náklady** — jednorázový setup, žádné per-fakturové poplatky, žádné limity.\n\n---\n\n## Co umí\n\n### 📄 Fakturace\n- 4 typy dokladů: **faktura**, **zálohová (proforma)**, **opravný daňový doklad** (dobropis), **interní storno**\n- Vystavení daňového dokladu z proformy s automatickým **odečtem zaplacené zálohy**\n- **Klonování faktur** s auto-inkrementem měsíce v popiscích (`3\u002F2026 → 4\u002F2026`)\n- Hromadné akce: *Vystavit znovu (N)*, *Odeslat klientovi (N)*, *Označit jako zaplacené*, *Upomínka*\n- **Výkaz víceprací** (work_report) jako 2. strana PDF s přenosem sumy do položky\n- **Schvalování výkazu zákazníkem přes e-mailový odkaz** — volitelné per zakázka:\n  zákazník dostane e-mail s odkazem na veřejnou stránku (token + CAPTCHA),\n  jedním klikem schválí\u002Fzamítne, faktura se po schválení automaticky vystaví\n  a odešle\n- PDF se **snapshotem dodavatele\u002Fodběratele\u002Fbanky** — vystavená faktura je neměnná\n- Editace vystavené faktury jen pro admina s `?force=1` + audit záznam\n\n![QR platba na PDF faktuře](manual\u002Fimg\u002F10_qr_platba.webp)\n\n### 💳 Platby\n- **QR platby** přímo v PDF: SPAYD pro CZK, SEPA EPC pro EUR\n- **Import GPC** výpisů (ABO formát, KB \u002F FIO \u002F ČSOB \u002F RB \u002F ČS) s SHA256 dedupe\n- **Auto-matching** transakcí na faktury podle VS + částky → automaticky `paid`\n- Manuální párování + označení transakce jako \"ignorovat\"\n- **Upomínky** po splatnosti — manuální tlačítko na detailu, hromadná akce, nebo cron\n\n![Schvalovací stránka pro zákazníka](manual\u002Fimg\u002F09_schvalit_vykaz_prace.webp)\n\n### 👥 Klienti & zakázky\n- Klienti s **ARES** (IČ → adresa, název) a **VIES** (DIČ) lookupem\n- Zakázky 1:N pod klientem, fakturační emaily per zakázka (účetní, PM…)\n- Filter zakázek podle klienta\n- Reverse charge přepínatelný per klient\n- Smazání chráněné 409, pokud má klient\u002Fzakázka navázané faktury\n\n### 🏢 Multi-supplier\n- Z jedné instalace fakturuj **za libovolný počet dodavatelů (firem \u002F IČ)**\n- Přepínač v horní liště, izolovaná data (klienti, zakázky, faktury, číselníky)\n- Každý dodavatel má vlastní sadu měn + bankovních účtů, vlastní řadu varsymbolů\n- Per-dodavatel: ARES údaje, logo, podpis, SMTP `From:` jméno + `Reply-To:` adresa, Pohoda kódy\n\n### 📦 Exporty pro účetní\n- **Hromadný export PDF** (ZIP po měsících)\n- **ISDOC 6.0.2** — český národní standard pro B2B výměnu faktur\n- **Pohoda XML** (Stormware data package) — přímý import do Pohody bez ručního opisu\n- Per-dodavatel konfigurace Pohoda kódů (středisko, činnost, předkontace, číselná řada)\n\n### 📧 Komunikace\n- Odesílání faktur **e-mailem** (Symfony Mailer + DKIM podpora)\n- **Editor e-mailových šablon** v UI (Twig) — CZ \u002F EN, HTML + plaintext varianty\n- Šablony: nová faktura, upomínka, reset hesla, test\n- Per-dodavatel branding (`From:` jméno, `Reply-To:`)\n\n### 🔒 Bezpečnost\n- **CZ + EN lokalizace** UI i faktur\n- **Brute-force ochrana** (Redis nebo MariaDB MEMORY fallback) — 5 selhání → CAPTCHA, 30\u002Fh → 24h lockout\n- **Cloudflare Turnstile** CAPTCHA\n- **IP allowlist** (IPv4 + IPv6 + CIDR)\n- **CSRF** + Origin check, **TOTP 2FA**, peppered bcrypt hesla\n- **RBAC** (admin \u002F accountant \u002F readonly)\n- **Activity log** všech mutací (včetně IP)\n\n### 📊 Dashboard\n- KPI tiles, **dynamický počet sloupců** dle aktivních měn (4–6)\n- Top klienti — koláč letošního i loňského roku\n- Obrat po měsících (line chart letos vs. minulý rok)\n- Po splatnosti + nezaplacené faktury (s tlačítkem upomínka)\n\n---\n\n## Quick start: Docker (3 minuty)\n\nNejrychlejší cesta k běžící aplikaci. Stačí mít nainstalovaný **Docker Desktop**\n(Windows \u002F macOS) nebo **Docker Engine + compose-plugin** (Linux) — nepotřebuješ\nlokálně PHP, MariaDB, Node ani nic dalšího.\n\n### Varianta A — one-click z GHCR ⭐ (nejsnazší)\n\nNaklonuj repo a spusť jeden příkaz. Stáhne pre-built multi-arch image\n(`ghcr.io\u002Fradekhulan\u002Fmyinvoice:latest`, `linux\u002Famd64` + `linux\u002Farm64`),\nvygeneruje hesla a configy, spustí stack a migrace. Nepotřebuješ na hostu\n`pnpm`\u002F`composer` ani několikaminutový build.\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fradekhulan\u002Fmyinvoice.git\ncd myinvoice\n\n# Linux \u002F macOS\ncmd\u002Fdocker-ghcr.sh\n\n# Windows PowerShell\n.\\cmd\\docker-ghcr.ps1\n```\n\n> **WSL2 \u002F Linux po klonu:** pokud `.\u002Fcmd\u002Fdocker-ghcr.sh` hlásí\n> `Permission denied` nebo `\u002Fusr\u002Fbin\u002Fenv: 'bash\\r': No such file…`,\n> má tvůj git zapnutý `core.autocrlf=true` (na checkoutu konvertuje LF → CRLF).\n> Oprav jednorázově existující soubory a vypni autocrlf globálně:\n>\n> ```bash\n> sed -i 's\u002F\\r$\u002F\u002F' cmd\u002F*.sh\n> chmod +x cmd\u002F*.sh\n> git config --global core.autocrlf input\n> ```\n>\n> Repo má `.gitattributes` s `*.sh text eol=lf`, takže příští `git clone`\n> bude LF i bez tohoto kroku.\n\nSkript automaticky:\n\n1. Vygeneruje `.env` s náhodnými DB hesly (28 znaků base64)\n2. Vygeneruje `cfg.docker.php` z `cfg.sample.php` (host=db \u002F redis, randomized\n   `app.pepper` + `secret_encryption_key`, dev-friendly cookies pro HTTP loopback)\n3. `docker compose pull` — stáhne image z GHCR\n4. Spustí stack: **app** (Apache:80→host:8080) + **db** (MariaDB 11)\n5. Počká, až bude DB healthy, a spustí migrace\n\nPoužívá `docker-compose.production.yml`, takže další compose příkazy vyžadují\nflag `-f docker-compose.production.yml` (logs, pull, down…).\n\n**Aktualizace na novou verzi** — stačí jeden příkaz:\n\n```bash\n# Linux \u002F macOS\ncmd\u002Fdocker-update.sh\n\n# Windows PowerShell\n.\\cmd\\docker-update.ps1\n```\n\nSkript v registry módu sám zavolá `docker compose pull app` (stáhne nový image\nz GHCR), restartuje stack a doběhne pending migrace. Volumes (DB data) zůstávají\nzachovány. Nový image se publikuje automaticky při každém release tagu\n`v*.*.*`.\n\n> 🔔 **Upgrade přímo z UI (admin):** od **v3.0.0** aplikace denně kontroluje\n> GitHub Releases API a v patičce zobrazí aktuální verzi + badge pokud je\n> dostupná novější. Admin v **Systém → Aktualizace** vidí release notes a\n> tlačítkem **„Aktualizovat\"** zařadí upgrade do fronty. Vlastní pull image\n> + restart provádí host-side proces `cmd\u002Fdocker-update-watcher.(sh\u002Fps1)` —\n> viz **„Update watcher\"** níže. Bez watcheru pořád funguje shell příkaz\n> výše. Daily check ke svému běhu potřebuje cron\n> `php api\u002Fbin\u002Fcron-version-check.php` (1× denně).\n\n#### Update watcher — jednoclick upgrade z UI\n\nWatcher je samostatný host-side proces, který sleduje flag soubor uvnitř\nkontejneru (`docker compose exec -T app test -f storage\u002Fupgrade-requested.json`)\na když ho najde, spustí `cmd\u002Fdocker-update.(sh\u002Fps1)` — pull `:latest`\nimage, restart stacku, migrace. Výsledek zapíše zpět do kontejneru,\nUI ho zobrazí jako „Upgrade úspěšně dokončen \u002F selhal\".\n\n**Test ve foregroundu** (než ho udělej daemon):\n\n```bash\n# Linux \u002F macOS\ncd \u002Fopt\u002Fmyinvoice && bash cmd\u002Fdocker-update-watcher.sh\n```\n\n```powershell\n# Windows\ncd C:\\inetpub\\myinvoice\npowershell -NoProfile -ExecutionPolicy Bypass -File cmd\\docker-update-watcher.ps1\n```\n\n**Produkce — daemon (Linux):**\n\n```bash\nsudo tee \u002Fetc\u002Fsystemd\u002Fsystem\u002Fmyinvoice-update-watcher.service \u003C\u003C'EOF'\n[Unit]\nDescription=MyInvoice update watcher\nAfter=docker.service\n\n[Service]\nType=simple\nWorkingDirectory=\u002Fopt\u002Fmyinvoice\nExecStart=\u002Fopt\u002Fmyinvoice\u002Fcmd\u002Fdocker-update-watcher.sh\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\nsudo systemctl daemon-reload\nsudo systemctl enable --now myinvoice-update-watcher\n```\n\n**Produkce — Scheduled Task (Windows):**\n\n```powershell\nschtasks \u002Fcreate \u002Ftn \"MyInvoice Update Watcher\" `\n  \u002Ftr \"powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\\inetpub\\myinvoice\\cmd\\docker-update-watcher.ps1\" `\n  \u002Fsc onstart \u002Fru SYSTEM \u002Frl HIGHEST\nschtasks \u002Frun \u002Ftn \"MyInvoice Update Watcher\"\n```\n\nDetaily, recovery při zaseknutém upgradu a odlaďování v manuálu §\n[19 Aktualizace](manual\u002F20_Aktualizace.md).\n\n### Varianta B — build z source (pro vývoj)\n\nS klonem repa máš přístup k celému kódu, můžeš upravovat a build si vyrobí\nlokálně místo stahování z GHCR:\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fradekhulan\u002Fmyinvoice.git\ncd myinvoice\n\n# Linux \u002F macOS\ncmd\u002Fdocker-install.sh\n\n# Windows PowerShell\n.\\cmd\\docker-install.ps1\n```\n\nStejné kroky jako Varianta A, jen místo `pull` z GHCR postaví `myinvoice:latest`\nimage lokálně (multi-stage: Vue build → composer → PHP 8.5 + Apache). Pomalejší,\nale zachytí tvoje rozpracované úpravy v repu.\n\n### Varianta C — bez klonování repa (jen Docker, manuálně)\n\nPro produkční Linux server, kde nechceš mít ani klon repa. Stáhneš jen dva\nsoubory přes `curl` a sestavíš konfiguraci ručně:\n\n```bash\nmkdir myinvoice && cd myinvoice\ncurl -O https:\u002F\u002Fraw.githubusercontent.com\u002Fradekhulan\u002Fmyinvoice\u002Fmaster\u002Fdocker-compose.production.yml\ncurl -O https:\u002F\u002Fraw.githubusercontent.com\u002Fradekhulan\u002Fmyinvoice\u002Fmaster\u002Fcfg.sample.php\nmv docker-compose.production.yml docker-compose.yml\ncp cfg.sample.php cfg.docker.php\n# uprav cfg.docker.php — minimálně:\n#   db.host => 'db', db.user => 'myinvoice', db.pass => '\u003Cheslo z .env níže>'\n#   app.pepper a secret_encryption_key (oboje: openssl rand -base64 32)\n\ncat > .env \u003C\u003CEOF\nDB_PASSWORD=$(openssl rand -base64 28)\nDB_ROOT_PASSWORD=$(openssl rand -base64 28)\nEOF\n\ndocker compose up -d\n```\n\n> ⚠️ Tato varianta hesla a secrets do `cfg.docker.php` automaticky nedoplní —\n> musíš je tam zapsat ručně (viz komentář v ukázce). Pro one-click použij\n> **Variantu A**.\n\n> 💡 V produkci pinuj konkrétní verzi — v `docker-compose.yml` (resp.\n> `docker-compose.production.yml`) změň `:latest` na konkrétní tag, např.\n> `:1.7.0`. Update pak `cmd\u002Fdocker-update.{sh,ps1}` (auto-detekuje registry\n> mode = `pull` + `up -d` + migrace).\n>\n> Od image **v3.1.0** se migrace pouští i automaticky při startu kontejneru\n> (`docker-entrypoint.sh`), takže nová DB se inicializuje sama.\n\n> 📖 **Manuál na `\u002Fmanual`:** GHCR image má od **v2.1.5** vygenerovaný HTML\n> manuál a od **v2.3.0** i PDF (`tools\u002FgenerateManualHtml.php` +\n> `tools\u002FexportManualToPdf.php` se volají build-time v `Dockerfile`),\n> takže `http:\u002F\u002Flocalhost:8080\u002Fmanual` funguje bez dalších kroků a v sidebaru\n> je button **„Stáhnout PDF\"**. Update na nový obsah = `cmd\u002Fdocker-update.{sh,ps1}`\n> (pull novějšího image).\n>\n> Kdyby `\u002Fmanual` vrátil 503 *„Manuál není zatím vygenerovaný“*: pokud\n> jedeš na starém image před v2.1.5, `cmd\u002Fdocker-update.{sh,ps1}` (pull\n> nového GHCR image) je řešení — staré image neměly `manual\u002F*.md` uvnitř\n> vůbec. Na v2.1.5+ image regeneruješ manuál ručně bez rebuildu:\n>\n> ```bash\n> docker compose -f docker-compose.production.yml exec app \\\n>   php tools\u002FgenerateManualHtml.php\n> docker compose -f docker-compose.production.yml exec app \\\n>   php tools\u002FexportManualToPdf.php\n> ```\n\n### Po dokončení (všechny varianty)\n\n**Otevři: 👉 [http:\u002F\u002Flocalhost:8080](http:\u002F\u002Flocalhost:8080)**\n\nV prohlížeči naskočí **setup wizard** (3 kroky):\n\n1. **Administrátor** — jméno, e-mail, heslo (min. 12 znaků)\n2. **Dodavatel** — IČ → *Načíst z ARES* → bankovní účet (např. `1000000005 \u002F 0100`)\n3. **Sample data** *(volitelné)* — checkboxem 5 klientů + 8 zakázek + 20 faktur + 4 dobropisy\n\nWizard tě po dokončení **automaticky přihlásí**.\n\n### Další port než 8080?\n\nEdituj `.env` (vznikl po prvním spuštění install skriptu):\n\n```bash\nAPP_PORT=9000              # místo 8080\nDB_PORT=3308               # místo 3307 (vázán jen na 127.0.0.1)\n```\n\na `docker compose up -d`. URL pak bude `http:\u002F\u002Flocalhost:9000`.\n\n### Env proměnné pro auto-migrace (Docker runtime)\n\n```bash\nMYINVOICE_SKIP_MIGRATIONS=1     # vypne auto-migraci při startu\nMYINVOICE_MIGRATE_ATTEMPTS=20   # počet retry pokusů migrace\nMYINVOICE_MIGRATE_DELAY=3       # pauza mezi pokusy (sekundy)\nMYINVOICE_DATA_DIR=\u002Fdata        # v3.6.0+ default v compose souborech (single-volume layout)\nMYINVOICE_AUTH_REQUIRE_TOTP=true # v3.3.0+ — vynutit 2FA pro všechny uživatele (default false)\n```\n\nOd image **v3.1.0** se migrace pouští při startu kontejneru automaticky\n(`docker-entrypoint.sh`). Ruční `php api\u002Fbin\u002Fmigrate.php` je stále bezpečný\nidempotentní fallback.\n\nOd **v3.6.0** je `MYINVOICE_DATA_DIR=\u002Fdata` default v `docker-compose.yml` i\n`docker-compose.production.yml` — všechen stateful obsah (log\u002F, storage\u002F,\nprivate\u002Fdkim\u002F, **i `cfg.local.php`**) leží v jediném `app-data:\u002Fdata` volumu.\nPer-instance konfigurace ze setup wizardu tak přežije image update.\n\nImage obsahuje stub `cfg.php`, takže bind-mount `cfg.docker.php` je volitelný —\npro full-ENV deploy ho lze vynechat.\n\n**Upgrade z 3.5.x a starší (3-volume layout):** `cmd\u002Fdocker-update.{sh,ps1}`\ndetekuje staré volumes (`app-log`, `app-storage`, `app-private`) a před `up -d`\nautomaticky spustí `cmd\u002Fdocker-migrate-volumes.{sh,ps1}` — zkopíruje data\ni `cfg.local.php` ze starého layoutu do `app-data`. Staré volumes nemaže\n(úklid příkazy vypíše).\n\n### Railway \u002F PaaS env placeholdery\n\nOd v3.1.0 aplikace v env overridech ignoruje nevyřešené placeholdery ve tvaru\n`${VAR}` (typicky Railway, když proměnná není definovaná), takže nepřepíšou\nvalidní hodnoty z `cfg.php` \u002F `cfg.docker.php`.\n\n### Daily ops\n\n```bash\ndocker compose up -d                                 # start\ndocker compose down                                  # stop (data v named volumes přežijí)\ndocker compose down -v                               # stop + WIPE volumes (ZNIČÍ DB!)\ndocker compose logs -f app                           # live logs\ndocker compose exec app bash                         # shell do kontejneru\ndocker compose exec app php api\u002Fbin\u002Fmigrate.php      # CLI uvnitř kontejneru\ncmd\u002Fdocker-build.sh --no-cache                       # rebuild image (po PHP\u002FJS změnách)\n```\n\n### Po setupu si edituj `cfg.docker.php`\n\nInstall skript nastaví minimum potřebné k běhu, ale tyto věci si musíš doplnit ručně:\n\n- `smtp.*` — odchozí pošta (jinak nepůjdou faktury \u002F upomínky \u002F reset hesla)\n- `captcha.site_key` + `captcha.secret_key` — z [dash.cloudflare.com → Turnstile](https:\u002F\u002Fdash.cloudflare.com)\n- `ip_allowlist.allow` — volitelné, doporučeno mimo lokál\n\nPo editaci stačí `docker compose restart app` (cfg je bind-mountovaný — žádný rebuild).\n\n### Volitelný Redis\n\n```bash\ndocker compose --profile redis up -d\n```\n\na v `cfg.docker.php` nastav `redis.enabled => true` (host už je `redis`). Restart appky.\n\nVíce detailů (cron uvnitř kontejneru, `.env` proměnné, troubleshooting): viz [`cmd\u002FREADME.md`](cmd\u002FREADME.md).\n\n---\n\n## Setup bez Dockeru (native, 5 minut)\n\nPokud nechceš Docker (např. cílový deploy je IIS \u002F Apache na holém železe).\n\n### Předpoklady\n\n- **PHP 8.5+** s extensions: `pdo`, `pdo_mysql`, `mbstring`, `openssl`, `json`, `iconv`, `gd`\n- **MariaDB 10.6+** (doporučeno 11.x)\n- **Composer 2.x**, **Node.js 22+**, **pnpm 10+**\n- **Redis** (volitelné — fallback na MariaDB MEMORY)\n- Web server: **IIS** nebo **Apache** (oba podporované, repo má `web.config` i `.htaccess`)\n\n### 1. Klon a konfigurace\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fradekhulan\u002Fmyinvoice.git myinvoice\ncd myinvoice\ncp cfg.sample.php cfg.php\n```\n\nOtevři `cfg.php` a vyplň:\n\n- `db.user` \u002F `db.pass` — připojení k MariaDB\n- `app.pepper` — vygeneruj `openssl rand -base64 32`\n- `smtp.host` \u002F `user` \u002F `pass` — odchozí pošta\n- `captcha.site_key` \u002F `secret_key` — z [dash.cloudflare.com → Turnstile](https:\u002F\u002Fdash.cloudflare.com)\n- `ip_allowlist.allow` — volitelné, doporučeno v produkci\n\n### 2. Vytvoř databázi\n\n```bash\nmysql -u root -p -e \"CREATE DATABASE myinvoice CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\"\n```\n\n### 3. Nainstaluj backend a spusť migrace\n\n```bash\ncd api && composer install && cd ..\nphp api\u002Fbin\u002Fmigrate.php\nphp tools\u002FgenerateManualHtml.php   # vyrenderuje manual\u002Fgenerated\u002F → \u002Fmanual route\nphp tools\u002FexportManualToPdf.php    # vygeneruje manual\u002Fmanual.pdf (Stáhnout PDF v sidebaru)\n```\n\n> `generateManualHtml.php` je self-contained (nepotřebuje composer\u002Fvendor),\n> generuje HTML kapitoly + search index. `exportManualToPdf.php` vyžaduje\n> `api\u002Fvendor\u002F` (mPDF). Spouštět znovu po každém pull repa, aby `\u002Fmanual`\n> ukazoval aktuální obsah. (V Docker variantě se obě volají build-time\n> uvnitř `Dockerfile`.)\n\n### 4. Frontend\n\n```bash\ncd web\npnpm install\npnpm build       # produkční build do web\u002Fdist\u002F\n# nebo pro vývoj:\npnpm dev         # dev server na :5173\n```\n\n### 5. Otevři prohlížeč → setup wizard\n\nV prohlížeči navštiv `https:\u002F\u002Ftvoje-domena.cz` (nebo `http:\u002F\u002Flocalhost:5173` v devu)\na projdi **3 kroky setup wizardu**:\n\n1. **Administrátor** — jméno, e-mail, heslo (min. 12 znaků, indikátor síly)\n2. **Dodavatel** — vyplň IČ a klikni *Načíst z ARES* (předvyplní název, adresu,\n   DIČ); doplň první bankovní účet (CZK)\n3. **Sample data** *(volitelné)* — checkboxem si necháš vygenerovat 5 klientů,\n   8 zakázek, 20 faktur a 4 dobropisy pro vyzkoušení systému\n\nPo dokončení tě wizard **automaticky přihlásí** a přesměruje do aplikace.\n\n### Další dodavatelé\n\nV menu **Systém → Dodavatelé** klikni *Nový dodavatel*. Stačí zadat IČ → ARES doplní\nzbytek. V horní liště se objeví přepínač pro snadné přepínání mezi firmami.\n\n### Aktualizace nativní instalace\n\nKlasická cesta (vyžaduje Composer + Node + pnpm na hostu):\n\n```bash\ngit fetch --tags\ngit checkout vX.Y.Z\ncd api && composer install --no-dev && cd ..\ncd web && pnpm install && pnpm build && cd ..\nphp tools\u002FgenerateManualHtml.php\nphp tools\u002FexportManualToPdf.php\nphp api\u002Fbin\u002Fmigrate.php\n```\n\nBez Composeru \u002F Node (sdílený hosting) — stáhni **production bundle** z release\npage (od **v3.0.0** se publikuje automaticky při tagu):\n\n```bash\nTAG=3.0.0\ncurl -LO https:\u002F\u002Fgithub.com\u002Fradekhulan\u002Fmyinvoice\u002Freleases\u002Fdownload\u002Fv$TAG\u002Fmyinvoice-$TAG.tar.gz\nsha256sum -c myinvoice-$TAG.tar.gz.sha256   # ověř integritu\ntar -xzf myinvoice-$TAG.tar.gz --strip-components=1 \\\n  --exclude='cfg.php' --exclude='cfg.local.php' \\\n  --exclude='storage' --exclude='private' --exclude='log'\nphp api\u002Fbin\u002Fmigrate.php\n```\n\nBundle obsahuje hotové `api\u002Fvendor\u002F`, `web\u002Fdist\u002F`, `manual\u002Fgenerated\u002F` i\n`manual.pdf`, takže žádný build krok není potřeba.\n\n> 🔔 **Upgrade z UI (admin):** v **Systém → Aktualizace** je tlačítko\n> *Aktualizovat*, které ti tyto příkazy zobrazí jako copy-paste box (Phase 2\n> doplní automatický download + extrakci). Footer aplikace zobrazuje\n> aktuální verzi + badge pokud je dostupná novější (denně refreshuje\n> `cron-version-check.php`).\n\n---\n\n## CLI nástroje\n\n```bash\nphp api\u002Fbin\u002Fmigrate.php              # spustí pending migrace\nphp api\u002Fbin\u002Fmigrate.php --status     # vypíše stav migrací\nphp api\u002Fbin\u002Fsetup.php                # interaktivní úvodní zřízení (cfg + DB + ARES + admin)\nphp api\u002Fbin\u002Fsample.php               # vygeneruje testovací data (po setupu)\nphp api\u002Fbin\u002Freset.php                # smaže všechna user-data (CLI only, vyžaduje \"ANO\")\nphp api\u002Fbin\u002Freset.php --yes          # bez potvrzení\nphp api\u002Fbin\u002Freset-2fa.php \u003Cemail>    # nouzově vypne 2FA uživateli podle e-mailu\nphp api\u002Fbin\u002Frecompute-stats.php      # přepočítá agregované statistiky\n```\n\n### Cron skripty\n\nV `cmd\u002F` jsou připravené `.cmd` (Windows) i `.sh` (Linux) wrappery:\n\n```bash\ncmd\u002Fcron-bank-scan.sh        # každých 15 min — scan příchozích GPC výpisů\ncmd\u002Fcron-send-reminders.sh   # 1× denně — upomínky po splatnosti (s --cooldown)\ncmd\u002Fcron-cleanup.sh          # 1× denně — čištění expirovaných session, logů, PDF cache\n```\n\nK tomu **`api\u002Fbin\u002Fcron-version-check.php`** — denní kontrola GitHub Releases\nAPI, cachuje poslední dostupnou verzi + release notes do `app_meta`. Bez\nněj UI v `Systém → Aktualizace` vidí jen aktuální verzi a admin se nedozví\no nové. Plánuj 1× denně:\n\n```bash\n# Linux cron (nativní instalace)\n0 6 * * *  cd \u002Fopt\u002Fmyinvoice && php api\u002Fbin\u002Fcron-version-check.php\n\n# Docker\n0 6 * * *  docker compose -f \u002Fopt\u002Fmyinvoice\u002Fdocker-compose.production.yml exec -T app php api\u002Fbin\u002Fcron-version-check.php\n```\n\n---\n\n## DKIM (volitelné, doporučeno pro deliverabilitu)\n\n```bash\nmkdir -p private\u002Fdkim && cd private\u002Fdkim\nopenssl genrsa -out myinvoice.pem 2048\nopenssl rsa -in myinvoice.pem -pubout -out myinvoice.pub\n\necho \"v=DKIM1; k=rsa; p=$(grep -v '^-----' myinvoice.pub | tr -d '\\n')\" > dns.txt\n```\n\nPublikuj DNS TXT záznam `myinvoice._domainkey.tvoje-domena.cz` s obsahem `dns.txt`,\npak v `cfg.php` přepni `smtp.dkim.enabled => true`.\n\n---\n\n## Stack\n\n| Vrstva | Volba |\n|---|---|\n| Backend | PHP 8.5 + Slim 4.13 + PHP-DI 7 + Twig 3.10 + Monolog 3.7 + Guzzle 7.9 |\n| Frontend | Vue 3.5 + Vite 8 + Tailwind 4 + Pinia 3 + vue-router 5 + vue-i18n 11 + VueUse 14 + axios 1.16 + TypeScript 6 |\n| Databáze | MariaDB 10.6+ (doporučeno 11.x) |\n| PDF | mPDF 8.2 + Twig 3.10 templates |\n| Grafy | Chart.js 4 + vue-chartjs 5 |\n| QR | rikudou\u002Fczqrpayment 5 (SPAYD), smhg\u002Fsepa-qr-data 3 (EPC), chillerlan\u002Fphp-qrcode 6 |\n| Mail | Symfony Mailer 8 (SMTP + DKIM) + Symfony Mime 8 |\n| Validace | respect\u002Fvalidation 3, enshrined\u002Fsvg-sanitize 0.22 |\n| Cache \u002F brute-force | Redis přes predis 3 (preferred) \u002F MariaDB MEMORY (fallback) |\n| Auth | session-based + CSRF + TOTP 2FA |\n| Testy \u002F kvalita | PHPUnit 13, PHPStan 2, php-cs-fixer 3, vue-tsc 3 |\n| Build | Composer 2 (PHP), pnpm 10 + Node.js 22+ (JS), GitHub Actions CI |\n\nPokud chybí `cfg.php` nebo nelze do DB, frontend i API vrací **503 s instrukcemi**\n(žádná bílá stránka).\n\n---\n\n## Dokumentace\n\n**Uživatelský manuál** (HTML, lokálně po instalaci): `https:\u002F\u002Ftvoje-domena.cz\u002Fmanual` —\n17 kapitol (od přihlášení po Pohoda XML export), fulltext search, sidebar TOC.\nZdroj v `manual\u002F*.md`.\n\n**Vývojářská spec** v `source\u002F`:\n\n- [`source\u002F00-README.md`](source\u002F00-README.md) — rozcestník\n- [`source\u002F01-spec.md`](source\u002F01-spec.md) — funkční + technická spec\n- [`source\u002F02-database.md`](source\u002F02-database.md) — DB schéma\n- [`source\u002F03-architecture.md`](source\u002F03-architecture.md) — architektura, deploy\n- [`source\u002F04-api.md`](source\u002F04-api.md) — REST API\n- [`source\u002F05-design.md`](source\u002F05-design.md) — design system\n- [`source\u002F06-roadmap.md`](source\u002F06-roadmap.md) — plán vývoje\n- [`source\u002F07-security-audit.md`](source\u002F07-security-audit.md) — bezpečnostní audit\n\n---\n\n## Bezpečnostní hlášení\n\nNašel jsi zranitelnost? **Nehlas přes public Issues** — pošli přímo přes\nformulář na [mywebdesign.cz](https:\u002F\u002Fmywebdesign.cz\u002F) s předmětem\n`[SECURITY] MyInvoice.cz`. Detailní postup v [SECURITY.md](SECURITY.md).\n\n---\n\n## Licence\n\n**MIT** — [LICENSE](LICENSE). Můžeš zdarma používat, modifikovat a redistribuovat\n(včetně komerčního použití). Jediná podmínka — zachovat copyright + MIT text\nv derivátech.\n\nVyvíjí **[MyWebdesign.cz s.r.o.](https:\u002F\u002Fmywebdesign.cz\u002F)** © 2026.\n\n## Zřeknutí se odpovědnosti\n\n> **Software je poskytován „TAK JAK JE\", bez záruky jakéhokoli druhu**,\n> výslovné nebo předpokládané, včetně, ale nikoliv pouze, záruk\n> obchodovatelnosti, vhodnosti pro určitý účel a neporušení práv třetích osob.\n>\n> **Použití této aplikace je výhradně na vlastní riziko uživatele.**\n> Autoři ani přispěvatelé v žádném případě neodpovídají za jakékoli přímé,\n> nepřímé, náhodné, zvláštní, exemplární či následné škody (mimo jiné za\n> ztrátu dat, ušlý zisk, výpadek provozu nebo poškození pověsti) vzniklé\n> v souvislosti s používáním nebo nemožností použití tohoto softwaru,\n> a to ani v případě, že byli o možnosti takových škod informováni.\n>\n> Aplikace zpracovává **fakturační a účetní data** — uživatel je výhradně\n> odpovědný za:\n> - **správnost vystavených dokladů** podle platné legislativy ČR \u002F EU\n>   (zákon o DPH, zákon o účetnictví, GDPR atd.);\n> - **zálohování databáze a souborů** v `storage\u002F`;\n> - **zabezpečení produkčního nasazení** (HTTPS, IP allowlist, 2FA, silná\n>   hesla, pravidelné aktualizace závislostí);\n> - **dodržení daňových a archivačních povinností** (ČR: 10 let pro\n>   účetní doklady).\n>\n> Plné znění viz [LICENSE](LICENSE) (MIT — sekce *„NO WARRANTY\"*).\n","MyInvoice.cz 是一个专为自由职业者、个体经营者和小型企业设计的捷克发票系统。该项目支持快速重复开具发票、QR支付、多工作报表生成、银行对账单导入以及会计软件导出等功能，所有操作均可在用户自有的服务器上完成，无需依赖云服务。基于PHP开发，并利用Vue 3构建前端界面，支持MariaDB数据库，同时提供了Docker镜像方便部署。适用于希望控制自身财务数据且不希望承担月度订阅费用的企业或个人使用场景。通过提供开源且自托管的解决方案，MyInvoice.cz确保了用户的隐私安全与成本效益。",2,"2026-06-11 03:30:49","CREATED_QUERY"]