# RAPPORT – Dokumentation

/docs/ Recent content in Dokumentation on RAPPORT Hugo -- gohugo.io de

# Erste Schritte

/docs/erste-schritte/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/erste-schritte/

<p>Von der Installation bis zur ersten Rechnung — in sechs Schritten.</p> <h2>01 · Installation<span class="hx:absolute hx:-mt-20" id="01--installation"></span> <a href="#01--installation" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>DMG von <a href="https://git.kgva.ch/karim/RAPPORT/releases"target="_blank" rel="noopener">Gitea Releases<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> herunterladen. Rapport in den <strong>Programme-Ordner</strong> ziehen. Beim ersten Start: <em>Systemeinstellungen → Datenschutz &amp; Sicherheit</em> öffnen und Rapport zulassen.</p> <p>Die Pre-Release-Builds sind <strong>signiert über Tauri</strong>, aber (noch) nicht über die Apple-Notarisierung gegangen — daher der manuelle Freigabe-Schritt.</p> <h2>02 · Einrichtung<span class="hx:absolute hx:-mt-20" id="02--einrichtung"></span> <a href="#02--einrichtung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>In den <strong>Einstellungen</strong> hinterlegen:</p> <ul> <li><strong>Bürodaten</strong> — Name, Adresse, IBAN, Logo</li> <li><strong>Mitarbeiter</strong> — Namen, Pensum, Stundensatz, Ferienanspruch</li> <li><strong>Kunden</strong> — Adresse, Ansprechperson, Honorartyp</li> <li><strong>Projekte</strong> — SIA-102-Phasen, Budget, Beteiligte</li> </ul> <p>Danach ist die Zeiterfassung bereit.</p> <h2>03 · Zeiterfassung<span class="hx:absolute hx:-mt-20" id="03--zeiterfassung"></span> <a href="#03--zeiterfassung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Im Modul <strong>Zeit</strong>:</p> <ol> <li>Mitarbeiter wählen</li> <li>Woche navigieren</li> <li>Stunden per <strong>Klick</strong> oder <strong>Drag</strong> erfassen</li> <li>Jedem Eintrag ein Projekt zuweisen</li> </ol> <p>Auswertungen pro Mitarbeiter und pro Projekt sind unter <em>Zeit → Auswertungen</em> abrufbar. Halbe Tage und Mehrfacheinträge pro Slot werden unterstützt.</p> <h2>04 · Rechnungen<span class="hx:absolute hx:-mt-20" id="04--rechnungen"></span> <a href="#04--rechnungen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Aus einer <strong>Offerte</strong> oder <strong>direkt</strong> erstellen:</p> <ul> <li>SIA-Phasen, Stundensatz oder Pauschal wählen</li> <li>Akonto-, Teil- oder Schlussrechnung</li> <li>Mit <em>PDF exportieren</em> wird die fertige Rechnung inkl. <strong>QR-Einzahlungsschein</strong> generiert</li> </ul> <p>Offerten lassen sich nahtlos in Projekte und Rechnungen konvertieren.</p> <h2>05 · Backup<span class="hx:absolute hx:-mt-20" id="05--backup"></span> <a href="#05--backup" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>In der Desktop-App liegen alle Daten als <strong>JSON</strong> im Applikationsordner:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">~/Library/Application Support/com.rapport.app/</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>Für ein Backup reicht es, diesen Ordner zu kopieren — z. B. auf einen externen Datenträger oder in die Cloud. Empfohlen: regelmässig (wöchentlich oder via Time Machine). Im Server-Modus läuft das Backup über Postgres-Dumps — siehe <a href="../../server/#backup">Rapport Server § Backup</a>.</p> <h2>06 · Probleme melden<span class="hx:absolute hx:-mt-20" id="06--probleme-melden"></span> <a href="#06--probleme-melden" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Ein <a href="https://git.kgva.ch/karim/RAPPORT/issues"target="_blank" rel="noopener">Issue auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> erstellen — mit kurzer Beschreibung, was passiert ist. <strong>Screenshots helfen.</strong> Bitte die Rapport-Version (links unten in der App) angeben.</p> <blockquote> <p><strong>Tipp:</strong> Wenn die App nicht mehr startet, hilft oft, den Cache-Ordner zu sichern und neu zu starten. Die JSON-Daten selbst bleiben unverändert.</p>

</blockquote>

# Installation

/docs/installation/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/installation/

<p>Schritt-für-Schritt-Anleitung für die Installation der Desktop-App.</p> <h2>Voraussetzungen<span class="hx:absolute hx:-mt-20" id="voraussetzungen"></span> <a href="#voraussetzungen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><table> <thead> <tr> <th>Plattform</th> <th>Status</th> <th>Versionen</th> </tr> </thead> <tbody> <tr> <td><strong>macOS</strong> Apple Silicon (M1 – M4)</td> <td>✅ Unterstützt</td> <td>macOS 12+</td> </tr> <tr> <td><strong>macOS</strong> Intel</td> <td>⚠ Build auf Anfrage</td> <td>macOS 12+</td> </tr> <tr> <td><strong>Linux</strong></td> <td>🕐 Geplant</td> <td>—</td> </tr> <tr> <td><strong>Windows</strong></td> <td>🕐 Geplant</td> <td>—</td> </tr> </tbody> </table> <p>Eine Portierung auf Linux und Windows ist mit Tauri 2 möglich. <a href="https://git.kgva.ch/karim/RAPPORT/issues/new"target="_blank" rel="noopener">Issue erstellen<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>, wenn du eine Plattform brauchst.</p> <h2>1 · Download<span class="hx:absolute hx:-mt-20" id="1--download"></span> <a href="#1--download" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Aktueller Build: <a href="../../downloads">Downloads-Seite</a> oder direkt <a href="https://git.kgva.ch/karim/RAPPORT/releases"target="_blank" rel="noopener">Releases auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p> <table> <thead> <tr> <th>Datei</th> <th>Plattform</th> </tr> </thead> <tbody> <tr> <td><code>RAPPORT_&lt;version&gt;_aarch64.dmg</code></td> <td>macOS Apple Silicon</td> </tr> <tr> <td><code>RAPPORT_&lt;version&gt;_x86_64.dmg</code></td> <td>macOS Intel (auf Anfrage)</td> </tr> </tbody> </table> <h2>2 · DMG öffnen &amp; installieren<span class="hx:absolute hx:-mt-20" id="2--dmg-öffnen--installieren"></span> <a href="#2--dmg-%c3%b6ffnen--installieren" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><ol> <li>DMG doppelklicken</li> <li>Rapport.app in den <strong>Applications</strong>-Ordner ziehen</li> <li>DMG auswerfen</li> </ol> <h2>3 · Erster Start (macOS Gatekeeper)<span class="hx:absolute hx:-mt-20" id="3--erster-start-macos-gatekeeper"></span> <a href="#3--erster-start-macos-gatekeeper" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Beim ersten Start verweigert macOS den Start, weil die Pre-Release-Builds <strong>Tauri-signiert</strong>, aber (noch) <strong>nicht Apple-notarisiert</strong> sind.</p> <h3>Lösung<span class="hx:absolute hx:-mt-20" id="lösung"></span> <a href="#l%c3%b6sung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><ol> <li><strong>Systemeinstellungen → Datenschutz &amp; Sicherheit</strong> öffnen</li> <li>Bis ganz nach unten scrollen — es erscheint: <blockquote> <p>&ldquo;Rapport&rdquo; wurde blockiert, da es nicht von einem identifizierten Entwickler stammt.</p>

</blockquote> </li> <li>Auf <strong>&ldquo;Trotzdem öffnen&rdquo;</strong> klicken</li> <li>Bestätigen</li> </ol> <p>Ab dem zweiten Start läuft Rapport ohne Rückfragen.</p> <h3>Alternative (Terminal)<span class="hx:absolute hx:-mt-20" id="alternative-terminal"></span> <a href="#alternative-terminal" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>Falls der GUI-Weg nicht funktioniert:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xattr -d com.apple.quarantine /Applications/Rapport.app</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>Das entfernt das Quarantäne-Flag und macOS akzeptiert den Start.</p> <h2>4 · Erstes Setup<span class="hx:absolute hx:-mt-20" id="4--erstes-setup"></span> <a href="#4--erstes-setup" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Beim ersten Start zeigt Rapport den <strong>Setup-Bildschirm</strong>. Hier werden die Stammdaten erfasst — siehe <a href="../einrichtung">Einrichtung</a>.</p> <h2>5 · Update-Strategie<span class="hx:absolute hx:-mt-20" id="5--update-strategie"></span> <a href="#5--update-strategie" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Ab Version 0.7.0 prüft Rapport beim Start automatisch auf neue Versionen (siehe <a href="../../features/auto-updater">Auto-Updater</a>). Updates können in den Einstellungen deaktiviert werden.</p> <p>Manuelle Updates: einfach das neuere DMG installieren — die Daten bleiben erhalten, da sie unabhängig von der App liegen (siehe <a href="../datenhaltung">Datenhaltung</a>).</p> <h2>Deinstallation<span class="hx:absolute hx:-mt-20" id="deinstallation"></span> <a href="#deinstallation" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># App entfernen</span> </span></span><span class="line"><span class="cl">rm -rf /Applications/Rapport.app </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Daten entfernen (optional!)</span> </span></span><span class="line"><span class="cl">rm -rf <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Caches</span> </span></span><span class="line"><span class="cl">rm -rf <span class="s2">&#34;~/Library/Caches/com.rapport.app&#34;</span> </span></span><span class="line"><span class="cl">rm -rf <span class="s2">&#34;~/Library/WebKit/com.rapport.app&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <blockquote> <p><strong>Achtung:</strong> Schritt 2 löscht <strong>alle Rapport-Daten unwiederbringlich</strong>. Vorher Backup machen — siehe <a href="../datenhaltung">Datenhaltung</a>.</p>

</blockquote> <h2>Bekannte Probleme<span class="hx:absolute hx:-mt-20" id="bekannte-probleme"></span> <a href="#bekannte-probleme" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><table> <thead> <tr> <th>Problem</th> <th>Lösung</th> </tr> </thead> <tbody> <tr> <td>App lässt sich nicht öffnen trotz Freigabe</td> <td>Terminal-Variante mit <code>xattr</code></td> </tr> <tr> <td>&ldquo;Rapport is damaged&rdquo;</td> <td>DMG erneut von Gitea ziehen (Browser-Cache hat evtl. Müll)</td> </tr> <tr> <td>Schwarzer Bildschirm beim Start</td> <td><code>~/Library/WebKit/com.rapport.app</code> löschen, neu starten</td> </tr> </tbody> </table> <p>Mehr unter <a href="../troubleshooting">Troubleshooting</a>.</p>

# Einrichtung

/docs/einrichtung/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/einrichtung/

<p>Nach der <a href="../installation">Installation</a>: Bürodaten, Mitarbeiter, Kunden und Projekte initial anlegen.</p> <h2>Reihenfolge<span class="hx:absolute hx:-mt-20" id="reihenfolge"></span> <a href="#reihenfolge" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Die Reihenfolge ist wichtig — jede Stufe baut auf der vorherigen auf:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">1. Bürodaten → 2. Mitarbeiter → 3. Kunden → 4. Projekte </span></span><span class="line"><span class="cl"> ▼ ▼ ▼ ▼ </span></span><span class="line"><span class="cl"> Briefbogen, Zeiterfassung, Adressen, Zeiterfassung, </span></span><span class="line"><span class="cl"> QR-Schein, Lohn Rechnungen Rechnungen </span></span><span class="line"><span class="cl"> Login</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h2>1 · Bürodaten<span class="hx:absolute hx:-mt-20" id="1--bürodaten"></span> <a href="#1--b%c3%bcrodaten" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Einstellungen → Bürodaten</strong></p> <table> <thead> <tr> <th>Feld</th> <th>Beschreibung</th> <th>Verwendung</th> </tr> </thead> <tbody> <tr> <td><strong>Name</strong></td> <td>Bürobezeichnung</td> <td>Briefbogen, Login-Screen</td> </tr> <tr> <td><strong>Adresse</strong></td> <td>Strasse, PLZ, Ort</td> <td>Briefbogen, QR-Rechnung (Empfänger)</td> </tr> <tr> <td><strong>Telefon, E-Mail</strong></td> <td>Kontaktdaten</td> <td>Briefbogen, Rechnung-Footer</td> </tr> <tr> <td><strong>IBAN</strong></td> <td>CH-IBAN (Format <code>CH XX XXXX …</code>)</td> <td><strong>QR-Einzahlungsschein</strong> — Pflicht</td> </tr> <tr> <td><strong>Logo</strong></td> <td>PNG/SVG-Upload</td> <td>Briefbogen, Rechnung, Brief</td> </tr> <tr> <td><strong>MwSt.-Nr.</strong></td> <td>optional</td> <td>Rechnung-Footer</td> </tr> </tbody> </table> <blockquote> <p><strong>Tipp:</strong> Das Logo wird hochauflösend gespeichert (Base64 im localStorage). Bei sehr grossen Dateien (&gt;1 MB) vorher in Vorschau verkleinern.</p>

</blockquote> <h2>2 · Mitarbeiter<span class="hx:absolute hx:-mt-20" id="2--mitarbeiter"></span> <a href="#2--mitarbeiter" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Einstellungen → Mitarbeiter → Neu</strong></p> <table> <thead> <tr> <th>Feld</th> <th>Beschreibung</th> </tr> </thead> <tbody> <tr> <td><strong>Name, Vorname</strong></td> <td>wird in Zeiterfassung &amp; Lohn verwendet</td> </tr> <tr> <td><strong>Initialen</strong></td> <td>Kürzel für Auswertungen (z. B. &ldquo;KGE&rdquo;)</td> </tr> <tr> <td><strong>Eintrittsdatum</strong></td> <td>für <strong>Prorata</strong> der Ferien</td> </tr> <tr> <td><strong>Pensum (%)</strong></td> <td>100 = Vollzeit</td> </tr> <tr> <td><strong>Stundensatz (CHF)</strong></td> <td>für Stundensatz-Rechnungen</td> </tr> <tr> <td><strong>Ferienanspruch (Tage/Jahr)</strong></td> <td>i. d. R. 25–30</td> </tr> <tr> <td><strong>Lohn (brutto, monatlich)</strong></td> <td>optional, für Lohnabrechnung</td> </tr> </tbody> </table> <p>Mindestens <strong>ein Mitarbeiter</strong> (z. B. der Inhaber selbst) muss angelegt sein, sonst lässt sich keine Zeit erfassen.</p> <h3>Sozialabzüge (optional)<span class="hx:absolute hx:-mt-20" id="sozialabzüge-optional"></span> <a href="#sozialabz%c3%bcge-optional" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>In Einstellungen → Lohn:</p> <table> <thead> <tr> <th>Abzug</th> <th>Standardwert (CH)</th> </tr> </thead> <tbody> <tr> <td>AHV / IV / EO</td> <td>5,3 %</td> </tr> <tr> <td>ALV</td> <td>1,1 %</td> </tr> <tr> <td>BVG (Pensionskasse)</td> <td>variabel — je Mitarbeiter</td> </tr> <tr> <td>NBU</td> <td>je nach Versicherung</td> </tr> </tbody> </table> <p>Die Standardsätze sind hinterlegt, können aber überschrieben werden.</p> <h2>3 · Kunden<span class="hx:absolute hx:-mt-20" id="3--kunden"></span> <a href="#3--kunden" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Kunden → Neu</strong></p> <table> <thead> <tr> <th>Feld</th> <th>Beschreibung</th> </tr> </thead> <tbody> <tr> <td><strong>Typ</strong></td> <td>Privatperson / Firma</td> </tr> <tr> <td><strong>Anrede, Name</strong></td> <td>für Brief / Rechnung</td> </tr> <tr> <td><strong>Adresse</strong></td> <td>Strasse, PLZ, Ort, Land</td> </tr> <tr> <td><strong>Ansprechperson</strong></td> <td>bei Firmen</td> </tr> <tr> <td><strong>Telefon, E-Mail</strong></td> <td>Kontakt</td> </tr> <tr> <td><strong>Honorartyp Default</strong></td> <td>Stundensatz / SIA / Pauschal</td> </tr> <tr> <td><strong>Stundensatz</strong></td> <td>falls vom Bürostandard abweichend</td> </tr> <tr> <td><strong>MwSt.-pflichtig</strong></td> <td>ja/nein</td> </tr> </tbody> </table> <h2>4 · Projekte<span class="hx:absolute hx:-mt-20" id="4--projekte"></span> <a href="#4--projekte" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Projekte → Neu</strong></p> <table> <thead> <tr> <th>Feld</th> <th>Beschreibung</th> </tr> </thead> <tbody> <tr> <td><strong>Projekt-Nr.</strong></td> <td>freie Form, oder generiert (<code>2026-001</code>)</td> </tr> <tr> <td><strong>Bezeichnung</strong></td> <td>Kurztitel</td> </tr> <tr> <td><strong>Standort</strong></td> <td>Adresse</td> </tr> <tr> <td><strong>Kunde</strong></td> <td>aus Kundendatenbank</td> </tr> <tr> <td><strong>Bauschätzwert</strong></td> <td>für SIA-Phasen-Honorar</td> </tr> <tr> <td><strong>SIA-Phasen</strong></td> <td>Vorprojekt / Bauprojekt / … — alle anwählbar</td> </tr> <tr> <td><strong>Honorartyp</strong></td> <td>Stundensatz / SIA 102 / Pauschal</td> </tr> <tr> <td><strong>Status</strong></td> <td>aktiv / pausiert / abgeschlossen</td> </tr> </tbody> </table> <h3>SIA-102-Phasen<span class="hx:absolute hx:-mt-20" id="sia-102-phasen"></span> <a href="#sia-102-phasen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>Wenn als Honorartyp <strong>SIA 102</strong> gewählt ist, werden die Phasen-Anteile am Gesamthonorar vorgeschlagen — siehe <a href="../../features/projekte#sia-102">Projekt-Feature</a>.</p> <h2>Checkliste<span class="hx:absolute hx:-mt-20" id="checkliste"></span> <a href="#checkliste" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Nach diesen vier Schritten ist Rapport einsatzbereit:</p> <ul> <li><input disabled="" type="checkbox"> Bürodaten inkl. IBAN erfasst</li> <li><input disabled="" type="checkbox"> Mindestens ein Mitarbeiter angelegt</li> <li><input disabled="" type="checkbox"> Erster Kunde angelegt</li> <li><input disabled="" type="checkbox"> Erstes Projekt angelegt</li> <li><input disabled="" type="checkbox"> Eine Test-Zeitbuchung erfasst — wird das Projekt korrekt zugewiesen?</li> <li><input disabled="" type="checkbox"> Eine Test-Rechnung erstellt — kommt der QR-Schein sauber raus?</li> </ul> <p>Wenn alles funktioniert: <a href="../arbeitsablauf">Typischer Arbeitsablauf</a>.</p>

# Typischer Arbeitsablauf

/docs/arbeitsablauf/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/arbeitsablauf/

<p>Vom Erstkontakt mit dem Kunden bis zur Schlussrechnung — der typische Weg eines Projekts durch Rapport.</p> <h2>Übersicht<span class="hx:absolute hx:-mt-20" id="übersicht"></span> <a href="#%c3%bcbersicht" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl"> Kunde → Offerte → Projekt → Zeit → Akonto → Schluss </span></span><span class="line"><span class="cl"> anlegen erstellen (aus Offerte) erfassen -Rechnung -Rechnung </span></span><span class="line"><span class="cl"> ↓ </span></span><span class="line"><span class="cl"> QR-Schein</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h2>1 · Kunde anlegen<span class="hx:absolute hx:-mt-20" id="1--kunde-anlegen"></span> <a href="#1--kunde-anlegen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Kunden → Neu</strong> — siehe <a href="../einrichtung#3--kunden">Einrichtung § 3</a>.</p> <p>Falls der Kunde später bestellt, lassen sich alle gesammelten Daten (Adresse, Honorartyp) direkt übernehmen.</p> <h2>2 · Offerte erstellen<span class="hx:absolute hx:-mt-20" id="2--offerte-erstellen"></span> <a href="#2--offerte-erstellen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Offerten → Neu</strong></p> <table> <thead> <tr> <th>Feld</th> <th>Inhalt</th> </tr> </thead> <tbody> <tr> <td><strong>Kunde</strong></td> <td>aus Kundendatenbank wählen</td> </tr> <tr> <td><strong>Bezeichnung</strong></td> <td>Projekttitel (z. B. &ldquo;Einfamilienhaus Müller, Bern&rdquo;)</td> </tr> <tr> <td><strong>Honorartyp</strong></td> <td>Stundensatz / SIA 102 / Pauschal</td> </tr> <tr> <td><strong>Bauschätzwert</strong></td> <td>bei SIA — Bruttowert in CHF</td> </tr> <tr> <td><strong>Phasen</strong></td> <td>bei SIA — anzuklickende Phasen</td> </tr> <tr> <td><strong>Positionen</strong></td> <td>bei Stundensatz/Pauschal — Position, Beschreibung, Betrag</td> </tr> </tbody> </table> <p>Mit <em>PDF exportieren</em> — fertige Offerte für den Kunden.</p> <h3>Offerten-Status<span class="hx:absolute hx:-mt-20" id="offerten-status"></span> <a href="#offerten-status" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><table> <thead> <tr> <th>Status</th> <th>Bedeutung</th> </tr> </thead> <tbody> <tr> <td><strong>Entwurf</strong></td> <td>noch nicht versandt</td> </tr> <tr> <td><strong>Versandt</strong></td> <td>beim Kunden, wartet auf Antwort</td> </tr> <tr> <td><strong>Angenommen</strong></td> <td>Kunde hat zugesagt — bereit zur Konvertierung</td> </tr> <tr> <td><strong>Abgelehnt</strong></td> <td>Kunde hat abgelehnt — Archiv</td> </tr> </tbody> </table> <h2>3 · Offerte → Projekt<span class="hx:absolute hx:-mt-20" id="3--offerte--projekt"></span> <a href="#3--offerte--projekt" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Bei Status <strong>&ldquo;Angenommen&rdquo;</strong>: Knopf <strong>&ldquo;In Projekt konvertieren&rdquo;</strong>.</p> <p>Das erzeugt:</p> <ul> <li>Ein neues Projekt mit den Daten der Offerte (Kunde, Bezeichnung, Honorar, Phasen)</li> <li>Eine Verknüpfung zwischen Offerte und Projekt</li> <li>Die Offerte selbst bleibt im Archiv erhalten</li> </ul> <p>Siehe auch <a href="../../features/projekte">Projekt-Feature</a>.</p> <h2>4 · Zeit erfassen<span class="hx:absolute hx:-mt-20" id="4--zeit-erfassen"></span> <a href="#4--zeit-erfassen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Zeit → Mitarbeiter wählen → Woche navigieren</strong></p> <ul> <li><strong>Klick</strong> auf einen Halbstunden-Slot → Eintrag erstellen</li> <li><strong>Drag</strong> über mehrere Slots → längerer Eintrag</li> <li><strong>Projekt zuweisen</strong> (Pflichtfeld) — aus aktiven Projekten</li> <li><strong>SIA-Phase</strong> zuweisen (optional, für detaillierte Auswertung)</li> </ul> <h3>Spezialfälle<span class="hx:absolute hx:-mt-20" id="spezialfälle"></span> <a href="#spezialf%c3%a4lle" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><ul> <li><strong>Ferien</strong> — eigener &ldquo;Projekt&rdquo;-Typ &ldquo;Ferien&rdquo;, in der Auswertung separat</li> <li><strong>Krankheit/Absenz</strong> — eigener &ldquo;Projekt&rdquo;-Typ, ebenfalls separat</li> <li><strong>Interne Stunden</strong> — z. B. Verwaltung, Marketing, IT — eigene interne Projekte</li> </ul> <h2>5 · Akonto-Rechnung<span class="hx:absolute hx:-mt-20" id="5--akonto-rechnung"></span> <a href="#5--akonto-rechnung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Während der Projektlaufzeit — typisch nach jeder abgeschlossenen SIA-Phase oder monatlich.</p> <p><strong>Rechnungen → Neu → Akonto</strong></p> <table> <thead> <tr> <th>Feld</th> <th>Inhalt</th> </tr> </thead> <tbody> <tr> <td><strong>Projekt</strong></td> <td>aus aktiven Projekten</td> </tr> <tr> <td><strong>Bezug</strong></td> <td>&ldquo;Akonto für Phase 31 — Vorprojekt&rdquo;</td> </tr> <tr> <td><strong>Betrag</strong></td> <td>Stundensatz × Stunden, oder Phasenanteil × Bausumme</td> </tr> <tr> <td><strong>Fälligkeit</strong></td> <td>i. d. R. 30 Tage</td> </tr> </tbody> </table> <p>Rapport zieht automatisch die geleisteten Stunden aus der Zeiterfassung — die kannst du als Basis nehmen oder überschreiben.</p> <p>PDF inkl. <strong>QR-Einzahlungsschein</strong> — siehe <a href="../../features/rechnungen">Rechnungen-Feature</a>.</p> <h2>6 · Schlussrechnung<span class="hx:absolute hx:-mt-20" id="6--schlussrechnung"></span> <a href="#6--schlussrechnung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Nach Projektabschluss — Differenz aus Gesamthonorar minus aller Akonto-Beträge.</p> <p><strong>Rechnungen → Neu → Schlussrechnung</strong></p> <p>Rapport rechnet die bisherigen Akonto-Rechnungen automatisch ab:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Gesamthonorar (SIA / Pauschal / Stundensatz) </span></span><span class="line"><span class="cl"> − Akonto-Rechnung 1 </span></span><span class="line"><span class="cl"> − Akonto-Rechnung 2 </span></span><span class="line"><span class="cl"> − Akonto-Rechnung 3 </span></span><span class="line"><span class="cl"> = Schlussrechnung</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h2>7 · Projektabschluss<span class="hx:absolute hx:-mt-20" id="7--projektabschluss"></span> <a href="#7--projektabschluss" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Im Projekt → Status auf <strong>&ldquo;Abgeschlossen&rdquo;</strong>.</p> <p>Das Projekt bleibt für historische Auswertungen sichtbar, taucht aber nicht mehr in der Zeiterfassungs-Auswahl auf.</p> <h2>Auswertungen<span class="hx:absolute hx:-mt-20" id="auswertungen"></span> <a href="#auswertungen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Wöchentlich / monatlich / am Jahresende:</p> <ul> <li><strong>Zeit → Auswertungen</strong> — Stunden pro Mitarbeiter, pro Projekt, pro Phase</li> <li><strong>Rechnungen → Übersicht</strong> — offene Beträge, bezahlt, Mahnungen</li> <li><strong>Buchhaltung → Erfolgsrechnung</strong> — Einnahmen vs. Ausgaben</li> <li><strong>Mitarbeiter → Lohnabrechnung</strong> — monatlich</li> </ul> <h2>Tipps aus dem Alltag<span class="hx:absolute hx:-mt-20" id="tipps-aus-dem-alltag"></span> <a href="#tipps-aus-dem-alltag" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><ul> <li><strong>Zeit jeden Tag erfassen</strong> statt rückwirkend — sonst gehen Details verloren</li> <li><strong>Akonto regelmässig</strong> statt einmal am Schluss — Liquidität</li> <li><strong>Backups</strong> vor Jahresabschluss — siehe <a href="../datenhaltung">Datenhaltung</a></li> <li><strong>Briefbogen-Logo</strong> in hoher Auflösung — sieht im PDF besser aus</li> </ul>

# Datenhaltung & Backup

/docs/datenhaltung/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/datenhaltung/

<p>Wo Rapport seine Daten speichert, wie du sie sicherst und wiederherstellst.</p> <blockquote> <p><strong>Diese Seite beschreibt die Desktop-App (Single-User).</strong> Wer im Team arbeitet und Rapport gegen einen <a href="../../server/">Rapport Server</a> betreibt, sichert stattdessen die Postgres-Datenbank — siehe <a href="../../server/#backup">Rapport Server § Backup</a>.</p>

</blockquote> <h2>Speicherort (Desktop-App)<span class="hx:absolute hx:-mt-20" id="speicherort-desktop-app"></span> <a href="#speicherort-desktop-app" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Die Desktop-App speichert <strong>alles lokal</strong> — keine Cloud, kein Server.</p> <h3>macOS<span class="hx:absolute hx:-mt-20" id="macos"></span> <a href="#macos" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">~/Library/Application Support/com.rapport.app/</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>Dort liegt eine einzelne <strong><code>localStorage</code></strong>-Datenbank des WebView, in der <strong>alle</strong> Rapport-Daten als JSON unter dem Key <code>studio_data_v1</code> gespeichert sind:</p> <ul> <li>Bürodaten, Logo, IBAN</li> <li>Mitarbeiter, Kunden, Projekte, Offerten</li> <li>Zeit-Einträge, Rechnungen</li> <li>Spesen, Lohnabrechnungen, Protokolle</li> <li>App-Einstellungen</li> </ul> <blockquote> <p><strong>Konsequenz:</strong> Wer den Application-Support-Ordner kopiert, hat ein vollständiges Backup. Wer ihn löscht, verliert alle Daten.</p>

</blockquote> <h3>Warum localStorage?<span class="hx:absolute hx:-mt-20" id="warum-localstorage"></span> <a href="#warum-localstorage" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>In der Desktop-App ist Rapport eine <strong>Single-User-Anwendung</strong>. localStorage ist dafür:</p> <ul> <li><strong>Schnell</strong> — keine Datenbank-Roundtrips</li> <li><strong>Einfach</strong> — keine Migration nötig, JSON-Schema im Code</li> <li><strong>Portabel</strong> — eine Datei → ein Backup</li> </ul> <p>Für <strong>Multi-User-Betrieb</strong> existiert <a href="../../server/">Rapport Server</a> — Postgres + Auth + Realtime in einem Docker-Compose. Wechsel zwischen Desktop- und Server-Modus erfolgt im Login-Bildschirm der App.</p> <h2>Backup-Strategien<span class="hx:absolute hx:-mt-20" id="backup-strategien"></span> <a href="#backup-strategien" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>A · Einfach (manuell)<span class="hx:absolute hx:-mt-20" id="a--einfach-manuell"></span> <a href="#a--einfach-manuell" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>Den ganzen Ordner kopieren:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp -R <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"> <span class="s2">&#34;~/Documents/Rapport-Backup-</span><span class="k">$(</span>date +%Y%m%d<span class="k">)</span><span class="s2">&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>→ Auf USB-Stick, externen Datenträger oder in die Cloud.</p> <h3>B · Time Machine<span class="hx:absolute hx:-mt-20" id="b--time-machine"></span> <a href="#b--time-machine" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>Wenn Time Machine läuft, ist der Ordner automatisch dabei. Versionierung inbegriffen.</p> <blockquote> <p><strong>Einschränkung:</strong> Time Machine sichert nur lokal/USB. Für off-site-Backup separat sorgen.</p>

</blockquote> <h3>C · Cron-Job (täglich automatisch)<span class="hx:absolute hx:-mt-20" id="c--cron-job-täglich-automatisch"></span> <a href="#c--cron-job-t%c3%a4glich-automatisch" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># In ~/Library/LaunchAgents/com.rapport.backup.plist hinterlegen</span> </span></span><span class="line"><span class="cl"><span class="c1"># oder als crontab-Eintrag:</span> </span></span><span class="line"><span class="cl"><span class="m">0</span> <span class="m">22</span> * * * rsync -a <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/Library/Application Support/com.rapport.app/&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/Backups/rapport/</span><span class="k">$(</span>date +<span class="se">\%</span>Y<span class="se">\%</span>m<span class="se">\%</span>d<span class="k">)</span><span class="s2">/&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h3>D · iCloud Drive (off-site)<span class="hx:absolute hx:-mt-20" id="d--icloud-drive-off-site"></span> <a href="#d--icloud-drive-off-site" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>Application-Support liegt <strong>nicht</strong> automatisch in iCloud. Wer das will:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Symlink anlegen</span> </span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;~/iCloud Drive/Rapport&#34;</span> </span></span><span class="line"><span class="cl">ln -s <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span> <span class="s2">&#34;~/iCloud Drive/Rapport/data&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <blockquote> <p><strong>Achtung:</strong> iCloud-Sync mit aktiver App kann zu <strong>Race-Conditions</strong> führen. Besser den Sync zeitversetzt (z. B. nachts via Cron).</p>

</blockquote> <h2>Wiederherstellung<span class="hx:absolute hx:-mt-20" id="wiederherstellung"></span> <a href="#wiederherstellung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>Vollständig (Rapport komplett tot)<span class="hx:absolute hx:-mt-20" id="vollständig-rapport-komplett-tot"></span> <a href="#vollst%c3%a4ndig-rapport-komplett-tot" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><ol> <li>Rapport beenden (Cmd+Q, nicht nur Fenster zu)</li> <li>Aktuellen Ordner umbenennen (falls noch da): <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mv <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"> <span class="s2">&#34;~/Library/Application Support/com.rapport.app.bak&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> </li> <li>Backup-Ordner zurück kopieren: <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp -R <span class="s2">&#34;~/Documents/Rapport-Backup-20260523&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"> <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> </li> <li>Rapport starten</li> </ol> <h3>Selektiv (nur einzelne Daten)<span class="hx:absolute hx:-mt-20" id="selektiv-nur-einzelne-daten"></span> <a href="#selektiv-nur-einzelne-daten" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>Da alle Daten in <strong>einem JSON unter <code>studio_data_v1</code></strong> liegen, ist selektive Wiederherstellung <strong>manuell</strong>:</p> <ol> <li>Backup-<code>localStorage</code>-Datei öffnen (WebKit-Format → mit Tool wie [WebKit Storage Inspector] lesen, oder via Rapport DevTools)</li> <li>Gewünschte Felder in die aktuelle Instanz übertragen</li> </ol> <p>In der Praxis: meistens lohnt sich die <strong>vollständige</strong> Wiederherstellung mehr.</p> <h2>Export-Funktionen (in der App)<span class="hx:absolute hx:-mt-20" id="export-funktionen-in-der-app"></span> <a href="#export-funktionen-in-der-app" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Aus Rapport selbst:</p> <table> <thead> <tr> <th>Was</th> <th>Wo</th> <th>Format</th> </tr> </thead> <tbody> <tr> <td><strong>Zeit-Auswertung</strong></td> <td>Zeit → Export</td> <td>CSV</td> </tr> <tr> <td><strong>Rechnung</strong></td> <td>Rechnung → PDF</td> <td>PDF (inkl. QR)</td> </tr> <tr> <td><strong>Offerte</strong></td> <td>Offerte → PDF</td> <td>PDF</td> </tr> <tr> <td><strong>Lohnabrechnung</strong></td> <td>Mitarbeiter → PDF</td> <td>PDF</td> </tr> <tr> <td><strong>Jahres-Buchhaltung</strong></td> <td>Buchhaltung → Export</td> <td>CSV</td> </tr> </tbody> </table> <p>Die Exports sind für externe Verwendung (Buchhalter, Treuhänder, Archiv) gedacht — kein Full-Backup.</p> <h2>Schema-Migrationen<span class="hx:absolute hx:-mt-20" id="schema-migrationen"></span> <a href="#schema-migrationen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Bei Updates kann sich das Datenformat ändern. Rapport hat einen <strong>Migrations-Mechanismus</strong>: beim Start prüft die App, ob das gespeicherte Format dem aktuellen entspricht, und migriert es automatisch.</p> <p>Code: <a href="https://git.kgva.ch/karim/RAPPORT/src/branch/main/APP/src/storage/migrations.js"target="_blank" rel="noopener">src/storage/migrations.js<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p> <blockquote> <p><strong>Empfehlung:</strong> Vor jedem grösseren Update ein Backup machen — Migrationen sind getestet, aber 100%-Sicherheit gibt es nicht.</p>

</blockquote> <h2>Was wird <strong>nicht</strong> gespeichert?<span class="hx:absolute hx:-mt-20" id="was-wird-nicht-gespeichert"></span> <a href="#was-wird-nicht-gespeichert" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><ul> <li><strong>WebView-Cache</strong> — <code>~/Library/Caches/com.rapport.app/</code> und <code>~/Library/WebKit/com.rapport.app/</code> sind sicher zu löschen (UI-Caches, regenerieren sich)</li> <li><strong>App-Updates</strong> — werden bei Bedarf erneut runtergeladen</li> <li><strong>Logs</strong> — <code>~/Library/Logs/com.rapport.app/</code> (geplant, derzeit nicht geschrieben)</li> </ul> <h2>Datenmenge<span class="hx:absolute hx:-mt-20" id="datenmenge"></span> <a href="#datenmenge" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Typische Grössen pro Bürojahr:</p> <table> <thead> <tr> <th>Inhalt</th> <th>Grösse</th> </tr> </thead> <tbody> <tr> <td>Logo (PNG/SVG)</td> <td>50 KB – 1 MB</td> </tr> <tr> <td>1 Jahr Zeiterfassung (1 MA)</td> <td>~ 80 KB</td> </tr> <tr> <td>1 Jahr Zeiterfassung (5 MA)</td> <td>~ 400 KB</td> </tr> <tr> <td>50 Projekte mit je 5 Rechnungen</td> <td>~ 800 KB</td> </tr> <tr> <td><strong>Total typisches Solo-Büro / Jahr</strong></td> <td><strong>~ 1–2 MB</strong></td> </tr> </tbody> </table> <p>localStorage hat Limits (i. d. R. ~10 MB pro Origin). Für Solo-Büros reicht das problemlos für viele Jahre. Wer das Limit erreicht oder im Team arbeitet → <a href="../../server/">Rapport Server</a>.</p>

# Web-Modus (Multi-User)

/docs/web-modus/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/web-modus/

<blockquote> <p><strong>Hinweis:</strong> Der frühere Supabase-basierte Web-Modus wurde durch <strong><a href="../../server/">Rapport Server</a></strong> abgelöst — den vollständigen Selfhost-Stack mit eigenem Postgres, Auth, Realtime und Storage. Keine externe Cloud-Abhängigkeit mehr.</p> <p>Diese Seite bleibt als Referenz erhalten, der <strong>empfohlene Weg</strong> für Multi-User-Setups ist <strong><a href="../../server/">Rapport Server</a></strong>.</p>

</blockquote> <h2>Wann brauchst du das?<span class="hx:absolute hx:-mt-20" id="wann-brauchst-du-das"></span> <a href="#wann-brauchst-du-das" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><table> <thead> <tr> <th>Anwendungsfall</th> <th>Empfehlung</th> </tr> </thead> <tbody> <tr> <td><strong>Solo-Büro, ein Mac</strong></td> <td>Desktop-App — siehe <a href="../installation">Installation</a></td> </tr> <tr> <td><strong>2–5 Personen, gleicher Standort</strong></td> <td><a href="../../server/">Rapport Server</a> auf einem Mac Mini im LAN</td> </tr> <tr> <td><strong>Verteiltes Team / Home-Office</strong></td> <td><a href="../../server/">Rapport Server</a> mit SSL + Reverse Proxy</td> </tr> <tr> <td><strong>Hosted Backend (eigener VPS)</strong></td> <td><a href="../../server/">Rapport Server</a> auf Linux-VPS</td> </tr> </tbody> </table> <h2>Architektur (Kurzfassung)<span class="hx:absolute hx:-mt-20" id="architektur-kurzfassung"></span> <a href="#architektur-kurzfassung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">┌────────────┐ HTTPS ┌──────────────┐ SQL ┌────────────┐ </span></span><span class="line"><span class="cl">│ Browser │ ──────────────│ nginx │ ─────────────│ Postgres │ </span></span><span class="line"><span class="cl">│ / Desktop │ │ (Frontend) │ │ + GoTrue │ </span></span><span class="line"><span class="cl">└────────────┘ └──────────────┘ │ + REST │ </span></span><span class="line"><span class="cl"> │ + Realtime │ </span></span><span class="line"><span class="cl"> │ + Storage │ </span></span><span class="line"><span class="cl"> └────────────┘</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <ul> <li><strong>Frontend:</strong> dieselbe React-App, aber Vite-Build statt Tauri (<code>npm run build</code>)</li> <li><strong>Backend:</strong> Postgres-Stack (<a href="../../server/">Rapport Server</a>)</li> <li><strong>Auth:</strong> E-Mail / Passwort über GoTrue</li> <li><strong>Storage:</strong> Belege, Logos in Object-Storage</li> </ul> <h2>Setup<span class="hx:absolute hx:-mt-20" id="setup"></span> <a href="#setup" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Alle Setup-Schritte (Repo klonen, <code>.env</code> erstellen, Migrations syncen, Docker-Compose starten, Reverse-Proxy konfigurieren) sind in <strong><a href="../../server/">Rapport Server</a></strong> dokumentiert.</p> <h2>Migration Desktop → Cloud<span class="hx:absolute hx:-mt-20" id="migration-desktop--cloud"></span> <a href="#migration-desktop--cloud" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Wer mit der Desktop-App startet und später auf den Web-Modus wechseln möchte:</p> <ul> <li><strong>Aktuell:</strong> manueller Export aus Rapport (CSV/PDF) und manuelles Wiederanlegen im neuen Setup</li> <li><strong>Geplant:</strong> <em>&ldquo;localStorage → Postgres&rdquo;</em>-Import-Knopf direkt in der App</li> </ul> <p>Status: <a href="https://git.kgva.ch/karim/RAPPORT/issues"target="_blank" rel="noopener">Issue auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p> <h2>Troubleshooting<span class="hx:absolute hx:-mt-20" id="troubleshooting"></span> <a href="#troubleshooting" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Siehe <a href="../../server/">Rapport Server § Troubleshooting</a> oder <a href="../troubleshooting">allgemeine Troubleshooting-Seite</a>.</p>

# Entwicklung & Build

/docs/entwicklung/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/entwicklung/

<p>Aus dem Quellcode kompilieren, beitragen, eigenes Release erzeugen.</p> <h2>Voraussetzungen<span class="hx:absolute hx:-mt-20" id="voraussetzungen"></span> <a href="#voraussetzungen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><table> <thead> <tr> <th>Tool</th> <th>Version</th> </tr> </thead> <tbody> <tr> <td><strong>Node.js</strong></td> <td>≥ 20 (für Vite 8)</td> </tr> <tr> <td><strong>npm</strong></td> <td>≥ 10</td> </tr> <tr> <td><strong>Rust toolchain</strong></td> <td>≥ 1.77.2 (via <code>rustup</code>)</td> </tr> <tr> <td><strong>Plattform-Tools</strong></td> <td>siehe <a href="https://v2.tauri.app/start/prerequisites/"target="_blank" rel="noopener">Tauri Prerequisites<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a></td> </tr> </tbody> </table> <p>Plattform-spezifisch:</p> <ul> <li><strong>macOS:</strong> Xcode Command Line Tools (<code>xcode-select --install</code>)</li> <li><strong>Windows:</strong> Microsoft C++ Build Tools + WebView2</li> <li><strong>Linux:</strong> <code>webkit2gtk-4.1</code>, <code>librsvg2-dev</code>, <code>libayatana-appindicator3-dev</code>, <code>build-essential</code></li> </ul> <h2>Setup<span class="hx:absolute hx:-mt-20" id="setup"></span> <a href="#setup" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://git.kgva.ch/karim/RAPPORT.git </span></span><span class="line"><span class="cl"><span class="nb">cd</span> RAPPORT/APP </span></span><span class="line"><span class="cl">npm install</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h2>Entwicklung<span class="hx:absolute hx:-mt-20" id="entwicklung"></span> <a href="#entwicklung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>Web-Modus (HMR, schnellster Loop)<span class="hx:absolute hx:-mt-20" id="web-modus-hmr-schnellster-loop"></span> <a href="#web-modus-hmr-schnellster-loop" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm run dev <span class="c1"># http://localhost:3000</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <ul> <li>Hot-Module-Replacement</li> <li>Schnellster Iteration-Loop für UI-Arbeit</li> <li>Datenpersistierung: Browser-localStorage</li> </ul> <h3>Native Window (Tauri-Fenster mit Desktop-Integration)<span class="hx:absolute hx:-mt-20" id="native-window-tauri-fenster-mit-desktop-integration"></span> <a href="#native-window-tauri-fenster-mit-desktop-integration" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx tauri dev</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <ul> <li>Echtes Tauri-Fenster</li> <li>System-Tray, Updater, native APIs verfügbar</li> <li>Erster Start dauert lange (Rust-Compile)</li> </ul> <h2>Architektur in einem Absatz<span class="hx:absolute hx:-mt-20" id="architektur-in-einem-absatz"></span> <a href="#architektur-in-einem-absatz" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><blockquote> <p>RAPPORT ist eine monolithische SPA: ein React-Root in <a href="https://git.kgva.ch/karim/RAPPORT/src/branch/main/APP/src/App.jsx"target="_blank" rel="noopener">App.jsx<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> hält den <strong>gesamten</strong> App-State in einem <code>useState({...})</code>, persistiert ihn synchron in <code>localStorage</code> unter <code>studio_data_v1</code>, und übergibt ihn als Props an lazy-geladene Views. <strong>Kein Routing-Framework</strong>, <strong>kein State-Library</strong>, <strong>kein TypeScript</strong>, <strong>kein CSS-Framework</strong>. Der <strong>Rust-Teil</strong> ist 109 Zeilen und macht nur drei Dinge: System-Tray, Window-Hide-on-Close, Plugin-Registrierung (Updater, Process, Log). <strong>Keine</strong> <code>#[tauri::command]</code> — Frontend ↔ Backend kommuniziert nur über das Event <code>rapport:navigate</code> (Tray → Frontend).</p>

</blockquote> <p>Detaillierte Karte: <a href="https://git.kgva.ch/karim/RAPPORT/src/branch/main/APP/ARCHITECTURE.md"target="_blank" rel="noopener">ARCHITECTURE.md<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p> <h2>Verzeichnis-Karte<span class="hx:absolute hx:-mt-20" id="verzeichnis-karte"></span> <a href="#verzeichnis-karte" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">APP/ </span></span><span class="line"><span class="cl">├── src/ React 19 (kein TS, nur .jsx) </span></span><span class="line"><span class="cl">│ ├── App.jsx Root: State, Navigation, Sidebar, Modals </span></span><span class="line"><span class="cl">│ ├── constants.js STORAGE_KEY, NAV_ITEMS, defaultData, SIA-Phasen </span></span><span class="line"><span class="cl">│ ├── utils.js Business-Logik: Kalkulation, QR-Bill, CSV, Lohn </span></span><span class="line"><span class="cl">│ ├── storage/adapter.js LocalStorageAdapter (Phase 1), SupabaseAdapter (Phase 2) </span></span><span class="line"><span class="cl">│ ├── storage/migrations.js Schema-Migrationen </span></span><span class="line"><span class="cl">│ ├── views/ 20 Top-Level-Screens, lazy-geladen </span></span><span class="line"><span class="cl">│ ├── components/UI.jsx StatusBadge, Modal, FormField, … </span></span><span class="line"><span class="cl">│ ├── components/Update* Auto-Update-UI </span></span><span class="line"><span class="cl">│ ├── print/ PrintComponents.jsx — alle Druckansichten </span></span><span class="line"><span class="cl">│ └── utils/updater.js @tauri-apps/plugin-updater Wrapper </span></span><span class="line"><span class="cl">│ </span></span><span class="line"><span class="cl">├── supabase/migrations/ Postgres-Schema für Cloud-Variante </span></span><span class="line"><span class="cl">│ </span></span><span class="line"><span class="cl">├── src-tauri/ Rust-Backend (Tauri 2.10.3) </span></span><span class="line"><span class="cl">│ ├── src/lib.rs ~103 Z. — Tray, Window-Events, Plugins </span></span><span class="line"><span class="cl">│ ├── tauri.conf.json Updater-URL, Public-Key, CSP, Bundle-Targets </span></span><span class="line"><span class="cl">│ └── capabilities/ Tauri Permissions </span></span><span class="line"><span class="cl">│ </span></span><span class="line"><span class="cl">├── scripts/release.sh Build + Sign + latest.json erzeugen </span></span><span class="line"><span class="cl">├── latest.json Updater-Manifest </span></span><span class="line"><span class="cl">└── deploy/ Docker-Compose für Web-Modus</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h2>Konventionen<span class="hx:absolute hx:-mt-20" id="konventionen"></span> <a href="#konventionen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><ul> <li><strong>JavaScript</strong> statt TypeScript — bewusste Entscheidung für Solo-Dev-Velocity</li> <li><strong>Inline-Styles</strong> statt CSS-Framework</li> <li><strong>kein Routing-Framework</strong> — <code>view</code>-State in App.jsx triggert Komponente</li> <li><strong>JSON-Schema implizit</strong> — definiert durch <code>defaultData</code> in <code>constants.js</code></li> <li><strong>Migrationen</strong> als reine Funktionen in <a href="https://git.kgva.ch/karim/RAPPORT/src/branch/main/APP/src/storage/migrations.js"target="_blank" rel="noopener">storage/migrations.js<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a></li> </ul> <h2>Build<span class="hx:absolute hx:-mt-20" id="build"></span> <a href="#build" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>Desktop (Tauri DMG)<span class="hx:absolute hx:-mt-20" id="desktop-tauri-dmg"></span> <a href="#desktop-tauri-dmg" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm run build <span class="c1"># erst Vite-Build (dist/)</span> </span></span><span class="line"><span class="cl">npx tauri build <span class="c1"># dann Tauri-Bundle (DMG)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>Output: <code>src-tauri/target/release/bundle/dmg/Rapport_&lt;version&gt;_aarch64.dmg</code></p> <h3>Web (statisches Bundle)<span class="hx:absolute hx:-mt-20" id="web-statisches-bundle"></span> <a href="#web-statisches-bundle" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm run build <span class="c1"># Output: dist/ (~500 KB)</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>Für Hosting auf einem Static-Server (z. B. Nginx, Caddy, GitHub Pages). Siehe <a href="../web-modus">Web-Modus</a>.</p> <h2>Release-Workflow<span class="hx:absolute hx:-mt-20" id="release-workflow"></span> <a href="#release-workflow" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 1 · Version bumpen in package.json + Cargo.toml + tauri.conf.json</span> </span></span><span class="line"><span class="cl">./scripts/release.sh 0.7.1 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 2 · Build mit Signatur</span> </span></span><span class="line"><span class="cl"><span class="nv">TAURI_SIGNING_PRIVATE_KEY</span><span class="o">=</span><span class="k">$(</span>cat ~/.tauri/rapport-key<span class="k">)</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="nv">TAURI_SIGNING_PRIVATE_KEY_PASSWORD</span><span class="o">=</span>… <span class="se">\ </span></span></span><span class="line"><span class="cl">npx tauri build </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 3 · latest.json aktualisieren mit neuer Signatur</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 4 · DMG + latest.json auf Gitea Releases hochladen</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h2>Beitragen<span class="hx:absolute hx:-mt-20" id="beitragen"></span> <a href="#beitragen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><a href="https://git.kgva.ch/karim/RAPPORT"target="_blank" rel="noopener">Issues &amp; Pull Requests<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> sind willkommen. Wertvoll sind:</p> <ul> <li><strong>Bug-Reports</strong> mit Reproduktionsschritten</li> <li><strong>Workflow-Verbesserungen</strong> aus dem realen Büroalltag</li> <li><strong>Vorlagen</strong> (Briefe, Protokolle, Lieferscheine) für andere Büros</li> <li><strong>Übersetzungen / Internationalisierung</strong> (FR, IT)</li> <li><strong>Linux-/Windows-Builds</strong> und plattformspezifische Fixes</li> </ul> <p>Vor grösseren Änderungen → Issue zum Diskutieren.</p> <h2>Lizenz<span class="hx:absolute hx:-mt-20" id="lizenz"></span> <a href="#lizenz" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>GNU AGPL-3.0-or-later</strong> — eigene Builds erlaubt, Modifikationen müssen unter derselben Lizenz veröffentlicht werden, wenn die Software als Service angeboten wird.</p>

# Troubleshooting

/docs/troubleshooting/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/troubleshooting/

<p>Typische Probleme und Lösungen. Wenn dein Problem nicht dabei ist → <a href="https://git.kgva.ch/karim/RAPPORT/issues"target="_blank" rel="noopener">Issue auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p> <h2>App startet nicht<span class="hx:absolute hx:-mt-20" id="app-startet-nicht"></span> <a href="#app-startet-nicht" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>&ldquo;Rapport ist beschädigt&rdquo; beim ersten Start<span class="hx:absolute hx:-mt-20" id="rapport-ist-beschädigt-beim-ersten-start"></span> <a href="#rapport-ist-besch%c3%a4digt-beim-ersten-start" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> macOS Gatekeeper blockt unsignierte/nicht-notarisierte Apps.</p> <p><strong>Lösung:</strong> siehe <a href="../installation#3--erster-start-macos-gatekeeper">Installation § 3</a>. Kurz:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xattr -d com.apple.quarantine /Applications/Rapport.app</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <h3>App startet, zeigt aber schwarzen Bildschirm<span class="hx:absolute hx:-mt-20" id="app-startet-zeigt-aber-schwarzen-bildschirm"></span> <a href="#app-startet-zeigt-aber-schwarzen-bildschirm" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> WebView-Cache korrupt.</p> <p><strong>Lösung:</strong></p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">rm -rf <span class="s2">&#34;~/Library/Caches/com.rapport.app&#34;</span> </span></span><span class="line"><span class="cl">rm -rf <span class="s2">&#34;~/Library/WebKit/com.rapport.app&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>App neu starten. Daten gehen dabei <strong>nicht</strong> verloren (liegen in <code>Application Support</code>, nicht im Cache).</p> <h3>App stürzt sofort beim Start ab<span class="hx:absolute hx:-mt-20" id="app-stürzt-sofort-beim-start-ab"></span> <a href="#app-st%c3%bcrzt-sofort-beim-start-ab" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> wahrscheinlich beschädigte JSON-Daten in <code>studio_data_v1</code>.</p> <p><strong>Diagnose:</strong></p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Daten ansehen (DevTools-Output)</span> </span></span><span class="line"><span class="cl">open <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p><strong>Lösung:</strong></p> <ol> <li>Backup wiederherstellen (siehe <a href="../datenhaltung#wiederherstellung">Datenhaltung</a>)</li> <li><strong>Oder</strong> als letzter Ausweg: Daten zurücksetzen <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mv <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"> <span class="s2">&#34;~/Library/Application Support/com.rapport.app.bad&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> App neu starten → erstellt frische Daten. Anschliessend Setup-Screen.</li> </ol> <h2>Daten weg<span class="hx:absolute hx:-mt-20" id="daten-weg"></span> <a href="#daten-weg" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>Nach einem App-Update fehlen Einträge<span class="hx:absolute hx:-mt-20" id="nach-einem-app-update-fehlen-einträge"></span> <a href="#nach-einem-app-update-fehlen-eintr%c3%a4ge" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> mögliche fehlgeschlagene Migration.</p> <p><strong>Sofortmassnahme:</strong></p> <ol> <li>Rapport <strong>beenden</strong> (Cmd+Q, nicht nur Fenster zu)</li> <li><strong>Aktuelles Datenverzeichnis sichern</strong>: <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp -R <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"> <span class="s2">&#34;~/Documents/Rapport-Notfall-</span><span class="k">$(</span>date +%Y%m%d-%H%M<span class="k">)</span><span class="s2">&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> </li> <li><a href="https://git.kgva.ch/karim/RAPPORT/issues/new"target="_blank" rel="noopener">Issue erstellen<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> mit: <ul> <li>Version vor dem Update (falls bekannt)</li> <li>Version nach dem Update</li> <li>Was fehlt</li> <li>Optional: gesicherter Datenordner (via Pastebin oder verschlüsselt zugesandt)</li> </ul> </li> </ol> <h3>localStorage voll<span class="hx:absolute hx:-mt-20" id="localstorage-voll"></span> <a href="#localstorage-voll" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Symptom:</strong> Rapport schreibt Fehler-Toast &ldquo;Speicher voll&rdquo; beim Sichern.</p> <p><strong>Ursache:</strong> macOS WebView limitiert localStorage auf ~10 MB pro Origin.</p> <p><strong>Lösung:</strong></p> <ul> <li>Sehr grosse Logos durch kleinere ersetzen (Bürodaten → Logo)</li> <li>Belege (Spesen) selektiv löschen oder als externe Datei archivieren</li> <li>Auf <a href="../web-modus">Web-Modus</a> wechseln (Postgres ohne praktisches Limit)</li> </ul> <h2>Updates<span class="hx:absolute hx:-mt-20" id="updates"></span> <a href="#updates" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>Auto-Update findet nichts<span class="hx:absolute hx:-mt-20" id="auto-update-findet-nichts"></span> <a href="#auto-update-findet-nichts" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Diagnose:</strong></p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -s https://git.kgva.ch/karim/RAPPORT/raw/branch/main/APP/latest.json</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>→ sollte JSON liefern. Wenn nicht: Server-/Netzwerkproblem.</p> <h3>Update lädt, lässt sich aber nicht installieren<span class="hx:absolute hx:-mt-20" id="update-lädt-lässt-sich-aber-nicht-installieren"></span> <a href="#update-l%c3%a4dt-l%c3%a4sst-sich-aber-nicht-installieren" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> Signaturprüfung scheitert (Public-Key in App ≠ Signatur in <code>latest.json</code>).</p> <p><strong>Lösung:</strong> Manuelles Update — DMG direkt von <a href="https://git.kgva.ch/karim/RAPPORT/releases"target="_blank" rel="noopener">Releases<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> laden und installieren. Daten bleiben erhalten.</p> <h3>&ldquo;Diese Version überspringen&rdquo; rückgängig machen<span class="hx:absolute hx:-mt-20" id="diese-version-überspringen-rückgängig-machen"></span> <a href="#diese-version-%c3%bcberspringen-r%c3%bcckg%c3%a4ngig-machen" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p>In <strong>Einstellungen → Updates</strong> → <em>Übersprungene Versionen zurücksetzen</em>. Beim nächsten Start wird die Version wieder angeboten.</p> <h2>PDF / QR-Schein<span class="hx:absolute hx:-mt-20" id="pdf--qr-schein"></span> <a href="#pdf--qr-schein" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>QR-Schein hat falsche Daten<span class="hx:absolute hx:-mt-20" id="qr-schein-hat-falsche-daten"></span> <a href="#qr-schein-hat-falsche-daten" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Diagnose-Checkliste:</strong></p> <ul> <li><input disabled="" type="checkbox"> IBAN korrekt? (CH, 21 Zeichen, keine Leerzeichen)</li> <li><input disabled="" type="checkbox"> Empfänger-Adresse vollständig? (PLZ und Ort beide gefüllt)</li> <li><input disabled="" type="checkbox"> Schuldner-Adresse vollständig?</li> <li><input disabled="" type="checkbox"> Betrag &gt; 0?</li> <li><input disabled="" type="checkbox"> Referenz nicht zu lang? (max 27 Zeichen)</li> </ul> <p>QR-Bibliothek: <a href="https://github.com/schoero/SwissQRBill"target="_blank" rel="noopener"><code>swissqrbill</code><svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> — bei merkwürdigen Fehlern dort nachschauen.</p> <h3>PDF-Export ist leer / weisses Blatt<span class="hx:absolute hx:-mt-20" id="pdf-export-ist-leer--weisses-blatt"></span> <a href="#pdf-export-ist-leer--weisses-blatt" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> Print-View hat keine Daten (möglicherweise Race-Condition beim Laden).</p> <p><strong>Lösung:</strong> Rechnung schliessen, erneut öffnen, dann PDF.</p> <h3>PDF-Schrift sieht falsch aus<span class="hx:absolute hx:-mt-20" id="pdf-schrift-sieht-falsch-aus"></span> <a href="#pdf-schrift-sieht-falsch-aus" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> Web-Schrift nicht geladen, Fallback greift.</p> <p><strong>Lösung:</strong> Vor dem Drucken warten, bis das Vorschau-Bild komplett geladen ist (3–5 Sek).</p> <h2>System-Tray<span class="hx:absolute hx:-mt-20" id="system-tray"></span> <a href="#system-tray" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>Tray-Icon erscheint nicht<span class="hx:absolute hx:-mt-20" id="tray-icon-erscheint-nicht"></span> <a href="#tray-icon-erscheint-nicht" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Plattform-Hinweis:</strong> Tray-Icons unter macOS sind bei extrem voller Menüleiste oder unter &ldquo;Bartender&rdquo;/&ldquo;Hidden Bar&rdquo; eventuell unsichtbar.</p> <p><strong>Diagnose:</strong></p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ps aux <span class="p">|</span> grep -i rapport</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>→ wenn Prozess läuft, aber kein Icon: in den Tray-Manager-Apps prüfen.</p> <p><strong>Konfiguration:</strong> Einstellungen → System-Tray → <em>Tray-Icon ausblenden</em> (aus → Icon erzwingen).</p> <h3>Tray-Menü reagiert nicht / hängt<span class="hx:absolute hx:-mt-20" id="tray-menü-reagiert-nicht--hängt"></span> <a href="#tray-men%c3%bc-reagiert-nicht--h%c3%a4ngt" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Lösung:</strong> App via <em>Activity Monitor</em> hart beenden und neu starten. Daten gehen nicht verloren (alle Schreibungen sind synchron in localStorage).</p> <h2>Web-Modus<span class="hx:absolute hx:-mt-20" id="web-modus"></span> <a href="#web-modus" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><h3>Login-Screen zeigt keine Server-URL<span class="hx:absolute hx:-mt-20" id="login-screen-zeigt-keine-server-url"></span> <a href="#login-screen-zeigt-keine-server-url" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> <code>.env.production</code> enthielt nicht den richtigen <code>VITE_SUPABASE_URL</code> zur Build-Zeit.</p> <p><strong>Lösung:</strong> <code>.env.production</code> prüfen, dann <code>npm run build</code> neu, Container restart.</p> <h3>Realtime-Updates kommen nicht an<span class="hx:absolute hx:-mt-20" id="realtime-updates-kommen-nicht-an"></span> <a href="#realtime-updates-kommen-nicht-an" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h3><p><strong>Ursache:</strong> Websocket-Support fehlt im Reverse Proxy.</p> <p><strong>Lösung:</strong> In Nginx Proxy Manager für <code>api.*</code> Websocket Support aktivieren.</p> <p>Siehe <a href="../web-modus#troubleshooting">Web-Modus § Troubleshooting</a>.</p> <h2>Debug-Informationen sammeln<span class="hx:absolute hx:-mt-20" id="debug-informationen-sammeln"></span> <a href="#debug-informationen-sammeln" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Bei einem Issue helfen folgende Infos:</p> <div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Rapport-Version</span> </span></span><span class="line"><span class="cl">defaults <span class="nb">read</span> /Applications/Rapport.app/Contents/Info.plist CFBundleShortVersionString </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># macOS-Version</span> </span></span><span class="line"><span class="cl">sw_vers </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Architektur</span> </span></span><span class="line"><span class="cl">uname -m </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Datenverzeichnis-Grösse</span> </span></span><span class="line"><span class="cl">du -sh <span class="s2">&#34;~/Library/Application Support/com.rapport.app&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Cache-Verzeichnis-Grösse</span> </span></span><span class="line"><span class="cl">du -sh <span class="s2">&#34;~/Library/Caches/com.rapport.app&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0"> <button class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50" title="Code kopieren" aria-label="Code kopieren" data-copied-label="Kopiert!" > <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div> <div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div> </button> </div> </div> <p>→ Bei Issue mit anhängen.</p> <h2>Wenn nichts hilft<span class="hx:absolute hx:-mt-20" id="wenn-nichts-hilft"></span> <a href="#wenn-nichts-hilft" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><a href="https://git.kgva.ch/karim/RAPPORT/issues/new"target="_blank" rel="noopener">Neues Issue auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> mit:</p> <ul> <li>Was du gemacht hast</li> <li>Was passiert ist</li> <li>Was du erwartet hättest</li> <li>Screenshots (auch von DevTools-Konsole falls möglich)</li> <li>Rapport-Version und macOS-Version</li> </ul>

# Changelog

/docs/changelog/ Mon, 01 Jan 0001 00:00:00 +0000

/docs/changelog/

<p>Versionsgeschichte von RAPPORT. Aktuelle Releases: <a href="https://git.kgva.ch/karim/RAPPORT/releases"target="_blank" rel="noopener">Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p> <h2>0.8.2 — Aktuelle Version <span class="rapport-status new">Aktuell</span><span class="hx:absolute hx:-mt-20" id="082--aktuelle-version-aktuell"></span> <a href="#082--aktuelle-version-aktuell" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Veröffentlicht am 2026-05-24.</p> <p><strong>Neu / Verbessert</strong></p> <ul> <li>Diverse Verbesserungen und Bugfixes (Details werden im <a href="https://git.kgva.ch/karim/RAPPORT/releases/tag/0.8.2"target="_blank" rel="noopener">Release auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a> gepflegt)</li> </ul> <p><strong>Bekannte Einschränkungen</strong></p> <ul> <li>Builds sind Tauri-signiert, aber noch nicht Apple-notarisiert — siehe <a href="../installation#3--erster-start-macos-gatekeeper">Installation § Gatekeeper</a></li> <li>Linux- und Windows-Builds noch nicht verfügbar</li> </ul> <h2>0.8.0–0.8.1 — Patch-Releases<span class="hx:absolute hx:-mt-20" id="080081--patch-releases"></span> <a href="#080081--patch-releases" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Patch-Reihe mit kleineren Verbesserungen und Bugfixes. Details siehe <a href="https://git.kgva.ch/karim/RAPPORT/releases"target="_blank" rel="noopener">Releases auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p> <h2>0.7.0 — Auto-Updater &amp; System-Tray<span class="hx:absolute hx:-mt-20" id="070--auto-updater--system-tray"></span> <a href="#070--auto-updater--system-tray" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Neu</strong></p> <ul> <li><strong>Auto-Updater</strong> — Rapport prüft beim Start auf neue Versionen und installiert Updates signiert über Tauri. Einzelne Versionen können übersprungen werden. (<a href="../../features/auto-updater">Doku</a>)</li> <li><strong>System-Tray</strong> — Schnellzugriff über die Menüleiste mit Hide-on-Close. Beim Schliessen läuft Rapport im Hintergrund weiter, Cmd+Q beendet die App vollständig. (<a href="../../features/system-tray">Doku</a>)</li> <li><strong>Quick-Open</strong> der letzten 5 Projekte direkt aus dem Tray-Menü</li> </ul> <p><strong>Verbessert</strong></p> <ul> <li>Schnellerer App-Start durch lazy-geladene Views</li> <li>Klarere Statusbadges in der Projekt-Übersicht</li> </ul> <h2>0.6.x — Spesen &amp; Buchhaltung<span class="hx:absolute hx:-mt-20" id="06x--spesen--buchhaltung"></span> <a href="#06x--spesen--buchhaltung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Neu</strong></p> <ul> <li>Spesenerfassung mit Beleg-Upload (Base64 in localStorage)</li> <li>Jahresbudget mit Einnahmen-/Ausgaben-Übersicht</li> <li>Vereinfachte Erfolgsrechnung pro Geschäftsjahr</li> </ul> <p><strong>Verbessert</strong></p> <ul> <li>Lohnabrechnung integriert Spesen-Erstattungen</li> <li>CSV-Export aus der Zeiterfassung</li> </ul> <h2>0.5.x — Mitarbeiter &amp; Lohn<span class="hx:absolute hx:-mt-20" id="05x--mitarbeiter--lohn"></span> <a href="#05x--mitarbeiter--lohn" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Neu</strong></p> <ul> <li>Mitarbeiterverwaltung mit Pensum, Stundensatz, Ferienanspruch</li> <li>Lohnabrechnung mit AHV/IV/EO, ALV, BVG, NBU</li> <li>Jahresabschluss mit Überstundenausgleich</li> <li>Ferien-Prorata bei Eintritt unter Jahr</li> </ul> <h2>0.4.x — Projekte &amp; SIA 102<span class="hx:absolute hx:-mt-20" id="04x--projekte--sia-102"></span> <a href="#04x--projekte--sia-102" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Neu</strong></p> <ul> <li>Projektverwaltung nach SIA 102</li> <li>Vorgeschlagene Phasen-Anteile am Gesamthonorar</li> <li>Bauschätzwert-basiertes Honorar</li> </ul> <p><strong>Verbessert</strong></p> <ul> <li>Zeit-Auswertung pro SIA-Phase</li> <li>Akonto- und Schlussrechnungen mit automatischer Differenzberechnung</li> </ul> <h2>0.3.x — Rechnungen &amp; QR<span class="hx:absolute hx:-mt-20" id="03x--rechnungen--qr"></span> <a href="#03x--rechnungen--qr" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Neu</strong></p> <ul> <li>Rechnungsmodul mit QR-Einzahlungsschein (via <code>swissqrbill</code>)</li> <li>Akonto-, Teil- und Schlussrechnungen</li> <li>PDF-Export mit Bürobriefbogen</li> <li>Stundensatz-Rechnungen ziehen direkt aus der Zeiterfassung</li> </ul> <h2>0.2.x — Zeiterfassung<span class="hx:absolute hx:-mt-20" id="02x--zeiterfassung"></span> <a href="#02x--zeiterfassung" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Neu</strong></p> <ul> <li>Wochenraster mit Halbstunden-Slots</li> <li>Drag &amp; Drop zur Slot-Erfassung</li> <li>Projekt-Zuweisung pro Eintrag</li> <li>Auswertungen pro Mitarbeiter und Projekt</li> </ul> <h2>0.1.x — Initial<span class="hx:absolute hx:-mt-20" id="01x--initial"></span> <a href="#01x--initial" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p><strong>Neu</strong></p> <ul> <li>Erste Setup-Routine (Bürodaten, Mitarbeiter, Kunden)</li> <li>Briefe und Lieferscheine</li> <li>Tauri-2-Bundle für macOS</li> </ul> <hr> <h2>Roadmap<span class="hx:absolute hx:-mt-20" id="roadmap"></span> <a href="#roadmap" class="subheading-anchor" aria-label="Permalink für diesen Abschnitt"></a></h2><p>Geplant — keine konkreten Termine:</p> <ul> <li><strong>Linux-Build</strong> (Tauri 2 unterstützt es, Bedarf nötig)</li> <li><strong>Windows-Build</strong> (analog)</li> <li><strong>Cloud-Modus</strong> Stable (Supabase) — derzeit in <a href="../web-modus">Web-Modus</a> verfügbar, aber experimentell</li> <li><strong>Französische / Italienische Übersetzung</strong></li> <li><strong>PostgreSQL-Migration</strong> aus localStorage (Knopf in der App)</li> <li><strong>Mobile App</strong> (iOS Companion zur Zeiterfassung) — offen</li> </ul> <p>Wünsche oder Prioritäten → <a href="https://git.kgva.ch/karim/RAPPORT/issues"target="_blank" rel="noopener">Issue auf Gitea<svg class="hx:inline hx:rtl:rotate-270 hx:align-baseline" height="1em" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/> </svg></a>.</p>