diff --git a/AUFRÄUMEN.md b/AUFRÄUMEN.md new file mode 100644 index 0000000..1bea2d5 --- /dev/null +++ b/AUFRÄUMEN.md @@ -0,0 +1,97 @@ +# 🧹 Aufräumen - Dateien organisieren + +Diese Datei listet alle Dateien auf, die aufgeräumt/entfernt werden können. + +## ✅ Was wurde gemacht + +1. ✅ Webhook-Dokumentation in `docs/deployment/` organisiert +2. ✅ Scripts-README aktualisiert +3. ✅ Deployment-Dokumentation strukturiert +4. ✅ Projekt-Ordnung dokumentiert (`PROJEKT_ORDNUNG.md`) + +## 🗑️ Dateien die entfernt werden können + +### Scripts (veraltete Git-Commit-Scripts) + +Diese können gelöscht werden, da Git-Commits direkt über `git commit` gemacht werden sollten: + +```bash +scripts/git-commit.bat +scripts/git-commit.sh +scripts/git-commit-fix.bat +scripts/FINAL_COMMIT.bat +scripts/run-git-commit.ps1 +scripts/COMMIT_COMMANDS.txt +scripts/COMMIT_MESSAGE.md +``` + +**Befehl zum Entfernen:** +```bash +cd scripts +rm git-commit.bat git-commit.sh git-commit-fix.bat FINAL_COMMIT.bat run-git-commit.ps1 COMMIT_COMMANDS.txt COMMIT_MESSAGE.md +``` + +### Dokumentation (kann archiviert werden) + +Diese Task-spezifischen Dokumentationsdateien können in `docs/archive/` verschoben werden: + +```bash +docs/development/TASK_5_COMPLETION.md +docs/server/TASK_4_COMPLETION_SUMMARY.md +docs/development/PROJECT_REVIEW_SUMMARY.md +``` + +**Befehl zum Archivieren:** +```bash +mkdir -p docs/archive +mv docs/development/TASK_5_COMPLETION.md docs/archive/ +mv docs/server/TASK_4_COMPLETION_SUMMARY.md docs/archive/ +mv docs/development/PROJECT_REVIEW_SUMMARY.md docs/archive/ +``` + +## 📋 Optionale Aufräumarbeiten + +### Temporäre Dateien im Root + +Falls es temporäre Markdown-Dateien im Root gibt (z.B. von mir erstellt), können diese entfernt werden, nachdem die Informationen in die richtige Dokumentation übernommen wurden: + +- `GITEA_WEBHOOK_ZUSAMMENFASSUNG.md` (falls vorhanden) +- `GITEA_AUTHORIZATION_HEADER.md` (falls vorhanden) +- `DEPLOYMENT_STATUS.md` (falls vorhanden) +- `DEPLOYMENT_KONFIGURIERT.md` (falls vorhanden) + +**Hinweis:** Diese sollten bereits in `docs/deployment/` sein. + +## ✅ Wichtige Dateien (NICHT löschen!) + +Diese Dateien müssen bleiben: + +- Alle Dateien in `client/`, `server/`, `docs/` (außer oben genannte) +- `README.md`, `STRUCTURE.md`, `PROJEKT_ORDNUNG.md` +- Alle Konfigurationsdateien (`.gitignore`, `package.json`, etc.) +- Alle aktiven Scripts (`deploy-to-server.mjs`, `setup-*.ps1`) + +## 🎯 Empfehlung + +1. **Sofort entfernen:** Veraltete Git-Commit-Scripts (werden nicht mehr benötigt) +2. **Archivieren:** Task-spezifische Dokumentation (für Referenz behalten) +3. **Prüfen:** Temporäre Root-Dateien (falls vorhanden, nach Übernahme entfernen) + +## 📝 Nach dem Aufräumen + +Nach dem Aufräumen sollte die Struktur sauberer sein: + +``` +scripts/ +├── deploy-to-server.mjs ✅ +├── setup-appwrite.ps1 ✅ +├── setup-production.ps1 ✅ +└── README.md ✅ + +docs/ +├── deployment/ ✅ (vollständig organisiert) +├── setup/ ✅ +├── development/ ✅ (teilweise archiviert) +├── server/ ✅ (teilweise archiviert) +└── archive/ ✅ (neu, für veraltete Docs) +``` diff --git a/PROJEKT_ORDNUNG.md b/PROJEKT_ORDNUNG.md new file mode 100644 index 0000000..ac3e851 --- /dev/null +++ b/PROJEKT_ORDNUNG.md @@ -0,0 +1,142 @@ +# 📁 Projekt-Ordnung und Dateistruktur + +Diese Datei beschreibt die Organisation aller Dateien im Projekt. + +## ✅ Wichtige Dateien (behalten) + +### Root-Verzeichnis + +- **README.md** - Hauptdokumentation des Projekts +- **STRUCTURE.md** - Detaillierte Projektstruktur +- **.gitignore** - Git-Ignore-Regeln +- **.env.example** - Beispiel-Umgebungsvariablen + +### Client (`client/`) + +- Alle Source-Dateien in `src/` +- Konfigurationsdateien (`package.json`, `vite.config.ts`, etc.) +- **README.md** - Client-spezifische Dokumentation + +### Server (`server/`) + +- Alle Backend-Dateien +- **routes/** - API-Routen (inkl. `webhook.mjs` für automatisches Deployment) +- **config/** - Konfiguration +- **.env** - Umgebungsvariablen (nicht im Git!) + +### Dokumentation (`docs/`) + +- **deployment/** - Deployment-Anleitungen + - `GITEA_WEBHOOK_SETUP.md` - Vollständige Webhook-Anleitung + - `WEBHOOK_QUICK_START.md` - Schnellstart + - `WEBHOOK_AUTHORIZATION.md` - Authentifizierung + - `DEPLOYMENT_INSTRUCTIONS.md` - Manuelles Deployment + - `PRODUCTION_SETUP.md` - Production-Setup + - `PRODUCTION_FIXES.md` - Bekannte Probleme +- **setup/** - Setup-Anleitungen +- **development/** - Development-Dokumentation +- **server/** - Server-Dokumentation + +### Scripts (`scripts/`) + +- **deploy-to-server.mjs** - Deployment-Skript (wird vom Webhook aufgerufen) +- **setup-*.ps1** - Setup-Scripts +- **README.md** - Scripts-Dokumentation + +### Marketing (`marketing/`) + +- Alle Marketing-Materialien und Anleitungen + +## 🗑️ Kann entfernt werden (temporäre/veraltete Dateien) + +### Scripts (`scripts/`) + +Diese Git-Commit-Scripts sind veraltet und können entfernt werden: + +- `git-commit.bat` +- `git-commit.sh` +- `git-commit-fix.bat` +- `FINAL_COMMIT.bat` +- `run-git-commit.ps1` +- `COMMIT_COMMANDS.txt` +- `COMMIT_MESSAGE.md` + +**Grund:** Git-Commits sollten direkt über `git commit` gemacht werden. + +### Dokumentation (`docs/`) + +Einige temporäre/veraltete Dokumentationsdateien können archiviert werden: + +- `development/TASK_5_COMPLETION.md` - Task-spezifisch, kann archiviert werden +- `server/TASK_4_COMPLETION_SUMMARY.md` - Task-spezifisch, kann archiviert werden +- `development/PROJECT_REVIEW_SUMMARY.md` - Review-spezifisch, kann archiviert werden + +**Empfehlung:** Verschiebe diese in `docs/archive/` statt zu löschen. + +## 📋 Dateien-Organisation + +### Aktuelle Struktur + +``` +/ +├── client/ # Frontend +├── server/ # Backend +├── docs/ # Dokumentation +│ ├── deployment/ # Deployment-Docs ✅ +│ ├── setup/ # Setup-Docs ✅ +│ ├── development/ # Development-Docs (teilweise archivieren) +│ └── server/ # Server-Docs (teilweise archivieren) +├── scripts/ # Scripts +│ ├── deploy-to-server.mjs ✅ +│ ├── setup-*.ps1 ✅ +│ └── [veraltete Git-Scripts] ❌ +├── marketing/ # Marketing ✅ +└── README.md # Hauptdokumentation ✅ +``` + +## 🧹 Aufräumen-Empfehlungen + +### 1. Veraltete Scripts entfernen + +```bash +# Diese Dateien können gelöscht werden: +scripts/git-commit.bat +scripts/git-commit.sh +scripts/git-commit-fix.bat +scripts/FINAL_COMMIT.bat +scripts/run-git-commit.ps1 +scripts/COMMIT_COMMANDS.txt +scripts/COMMIT_MESSAGE.md +``` + +### 2. Temporäre Dokumentation archivieren + +Erstelle `docs/archive/` und verschiebe: +- `docs/development/TASK_5_COMPLETION.md` +- `docs/server/TASK_4_COMPLETION_SUMMARY.md` +- `docs/development/PROJECT_REVIEW_SUMMARY.md` + +### 3. README aktualisieren + +Die `scripts/README.md` wurde bereits aktualisiert. + +## ✅ Checkliste + +- [x] Webhook-Dokumentation in `docs/deployment/` organisiert +- [x] Scripts-README aktualisiert +- [x] Deployment-Dokumentation strukturiert +- [ ] Veraltete Scripts entfernen (optional) +- [ ] Temporäre Dokumentation archivieren (optional) + +## 📝 Wichtige Hinweise + +1. **`.env` Dateien** sind nie im Git (siehe `.gitignore`) +2. **Temporäre Anleitungen** können nach erfolgreicher Einrichtung entfernt werden +3. **Task-spezifische Dokumentation** kann archiviert werden, sollte aber nicht gelöscht werden +4. **Alle produktiven Dateien** (Code, Konfiguration, aktive Dokumentation) bleiben erhalten + +## 🔄 Regelmäßige Wartung + +- **Monatlich:** Prüfe auf veraltete Scripts/Dokumentation +- **Nach großen Features:** Aktualisiere README und Dokumentation +- **Nach Deployment:** Entferne temporäre Deployment-Anleitungen (falls nicht mehr benötigt) diff --git a/README.md b/README.md index 703eeff..412b41a 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,19 @@ EmailSorter ist eine SaaS-Anwendung, die automatisch E-Mails kategorisiert und s │ ├── routes/ # API Routen │ ├── services/ # Business Logic │ └── package.json +├── docs/ # Dokumentation +│ ├── setup/ # Setup-Anleitungen +│ ├── deployment/ # Deployment-Docs +│ ├── development/ # Development-Docs +│ └── server/ # Server-Dokumentation +├── scripts/ # Hilfs-Scripts +│ ├── git-commit.* # Git-Scripts +│ └── deploy-build.js # Deployment-Scripts +├── marketing/ # Marketing-Materialien +│ └── *.md # Marketing-Dokumentation ├── n8n/ # n8n Workflows │ └── workflows/ -└── public/ # Legacy Frontend +└── README.md # Diese Datei ``` ## Quick Start @@ -199,6 +209,8 @@ Siehe `n8n/README.md` für Details. ## Deployment +Siehe `docs/deployment/` für detaillierte Deployment-Anleitungen. + ### Frontend (Vercel/Netlify) ```bash @@ -219,6 +231,17 @@ Aktualisiere die Webhook-URL im Stripe Dashboard auf deine Produktions-URL: https://your-domain.com/api/subscription/webhook ``` +## Dokumentation + +Alle Dokumentation befindet sich im `docs/` Ordner: + +- **Setup:** `docs/setup/` - Setup-Anleitungen für Appwrite, OAuth, etc. +- **Deployment:** `docs/deployment/` - Production-Setup und Deployment +- **Development:** `docs/development/` - Development-Dokumentation +- **Server:** `docs/server/` - Server-spezifische Dokumentation + +Siehe `docs/README.md` für eine vollständige Übersicht. + ## Troubleshooting ### Frontend startet nicht diff --git a/STRUCTURE.md b/STRUCTURE.md new file mode 100644 index 0000000..85a01bc --- /dev/null +++ b/STRUCTURE.md @@ -0,0 +1,95 @@ +# Projektstruktur-Übersicht + +Diese Datei beschreibt die organisierte Struktur des Projekts. + +## 📁 Hauptverzeichnisse + +### `/client/` +React Frontend-Anwendung +- `src/` - Quellcode +- `public/` - Statische Assets +- `package.json` - Frontend-Dependencies + +### `/server/` +Node.js Backend-Server +- `routes/` - API-Routen +- `services/` - Business-Logik +- `middleware/` - Express-Middleware +- `config/` - Konfiguration +- `utils/` - Utility-Funktionen +- `package.json` - Backend-Dependencies + +### `/docs/` +Alle Dokumentation +- `setup/` - Setup-Anleitungen (Appwrite, OAuth, etc.) +- `deployment/` - Deployment & Production-Docs +- `development/` - Development-Dokumentation +- `server/` - Server-spezifische Dokumentation +- `examples/` - Beispiel-Code (z.B. starter-for-react) +- `legacy/` - Legacy-Dateien + +### `/scripts/` +Hilfs-Scripts für Entwicklung & Deployment +- Git-Scripts (`git-commit.*`, `run-git-commit.ps1`) +- Deployment-Scripts (`deploy-build.js`) +- Setup-Scripts (`setup-appwrite.ps1`, `setup-production.ps1`) +- Commit-Hilfsdateien (`COMMIT_MESSAGE.md`, `COMMIT_COMMANDS.txt`) + +### `/marketing/` +Marketing-Materialien und Dokumentation +- Logo-Dateien (SVG) +- Marketing-Guides (TikTok, YouTube, Product Hunt, etc.) +- Influencer-Templates + +### `/n8n/` +n8n Workflow-Konfigurationen +- `workflows/` - Workflow-Definitionen + +### `/.kiro/` +Kiro-Spezifikationen (Design, Requirements, Tasks) + +## 📄 Root-Dateien + +- `README.md` - Haupt-README mit Projektübersicht +- `STRUCTURE.md` - Diese Datei +- `.env.example` - Beispiel-Umgebungsvariablen +- `.gitignore` - Git-Ignore-Regeln + +## 🎯 Organisationsprinzipien + +1. **Dokumentation zentralisiert:** Alle `.md` Dateien sind in `docs/` organisiert +2. **Scripts getrennt:** Alle Scripts sind in `scripts/` gesammelt +3. **Sauberes Root:** Root-Verzeichnis enthält nur essenzielle Dateien +4. **Klare Kategorien:** Dokumentation nach Themen sortiert (setup, deployment, development) + +## 📝 Wichtige Dateien + +### Setup +- `docs/setup/SETUP_GUIDE.md` - Allgemeine Setup-Anleitung +- `docs/setup/APPWRITE_SETUP.md` - Appwrite-Konfiguration +- `docs/setup/GOOGLE_OAUTH_SETUP.md` - Google OAuth Setup + +### Deployment +- `docs/deployment/PRODUCTION_SETUP.md` - Production-Server Setup +- `docs/deployment/DEPLOYMENT_INSTRUCTIONS.md` - Deployment-Anleitung + +### Development +- `docs/development/PROJECT_REVIEW_SUMMARY.md` - Projekt-Review +- `docs/development/TESTING_SUMMARY.md` - Testing-Dokumentation + +## 🔧 Scripts-Verwendung + +Alle Scripts befinden sich in `scripts/`: + +```bash +# Git-Commit (Windows) +scripts\git-commit.bat + +# Git-Commit (PowerShell) +scripts\run-git-commit.ps1 + +# Deployment +node scripts\deploy-build.js +``` + +Siehe `scripts/README.md` für Details. diff --git a/client/src/App.tsx b/client/src/App.tsx index e195c6b..634b6d7 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -21,10 +21,10 @@ initAnalytics() // Loading spinner component function LoadingSpinner() { return ( -
+
-
-

Loading...

+
+

Loading...

) diff --git a/client/src/components/landing/FAQ.tsx b/client/src/components/landing/FAQ.tsx index 8c2db48..6816312 100644 --- a/client/src/components/landing/FAQ.tsx +++ b/client/src/components/landing/FAQ.tsx @@ -41,17 +41,17 @@ export function FAQ() { const [openIndex, setOpenIndex] = useState(0) return ( -
+
{/* Section header */}
-
- +
+
-

+

FAQ

-

+

Quick answers to common questions.

@@ -70,11 +70,11 @@ export function FAQ() {
{/* Contact CTA */} -
-

Still have questions?

+
+

Still have questions?

Contact us → @@ -93,15 +93,15 @@ interface FAQItemProps { function FAQItem({ question, answer, isOpen, onClick }: FAQItemProps) { return ( -
+
) diff --git a/client/src/components/landing/Features.tsx b/client/src/components/landing/Features.tsx index 56641b0..e6f118f 100644 --- a/client/src/components/landing/Features.tsx +++ b/client/src/components/landing/Features.tsx @@ -52,17 +52,17 @@ const features = [ export function Features() { return ( -
+
{/* Section header */}
-

+

Everything you need for{' '} Inbox Zero

-

+

EmailSorter combines AI technology with proven email management methods for maximum productivity.

@@ -77,17 +77,17 @@ export function Features() { {/* Bottom illustration */}
-
+
{/* Before */}
-
- +
+
-

Before

-

Inbox chaos

-
847
-

unread emails

+

Before

+

Inbox chaos

+
847
+

unread emails

{/* Arrow */} @@ -99,13 +99,13 @@ export function Features() { {/* After */}
-
- +
+
-

After

-

All sorted

-
12
-

important emails

+

After

+

All sorted

+
12
+

important emails

@@ -129,16 +129,16 @@ function FeatureCard({ icon: Icon, title, description, color, index, highlight }
-

{title}

-

{description}

+

{title}

+

{description}

) } diff --git a/client/src/components/landing/HowItWorks.tsx b/client/src/components/landing/HowItWorks.tsx index a2ef567..0932599 100644 --- a/client/src/components/landing/HowItWorks.tsx +++ b/client/src/components/landing/HowItWorks.tsx @@ -35,17 +35,17 @@ const steps = [ export function HowItWorks() { return ( -
+
{/* Section header */}
-

+

4 steps to a{' '} clean inbox

-

+

Get started in minutes – no technical knowledge required.

@@ -65,11 +65,11 @@ export function HowItWorks() { {/* CTA */}
- -

Ready to get started?

+ +

Ready to get started?

Try it free now → @@ -91,20 +91,20 @@ function StepCard({ icon: Icon, step, title, description }: StepCardProps) { return (
{/* Card */} -
+
{/* Step number */} -
+
{step}
{/* Icon */} -
- +
+
{/* Content */} -

{title}

-

{description}

+

{title}

+

{description}

) diff --git a/client/src/components/landing/Pricing.tsx b/client/src/components/landing/Pricing.tsx index c43f802..e9f7a87 100644 --- a/client/src/components/landing/Pricing.tsx +++ b/client/src/components/landing/Pricing.tsx @@ -64,7 +64,7 @@ export function Pricing() { const navigate = useNavigate() return ( -
+
{/* Section header */}
@@ -72,10 +72,10 @@ export function Pricing() { 14-day free trial -

+

Simple, transparent pricing

-

+

Choose the plan that fits you. Cancel anytime, no hidden costs.

@@ -93,11 +93,11 @@ export function Pricing() { {/* FAQ teaser */}
-

+

Still have questions?{' '} @@ -131,15 +131,15 @@ function PricingCard({ }: PricingCardProps) { return (

{popular && (
- + Most Popular
@@ -147,15 +147,15 @@ function PricingCard({ {/* Header */}
-

{name}

-

{description}

+

{name}

+

{description}

{/* Price */}
- ${price} - {period} + ${price} + {period}
@@ -164,15 +164,15 @@ function PricingCard({ {features.map((feature, index) => (
  • {feature.included ? ( -
    - +
    +
    ) : ( -
    - +
    +
    )} - + {feature.text}
  • diff --git a/client/src/lib/appwrite.ts b/client/src/lib/appwrite.ts index 53dae5d..9cab4a0 100644 --- a/client/src/lib/appwrite.ts +++ b/client/src/lib/appwrite.ts @@ -18,9 +18,19 @@ export { ID } export const auth = { // Create a new account async register(email: string, password: string, name?: string) { - const user = await account.create(ID.unique(), email, password, name) - await this.login(email, password) - return user + // #region agent log + fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'appwrite.ts:20',message:'register called',data:{endpoint:APPWRITE_ENDPOINT,origin:window.location.origin,email},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{}); + // #endregion + try { + const user = await account.create(ID.unique(), email, password, name) + await this.login(email, password) + return user + } catch (error) { + // #region agent log + fetch('http://127.0.0.1:7242/ingest/4fa7412d-6f79-4871-8728-29c37c9e5772',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'appwrite.ts:23',message:'register error',data:{errorMessage:error instanceof Error ? error.message : 'Unknown error'},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{}); + // #endregion + throw error + } }, // Login with email and password diff --git a/client/src/pages/ForgotPassword.tsx b/client/src/pages/ForgotPassword.tsx index da2ee66..28e99e0 100644 --- a/client/src/pages/ForgotPassword.tsx +++ b/client/src/pages/ForgotPassword.tsx @@ -29,22 +29,22 @@ export function ForgotPassword() { } return ( -
    +
    {/* Logo */}
    - - EmailSorter + + EmailSorter - + - Passwort vergessen? - + Passwort vergessen? + {sent ? 'Prüfe dein E-Mail-Postfach' : 'Gib deine E-Mail-Adresse ein und wir senden dir einen Link zum Zurücksetzen.' @@ -54,14 +54,14 @@ export function ForgotPassword() { {sent ? (
    -
    - +
    +
    -

    E-Mail gesendet!

    -

    - Wir haben dir eine E-Mail mit einem Link zum Zurücksetzen deines Passworts an {email} gesendet. +

    E-Mail gesendet!

    +

    + Wir haben dir eine E-Mail mit einem Link zum Zurücksetzen deines Passworts an {email} gesendet.

    -

    +

    Keine E-Mail erhalten? Prüfe deinen Spam-Ordner oder versuche es erneut.

    @@ -83,13 +83,13 @@ export function ForgotPassword() { ) : (
    {error && ( -
    +
    {error}
    )}
    - + setEmail(e.target.value)} required autoFocus + className="dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100" />
    @@ -115,7 +116,7 @@ export function ForgotPassword() {
    Zurück zum Login diff --git a/client/src/pages/Imprint.tsx b/client/src/pages/Imprint.tsx index e2ca3c9..68180cf 100644 --- a/client/src/pages/Imprint.tsx +++ b/client/src/pages/Imprint.tsx @@ -3,7 +3,7 @@ import { ArrowLeft, Building2 } from 'lucide-react' export function Imprint() { return ( -
    +
    {/* Header */}
    @@ -19,56 +19,56 @@ export function Imprint() { {/* Content */}
    -
    +
    {/* Title */}
    -
    - +
    +
    -

    Impressum

    -

    Legal Information

    +

    Impressum

    +

    Legal Information

    {/* Content - Placeholder for webklar.com content */} -
    -

    +

    +

    Note: This imprint is managed by webklar.com. Please refer to their imprint for detailed information.

    -
    -

    Information according to § 5 TMG

    +
    +

    Information according to § 5 TMG

    -
    +
    -

    Operator

    +

    Operator

    EmailSorter is operated by:

    webklar.com
    Kenso Grimm, Justin Klein

    -

    +

    For complete contact details and legal information, please visit:{' '} webklar.com/impressum

    -
    -

    Contact

    +
    +

    Contact

    Email:{' '} support@webklar.com @@ -77,23 +77,23 @@ export function Imprint() { Phone:{' '} +49 176 23726355 {' / '} +49 170 4969375

    -

    +

    For questions regarding EmailSorter specifically:{' '} support@emailsorter.com @@ -101,8 +101,8 @@ export function Imprint() {

    -
    -

    Responsible for Content

    +
    +

    Responsible for Content

    The content of this website is the responsibility of webklar.com. For detailed information, please refer to the official imprint at{' '} @@ -110,23 +110,23 @@ export function Imprint() { href="https://webklar.com/impressum" target="_blank" rel="noopener noreferrer" - className="text-primary-600 hover:text-primary-700 underline" + className="text-primary-600 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300 underline" > webklar.com/impressum

    -
    -

    Liability for Links

    +
    +

    Liability for Links

    Our website contains links to external websites. We have no influence on the content of these websites. Therefore, we cannot assume any liability for these external contents.

    -
    -

    Copyright

    +
    +

    Copyright

    The content and works on this website are subject to German copyright law. Reproduction, processing, distribution, and any form of commercialization require the written consent of the respective author or creator. @@ -134,14 +134,14 @@ export function Imprint() {

    -
    -

    +

    +

    Important: This is a simplified version. For the complete and legally binding imprint, please visit{' '} webklar.com/impressum diff --git a/client/src/pages/Privacy.tsx b/client/src/pages/Privacy.tsx index 2448ed1..3c78cc5 100644 --- a/client/src/pages/Privacy.tsx +++ b/client/src/pages/Privacy.tsx @@ -3,7 +3,7 @@ import { ArrowLeft, Shield } from 'lucide-react' export function Privacy() { return ( -

    +
    {/* Header */}
    @@ -19,81 +19,81 @@ export function Privacy() { {/* Content */}
    -
    +
    {/* Title */}
    -
    - +
    +
    -

    Privacy Policy

    -

    Last updated: {new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}

    +

    Privacy Policy

    +

    Last updated: {new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}

    {/* Content - Placeholder for webklar.com content */} -
    -

    +

    +

    Note: This privacy policy is managed by webklar.com. Please refer to their privacy policy for detailed information.

    -
    -

    Data Protection Information

    -

    +

    +

    Data Protection Information

    +

    EmailSorter is operated by webklar.com. The following privacy policy applies to the use of this website and our services.

    -

    1. Responsible Party

    -

    +

    1. Responsible Party

    +

    The responsible party for data processing on this website is:

    -
    -

    +

    +

    webklar.com
    Kenso Grimm, Justin Klein

    -

    +

    Contact:
    - Email: support@webklar.com
    - Phone: +49 176 23726355 + Email: support@webklar.com
    + Phone: +49 176 23726355

    -

    - For complete contact details, please refer to the Impressum. +

    + For complete contact details, please refer to the Impressum.

    -

    2. Data Collection and Processing

    -

    +

    2. Data Collection and Processing

    +

    When you use EmailSorter, we collect and process the following data:

    -
      +
      • Account information (email address, name)
      • Email metadata (sender, subject, date) for sorting purposes
      • Usage statistics and preferences
      • Payment information (processed securely via Stripe)
      -

      3. Purpose of Data Processing

      -

      +

      3. Purpose of Data Processing

      +

      We process your data exclusively for the following purposes:

      -
        +
        • Providing and improving the EmailSorter service
        • Automated email sorting and categorization
        • Processing payments and subscriptions
        • Customer support and communication
        -

        4. Data Security

        -

        +

        4. Data Security

        +

        We implement appropriate technical and organizational measures to protect your data against unauthorized access, loss, or destruction.

        -

        5. Your Rights

        -

        +

        5. Your Rights

        +

        You have the right to:

        -
          +
          • Access your personal data
          • Correct inaccurate data
          • Request deletion of your data
          • @@ -101,14 +101,14 @@ export function Privacy() {
          • Data portability
          -

          6. Hosting and Third-Party Services

          -

          +

          6. Hosting and Third-Party Services

          +

          Hosting: Our website is hosted by Netlify, which acts as a data processor.

          -

          +

          We use the following third-party services:

          -
            +
            • Appwrite: User authentication and database
            • Stripe: Payment processing
            • Mistral AI: Email categorization
            • @@ -116,45 +116,45 @@ export function Privacy() {
            • Plausible (optional): Privacy-friendly analytics tool, if enabled
            -

            6.1. Cookies and Tracking

            -

            +

            6.1. Cookies and Tracking

            +

            We do not use external fonts or unnecessary cookies. If we use any tracking tools (such as Plausible), they are privacy-friendly and do not store personal data. We only process personal data to the extent that it is technically or organizationally necessary.

            -

            7. Contact Form Data

            -

            +

            7. Contact Form Data

            +

            Data that you send to us via contact forms will be stored and used for processing your inquiry. This data will not be shared with third parties without your consent.

            -

            8. Contact

            -

            +

            8. Contact

            +

            For questions regarding data protection, please contact us:

            -
            -

            +

            +

            Email:{' '} - + support@webklar.com

            -

            +

            Phone:{' '} - + +49 176 23726355

            -

            - For complete contact details, please refer to the Impressum. +

            + For complete contact details, please refer to the Impressum.

            -
            -

            +

            +

            Important: This is a simplified version. For the complete and legally binding privacy policy, please visit{' '} - + webklar.com/datenschutz

            diff --git a/client/src/pages/Register.tsx b/client/src/pages/Register.tsx index 71e4017..9e95341 100644 --- a/client/src/pages/Register.tsx +++ b/client/src/pages/Register.tsx @@ -114,30 +114,30 @@ export function Register() {
            {/* Right side - Form */} -
            +
            {/* Logo */}
            - - E-Mail-Sorter + + E-Mail-Sorter -

            +

            Create account

            -

            +

            Ready to go in less than a minute.

            {/* Error message */} {error && ( -
            - -

            {error}

            +
            + +

            {error}

            )} @@ -217,16 +217,16 @@ export function Register() { )} -

            +

            By signing up, you agree to our{' '} - Terms of Service and{' '} - Privacy Policy. + Terms of Service and{' '} + Privacy Policy.

            -

            +

            Already have an account?{' '} - + Sign in

            diff --git a/client/src/pages/ResetPassword.tsx b/client/src/pages/ResetPassword.tsx index 8c417f6..7402566 100644 --- a/client/src/pages/ResetPassword.tsx +++ b/client/src/pages/ResetPassword.tsx @@ -83,24 +83,24 @@ export function ResetPassword() { const passwordStrength = getPasswordStrength() return ( -
            +
            {/* Logo */}
            - - EmailSorter + + EmailSorter - + - + {success ? 'Passwort geändert!' : 'Neues Passwort festlegen'} - + {success ? 'Dein Passwort wurde erfolgreich geändert.' : 'Wähle ein sicheres neues Passwort für deinen Account.' @@ -110,10 +110,10 @@ export function ResetPassword() { {success ? (
            -
            - +
            +
            -

            +

            Du kannst dich jetzt mit deinem neuen Passwort anmelden.

            ) : !userId || !secret ? (
            -
            - +
            +
            -

            Ungültiger Link

            -

            +

            Ungültiger Link

            +

            Dieser Link zum Zurücksetzen des Passworts ist ungültig oder abgelaufen.

            @@ -136,13 +136,13 @@ export function ResetPassword() { ) : (
            {error && ( -
            +
            {error}
            )}
            - +
            setPassword(e.target.value)} required autoFocus + className="dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100" /> @@ -172,13 +173,13 @@ export function ResetPassword() { className={`h-1 flex-1 rounded-full transition-colors ${ level <= passwordStrength.strength ? passwordStrength.color - : 'bg-slate-200' + : 'bg-slate-200 dark:bg-slate-700' }`} /> ))}

            {passwordStrength.label}

            @@ -187,7 +188,7 @@ export function ResetPassword() {
            - + setConfirmPassword(e.target.value)} required + className="dark:bg-slate-800 dark:border-slate-600 dark:text-slate-100" /> {confirmPassword && password !== confirmPassword && ( -

            Passwörter stimmen nicht überein

            +

            Passwörter stimmen nicht überein

            )}
            diff --git a/client/src/pages/Setup.tsx b/client/src/pages/Setup.tsx index 2d76063..99ddf84 100644 --- a/client/src/pages/Setup.tsx +++ b/client/src/pages/Setup.tsx @@ -283,17 +283,17 @@ export function Setup() { // Show loading while checking accounts if (checkingAccounts) { return ( -
            +
            - -

            Setting up your account...

            + +

            Setting up your account...

            ) } return ( -
            +
            @@ -315,13 +315,13 @@ export function Setup() { {/* Success message after checkout */} {isFromCheckout && (
            -
            -
            +
            +
            -

            Payment successful!

            -

            +

            Payment successful!

            +

            Your subscription is active. Let's connect your email account to get started.

            @@ -351,23 +351,23 @@ export function Setup() {
            {index < stepIndex ? : index + 1}
            {index < steps.length - 1 && (
            )}
            @@ -376,7 +376,7 @@ export function Setup() {
            {error && ( -
            +

            {error}

            @@ -388,8 +388,8 @@ export function Setup() {
            -

            Connect your email account

            -

            +

            Connect your email account

            +

            Choose your email provider. The connection is secure and your data stays private.

            @@ -416,10 +416,10 @@ export function Setup() {
            -
            +
            - Or connect your inbox + Or connect your inbox
            @@ -427,12 +427,12 @@ export function Setup() {
            -
            -

            +

            +

            🔒 Your data is secure. We don't store email content and only have read access.

            @@ -485,16 +485,16 @@ export function Setup() {
            -

            Sorting Settings

            -

            +

            Sorting Settings

            +

            Customize how strictly the AI should sort your emails.

            - +
            - +
            {[ { id: 'light', name: 'Light', desc: 'Only obvious distractions', emoji: '🌱' }, @@ -506,30 +506,30 @@ export function Setup() { onClick={() => setPreferences(p => ({ ...p, sortingStrictness: option.id }))} className={`p-4 rounded-xl border-2 text-center transition-all ${ preferences.sortingStrictness === option.id - ? 'border-primary-500 bg-primary-50 shadow-lg shadow-primary-500/10' - : 'border-slate-200 hover:border-slate-300 bg-white' + ? 'border-primary-500 dark:border-primary-400 bg-primary-50 dark:bg-primary-900/30 shadow-lg shadow-primary-500/10' + : 'border-slate-200 dark:border-slate-700 hover:border-slate-300 dark:hover:border-slate-600 bg-white dark:bg-slate-800' }`} > {option.emoji} -

            {option.name}

            -

            {option.desc}

            +

            {option.name}

            +

            {option.desc}

            ))}
            -
            +
            -

            Historical emails

            -

            Analyze and sort last 30 days

            +

            Historical emails

            +

            Analyze and sort last 30 days

            @@ -545,8 +545,8 @@ export function Setup() {
            -

            Choose your categories

            -

            +

            Choose your categories

            +

            Which categories should your emails be sorted into?

            @@ -558,21 +558,21 @@ export function Setup() { onClick={() => toggleCategory(category.id)} className={`flex items-center gap-4 p-5 rounded-xl border-2 text-left transition-all ${ selectedCategories.includes(category.id) - ? 'border-primary-500 bg-primary-50 shadow-lg shadow-primary-500/10' - : 'border-slate-200 bg-white hover:border-slate-300 hover:shadow-md' + ? 'border-primary-500 dark:border-primary-400 bg-primary-50 dark:bg-primary-900/30 shadow-lg shadow-primary-500/10' + : 'border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 hover:border-slate-300 dark:hover:border-slate-600 hover:shadow-md' }`} >
            {category.icon}
            -

            {category.name}

            -

            {category.description}

            +

            {category.name}

            +

            {category.description}

            {selectedCategories.includes(category.id) && }
            @@ -580,7 +580,7 @@ export function Setup() { ))}
            -

            +

            You can change these categories later in settings.

            @@ -591,20 +591,20 @@ export function Setup() {
            -

            All set! 🎉

            -

            +

            All set! 🎉

            +

            Your email account is connected. The AI will now start intelligent sorting.

            -
            -
            - +
            +
            +
            -

            +

            {connectedProvider === 'gmail' ? 'Gmail' : connectedProvider === 'outlook' ? 'Outlook' : 'Email'} connected

            -

            {connectedEmail || user?.email}

            +

            {connectedEmail || user?.email}

            Active
            @@ -628,7 +628,7 @@ export function Setup() { {currentStep !== 'connect' && currentStep !== 'complete' && (
            - diff --git a/client/src/pages/VerifyEmail.tsx b/client/src/pages/VerifyEmail.tsx index ea45d12..e90571f 100644 --- a/client/src/pages/VerifyEmail.tsx +++ b/client/src/pages/VerifyEmail.tsx @@ -51,26 +51,26 @@ export function VerifyEmail() { } return ( -
            +
            {/* Logo */}
            - - EmailSorter + + EmailSorter - + - + {status === 'loading' && 'E-Mail wird verifiziert...'} {status === 'success' && 'E-Mail verifiziert!'} {status === 'error' && 'Verifizierung fehlgeschlagen'} - + {status === 'loading' && 'Bitte warte einen Moment.'} {status === 'success' && 'Deine E-Mail-Adresse wurde erfolgreich bestätigt.'} {status === 'error' && error} @@ -79,25 +79,25 @@ export function VerifyEmail() { {status === 'loading' && (
            - -

            Verifizierung läuft...

            + +

            Verifizierung läuft...

            )} {status === 'success' && (
            -
            - +
            +
            -
            -

            +

            +

            Dein Account ist jetzt vollständig aktiviert!

            -

            +

            Du kannst jetzt alle Features von EmailSorter nutzen.

            @@ -110,18 +110,18 @@ export function VerifyEmail() { {status === 'error' && (
            -
            - +
            +
            -
            -

            +

            +

            {error || 'Der Verifizierungslink ist ungültig oder abgelaufen.'}

            -

            +

            Falls dein Link abgelaufen ist, kannst du eine neue Verifizierungs-E-Mail anfordern.

            @@ -142,9 +142,9 @@ export function VerifyEmail() { {/* Help text */} -

            +

            Probleme? Kontaktiere uns unter{' '} - + support@emailsorter.de

            diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..ac5a4f1 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,60 @@ +# Dokumentation + +Diese Dokumentation ist in verschiedene Kategorien unterteilt: + +## 📁 Struktur + +``` +docs/ +├── setup/ # Setup-Anleitungen +├── deployment/ # Deployment & Production +├── development/ # Development-Dokumentation +├── server/ # Server-spezifische Docs +├── examples/ # Beispiel-Code +└── legacy/ # Legacy-Dateien +``` + +## 📚 Kategorien + +### Setup (`docs/setup/`) +- **APPWRITE_SETUP.md** - Appwrite Installation & Konfiguration +- **APPWRITE_CORS_SETUP.md** - CORS-Konfiguration für Appwrite +- **GOOGLE_OAUTH_SETUP.md** - Google OAuth Setup +- **SETUP_GUIDE.md** - Allgemeine Setup-Anleitung +- **FAVICON_SETUP.md** - Favicon-Konfiguration + +### Deployment (`docs/deployment/`) +- **README.md** - Deployment-Übersicht +- **GITEA_WEBHOOK_SETUP.md** - Vollständige Anleitung für automatisches Deployment via Gitea Webhook +- **WEBHOOK_QUICK_START.md** - Schnellstart-Anleitung (5 Minuten) +- **WEBHOOK_AUTHORIZATION.md** - Webhook-Authentifizierung und Sicherheit +- **PRODUCTION_SETUP.md** - Production-Server Setup +- **PRODUCTION_FIXES.md** - Production-Fixes & Troubleshooting +- **DEPLOYMENT_INSTRUCTIONS.md** - Manuelle Deployment-Anleitungen + +### Development (`docs/development/`) +- **GIT_AUTHENTICATION_FIX.md** - Git-Authentifizierung +- **PROJECT_RENAME_GUIDE.md** - Projekt-Umbenennung +- **PROJECT_REVIEW_SUMMARY.md** - Projekt-Review +- **TASK_5_COMPLETION.md** - Task-Completion-Dokumentation +- **TESTING_SUMMARY.md** - Testing-Zusammenfassung + +### Server (`docs/server/`) +- **CORRECTNESS_VALIDATION.md** - Korrektheits-Validierung +- **E2E_TEST_GUIDE.md** - End-to-End Test Guide +- **ENDPOINT_VERIFICATION.md** - API-Endpoint-Verifikation +- **FRONTEND_VERIFICATION.md** - Frontend-Verifikation +- **MANUAL_TEST_CHECKLIST.md** - Manuelle Test-Checkliste +- **TASK_4_COMPLETION_SUMMARY.md** - Task 4 Completion + +### Examples (`docs/examples/`) +- **starter-for-react/** - React Starter Template (Beispiel) + +### Legacy (`docs/legacy/`) +- **public/** - Alte Public-Dateien (falls noch benötigt) + +## 🚀 Schnellstart + +1. **Erstes Setup:** Siehe `docs/setup/SETUP_GUIDE.md` +2. **Production Deployment:** Siehe `docs/deployment/PRODUCTION_SETUP.md` +3. **Development:** Siehe `docs/development/` für Development-Dokumentation diff --git a/DEPLOYMENT_INSTRUCTIONS.md b/docs/deployment/DEPLOYMENT_INSTRUCTIONS.md similarity index 100% rename from DEPLOYMENT_INSTRUCTIONS.md rename to docs/deployment/DEPLOYMENT_INSTRUCTIONS.md diff --git a/docs/deployment/GITEA_WEBHOOK_SETUP.md b/docs/deployment/GITEA_WEBHOOK_SETUP.md new file mode 100644 index 0000000..7009aa6 --- /dev/null +++ b/docs/deployment/GITEA_WEBHOOK_SETUP.md @@ -0,0 +1,219 @@ +# Gitea Webhook Setup - Automatisches Deployment + +Diese Anleitung erklärt, wie du einen Gitea-Webhook einrichtest, um automatisch zu deployen, wenn Code gepusht wird. + +## Übersicht + +Der Webhook funktioniert folgendermaßen: +1. **Push auf Gitea** → Gitea sendet Webhook-Event an deinen Server +2. **Webhook-Handler** empfängt das Event und verifiziert die Signatur +3. **Deployment-Skript** wird ausgeführt: + - Git Pull (falls auf Server) + - Frontend Build (`npm run build`) + - Upload auf Production-Server (via SCP/SSH) + - Backend Neustart (optional, via PM2) + +## Voraussetzungen + +- ✅ Gitea-Repository mit deinem Code +- ✅ Production-Server mit SSH-Zugriff +- ✅ Node.js auf dem Server installiert +- ✅ PM2 installiert (optional, für Backend-Neustart) + +## Schritt 1: Webhook-Secret generieren + +Generiere ein sicheres Secret für die Webhook-Signatur-Verification: + +```bash +# Generiere ein zufälliges Secret (32 Zeichen) +node -e "console.log(require('crypto').randomBytes(16).toString('hex'))" +``` + +**Wichtig:** Speichere dieses Secret sicher - du brauchst es in Schritt 3 und 4. + +## Schritt 2: Environment Variables konfigurieren + +Füge folgende Variablen zu deiner `server/.env` Datei hinzu: + +```bash +# Gitea Webhook Secret (aus Schritt 1) +GITEA_WEBHOOK_SECRET=dein_generiertes_secret_hier + +# Optional: Authorization Header Token +GITEA_WEBHOOK_AUTH_TOKEN=dein_auth_token_hier + +# Server-Deployment (optional, nur wenn automatischer Upload gewünscht) +DEPLOY_SERVER_HOST=91.99.156.85 +DEPLOY_SERVER_USER=root +DEPLOY_SERVER_PATH=/var/www/emailsorter +DEPLOY_SSH_KEY=/path/to/ssh/private/key # Optional, falls SSH-Key benötigt wird +DEPLOY_FRONTEND_PATH=/var/www/emailsorter/client/dist +DEPLOY_BACKEND_PATH=/var/www/emailsorter/server + +# PM2 für Backend-Neustart (optional) +USE_PM2=true +``` + +## Schritt 3: Webhook in Gitea konfigurieren + +1. **Öffne dein Repository** in Gitea +2. Gehe zu **Settings** → **Webhooks** +3. Klicke auf **Add Webhook** → **Gitea** +4. Fülle die Felder aus: + + - **Target URL:** + ``` + https://emailsorter.webklar.com/api/webhook/gitea + ``` + (Ersetze mit deiner tatsächlichen Domain) + + - **HTTP Method:** `POST` + + - **Post Content Type:** `application/json` + + - **Secret:** + ``` + dein_generiertes_secret_hier + ``` + (Das gleiche Secret wie in Schritt 1) + + - **Authorization Header:** (Optional) + ``` + Bearer dein_auth_token_hier + ``` + + - **Trigger On:** + - ✅ **Push Events** (wichtig!) + - Optional: **Create**, **Delete** (falls gewünscht) + + - **Branch Filter:** `main` oder `master` (je nach deinem Standard-Branch) + +5. Klicke auf **Add Webhook** + +## Schritt 4: Webhook testen + +### Option A: Test über Gitea UI + +1. Gehe zurück zu **Settings** → **Webhooks** +2. Klicke auf deinen Webhook +3. Klicke auf **Test Delivery** → **Push Events** +4. Prüfe die Antwort: + - ✅ **Status 202** = Webhook empfangen, Deployment gestartet + - ❌ **Status 401** = Secret falsch + - ❌ **Status 500** = Server-Fehler (prüfe Server-Logs) + +### Option B: Test über Git Push + +1. Mache eine kleine Änderung (z.B. Kommentar in einer Datei) +2. Committe und pushe: + ```bash + git add . + git commit -m "test: Webhook test" + git push + ``` +3. Prüfe die Server-Logs: + ```bash + # Auf dem Server + pm2 logs emailsorter-backend + # Oder + tail -f /var/log/emailsorter/webhook.log + ``` +4. Du solltest sehen: + ``` + 📥 Gitea Webhook empfangen + 🚀 Starte Deployment... + 📦 Baue Frontend... + ✅ Deployment erfolgreich abgeschlossen + ``` + +## Schritt 5: Deployment-Logs prüfen + +Die Webhook-Handler loggen alle Schritte. Prüfe die Logs: + +```bash +# PM2 Logs +pm2 logs emailsorter-backend + +# Oder direkt im Server +tail -f server/logs/webhook.log +``` + +## Fehlerbehebung + +### Webhook wird nicht ausgelöst + +- ✅ Prüfe, ob die **Target URL** korrekt ist +- ✅ Prüfe, ob der Server erreichbar ist (`curl https://emailsorter.webklar.com/api/webhook/status`) +- ✅ Prüfe Gitea-Logs: **Settings** → **Webhooks** → **Delivery Log** + +### "Ungültige Webhook-Signatur" (401) + +- ✅ Prüfe, ob `GITEA_WEBHOOK_SECRET` in `server/.env` gesetzt ist +- ✅ Prüfe, ob das Secret in Gitea **genau gleich** ist (keine Leerzeichen!) +- ✅ Prüfe, ob der Webhook **"application/json"** als Content-Type verwendet + +### Deployment schlägt fehl + +- ✅ Prüfe Server-Logs für detaillierte Fehlermeldungen +- ✅ Prüfe, ob SSH-Zugriff funktioniert: `ssh root@91.99.156.85` +- ✅ Prüfe, ob `npm` und `node` auf dem Server installiert sind +- ✅ Prüfe, ob die Pfade (`DEPLOY_SERVER_PATH`) korrekt sind + +### Frontend-Build fehlgeschlagen + +- ✅ Prüfe, ob alle Dependencies installiert sind: `cd client && npm install` +- ✅ Prüfe, ob `.env.production` korrekt konfiguriert ist +- ✅ Prüfe Build-Logs für TypeScript/ESLint-Fehler + +### Backend startet nicht neu + +- ✅ Prüfe, ob PM2 installiert ist: `pm2 --version` +- ✅ Prüfe, ob `USE_PM2=true` in `.env` gesetzt ist +- ✅ Prüfe PM2-Status: `pm2 list` + +## Sicherheit + +### Best Practices + +1. **Webhook-Secret:** Verwende immer ein starkes, zufälliges Secret +2. **HTTPS:** Stelle sicher, dass dein Server HTTPS verwendet (Let's Encrypt) +3. **Firewall:** Beschränke Webhook-Endpoint auf Gitea-IPs (optional) +4. **Rate Limiting:** Der Webhook-Endpoint ist bereits rate-limited +5. **Logs:** Prüfe regelmäßig die Webhook-Logs auf verdächtige Aktivitäten + +## Alternative: Lokales Deployment ohne Server-Upload + +Falls du den automatischen Upload auf den Server nicht möchtest, kannst du: + +1. `DEPLOY_SERVER_HOST` **nicht** setzen +2. Das Deployment-Skript erstellt nur den Build lokal +3. Du lädst die Dateien manuell hoch oder verwendest ein anderes Tool + +Der Webhook wird trotzdem ausgelöst und erstellt den Build, aber überspringt den Upload-Schritt. + +## Manuelles Deployment auslösen + +Du kannst das Deployment auch manuell auslösen: + +```bash +# Auf dem Server +cd /var/www/emailsorter +node scripts/deploy-to-server.mjs +``` + +## Nächste Schritte + +Nach erfolgreichem Setup: + +1. ✅ Teste den Webhook mit einem kleinen Push +2. ✅ Prüfe, ob die Website aktualisiert wurde +3. ✅ Überwache die Logs für die ersten Deployments +4. ✅ Dokumentiere deine spezifische Konfiguration + +## Support + +Bei Problemen: +- Prüfe die Server-Logs +- Prüfe Gitea Webhook Delivery Logs +- Prüfe die Environment Variables +- Teste SSH-Verbindung manuell diff --git a/docs/deployment/PRODUCTION_FIXES.md b/docs/deployment/PRODUCTION_FIXES.md new file mode 100644 index 0000000..cdf5e09 --- /dev/null +++ b/docs/deployment/PRODUCTION_FIXES.md @@ -0,0 +1,51 @@ +# Production Fixes - Wichtige Schritte + +## ✅ Behoben + +1. **Debug-Logs entfernt** - Alle Debug-Logs zu `127.0.0.1:7242` wurden entfernt +2. **Favicon-Problem behoben** - `site.webmanifest` verwendet jetzt vorhandene SVG-Dateien + +## ⚠️ Noch zu beheben (im Appwrite Dashboard) + +### 1. Appwrite CORS-Konfiguration + +**Problem:** Appwrite erlaubt nur `https://localhost` statt `https://emailsorter.webklar.com` + +**Lösung:** +1. Gehe zu: https://appwrite.webklar.com +2. Öffne dein Projekt +3. Gehe zu **Settings** → **Platforms** (oder **Web**) +4. Füge eine neue Platform hinzu: + - **Name:** Production + - **Hostname:** `emailsorter.webklar.com` + - **Origin:** `https://emailsorter.webklar.com` +5. Speichere die Änderungen + +**ODER** bearbeite die existierende Platform und ändere den Hostname/Origin zu `https://emailsorter.webklar.com` + +### 2. Backend-Server (502 Bad Gateway) + +**Problem:** `/api/analytics/track` gibt 502 zurück - Backend-Server läuft nicht + +**Lösung:** +1. SSH zum Server: `ssh user@webklar.com` +2. Prüfe ob Server läuft: `pm2 list` oder `ps aux | grep node` +3. Falls nicht: Starte den Server: + ```bash + cd /path/to/ANDJJJJJJ/server + pm2 start index.mjs --name emailsorter-api + pm2 save + ``` +4. Prüfe Logs: `pm2 logs emailsorter-api` + +### 3. Build deployen + +Nach dem Commit und Push: +1. Kopiere den Inhalt von `client/dist` auf den Web-Server +2. Stelle sicher, dass die Dateien unter `https://emailsorter.webklar.com` erreichbar sind + +## Nach allen Fixes + +1. Leere den Browser-Cache (Strg+Shift+R) +2. Teste die Website +3. Prüfe die Browser-Konsole - sollte keine Fehler mehr zeigen diff --git a/PRODUCTION_SETUP.md b/docs/deployment/PRODUCTION_SETUP.md similarity index 100% rename from PRODUCTION_SETUP.md rename to docs/deployment/PRODUCTION_SETUP.md diff --git a/docs/deployment/README.md b/docs/deployment/README.md new file mode 100644 index 0000000..0387305 --- /dev/null +++ b/docs/deployment/README.md @@ -0,0 +1,60 @@ +# Deployment-Dokumentation + +Diese Dokumentation beschreibt alle Aspekte des Deployments für E-Mail-Sorter. + +## 📚 Inhaltsverzeichnis + +### Automatisches Deployment + +- **[Gitea Webhook Setup](./GITEA_WEBHOOK_SETUP.md)** - Vollständige Anleitung für automatisches Deployment via Gitea Webhook +- **[Webhook Quick Start](./WEBHOOK_QUICK_START.md)** - Schnellstart-Anleitung (5 Minuten) +- **[Webhook Authorization](./WEBHOOK_AUTHORIZATION.md)** - Authentifizierung und Sicherheit + +### Manuelles Deployment + +- **[Deployment Instructions](./DEPLOYMENT_INSTRUCTIONS.md)** - Manuelle Deployment-Schritte +- **[Production Setup](./PRODUCTION_SETUP.md)** - Production-Server Setup +- **[Production Fixes](./PRODUCTION_FIXES.md)** - Bekannte Probleme und Lösungen + +## 🚀 Schnellstart + +Für automatisches Deployment siehe [Webhook Quick Start](./WEBHOOK_QUICK_START.md). + +## 📋 Übersicht + +### Automatisches Deployment (Empfohlen) + +1. **Gitea Webhook einrichten** → Siehe [GITEA_WEBHOOK_SETUP.md](./GITEA_WEBHOOK_SETUP.md) +2. **Bei jedem Push** wird automatisch deployed +3. **Keine manuellen Schritte** nötig + +### Manuelles Deployment + +1. **Frontend bauen:** `cd client && npm run build` +2. **Dateien hochladen** auf Server +3. **Backend neustarten** (falls nötig) + +Siehe [DEPLOYMENT_INSTRUCTIONS.md](./DEPLOYMENT_INSTRUCTIONS.md) für Details. + +## 🔧 Konfiguration + +Alle Deployment-Konfigurationen finden sich in `server/.env`: + +```bash +# Webhook-Konfiguration +GITEA_WEBHOOK_SECRET=... +GITEA_WEBHOOK_AUTH_TOKEN=... + +# Server-Deployment +DEPLOY_SERVER_HOST=91.99.156.85 +DEPLOY_SERVER_USER=root +DEPLOY_SERVER_PATH=/var/www/emailsorter +USE_PM2=true +``` + +## 📞 Support + +Bei Problemen: +1. Prüfe die Server-Logs +2. Siehe [Production Fixes](./PRODUCTION_FIXES.md) +3. Prüfe Webhook Delivery Logs in Gitea diff --git a/docs/deployment/WEBHOOK_AUTHORIZATION.md b/docs/deployment/WEBHOOK_AUTHORIZATION.md new file mode 100644 index 0000000..8276f82 --- /dev/null +++ b/docs/deployment/WEBHOOK_AUTHORIZATION.md @@ -0,0 +1,83 @@ +# Webhook Authorization Header - Anleitung + +Der Webhook unterstützt **zwei Authentifizierungsmethoden**: + +1. **Signature-Verification** (Standard, von Gitea) +2. **Authorization Header** (Optional, zusätzliche Sicherheit) + +## Option 1: Nur Signature (Standard) + +Das ist die Standard-Methode, die Gitea automatisch verwendet: + +### Konfiguration + +In `server/.env`: +```bash +GITEA_WEBHOOK_SECRET=dein_secret_hier +``` + +### In Gitea + +- **Secret:** Trage das gleiche Secret ein +- **Authorization Header:** Nicht nötig + +Gitea sendet automatisch den `X-Gitea-Signature` Header. + +## Option 2: Authorization Header (Zusätzliche Sicherheit) + +Falls du zusätzliche Sicherheit möchtest oder den Webhook manuell aufrufst: + +### Schritt 1: Token generieren + +```bash +node -e "console.log(require('crypto').randomBytes(16).toString('hex'))" +``` + +### Schritt 2: Server konfigurieren + +In `server/.env`: +```bash +GITEA_WEBHOOK_SECRET=dein_secret_hier +GITEA_WEBHOOK_AUTH_TOKEN=dein_auth_token_hier +``` + +### Schritt 3: In Gitea konfigurieren + +Gitea unterstützt **keine** Authorization Header direkt, aber du kannst: + +#### Option A: Nur Signature verwenden (empfohlen) +- Lass `GITEA_WEBHOOK_AUTH_TOKEN` leer +- Nur `GITEA_WEBHOOK_SECRET` verwenden + +#### Option B: Manuelle Webhook-Aufrufe +Wenn du den Webhook manuell aufrufst (z.B. via curl), verwende: + +```bash +curl -X POST https://emailsorter.webklar.com/api/webhook/gitea \ + -H "Content-Type: application/json" \ + -H "X-Gitea-Signature: sha256=..." \ + -H "Authorization: Bearer dein_auth_token_hier" \ + -d '{"ref":"refs/heads/main",...}' +``` + +## Option 3: Beide Methoden kombinieren + +Für maximale Sicherheit kannst du beide verwenden: + +```bash +# In server/.env +GITEA_WEBHOOK_SECRET=secret_fuer_signature +GITEA_WEBHOOK_AUTH_TOKEN=token_fuer_auth_header +``` + +**Verhalten:** +- Wenn beide gesetzt sind, müssen **beide** passen +- Wenn nur eine gesetzt ist, reicht diese + +## Empfehlung + +**Für Gitea-Webhooks:** Verwende nur `GITEA_WEBHOOK_SECRET` (Signature) + +**Für manuelle Aufrufe:** Verwende `GITEA_WEBHOOK_AUTH_TOKEN` (Authorization Header) + +**Für maximale Sicherheit:** Verwende beide diff --git a/docs/deployment/WEBHOOK_QUICK_START.md b/docs/deployment/WEBHOOK_QUICK_START.md new file mode 100644 index 0000000..9fefc21 --- /dev/null +++ b/docs/deployment/WEBHOOK_QUICK_START.md @@ -0,0 +1,61 @@ +# Gitea Webhook - Quick Start Guide + +## 🚀 Schnellstart (5 Minuten) + +### Schritt 1: Secret generieren + +```bash +node -e "console.log(require('crypto').randomBytes(16).toString('hex'))" +``` + +Kopiere das generierte Secret - du brauchst es gleich! + +### Schritt 2: Server konfigurieren + +Füge zu `server/.env` hinzu: + +```bash +GITEA_WEBHOOK_SECRET=dein_generiertes_secret_hier +DEPLOY_SERVER_HOST=91.99.156.85 +DEPLOY_SERVER_USER=root +DEPLOY_SERVER_PATH=/var/www/emailsorter +USE_PM2=true +``` + +### Schritt 3: Gitea Webhook einrichten + +1. Gehe zu deinem Repository → **Settings** → **Webhooks** +2. Klicke **Add Webhook** → **Gitea** +3. Fülle aus: + - **Target URL:** `https://emailsorter.webklar.com/api/webhook/gitea` + - **Secret:** `dein_generiertes_secret_hier` (aus Schritt 1) + - **Trigger On:** ✅ **Push Events** + - **Branch Filter:** `main` oder `master` +4. Klicke **Add Webhook** + +### Schritt 4: Testen + +```bash +git add . +git commit -m "test: Webhook test" +git push +``` + +Prüfe die Server-Logs - du solltest sehen: +``` +📥 Gitea Webhook empfangen +🚀 Starte Deployment... +✅ Deployment erfolgreich abgeschlossen +``` + +## ✅ Fertig! + +Jetzt wird bei jedem Push automatisch deployed! + +## 📚 Weitere Informationen + +Siehe [GITEA_WEBHOOK_SETUP.md](./GITEA_WEBHOOK_SETUP.md) für: +- Detaillierte Anleitung +- Fehlerbehebung +- Sicherheitsbest Practices +- Server-Upload Konfiguration diff --git a/GIT_AUTHENTICATION_FIX.md b/docs/development/GIT_AUTHENTICATION_FIX.md similarity index 100% rename from GIT_AUTHENTICATION_FIX.md rename to docs/development/GIT_AUTHENTICATION_FIX.md diff --git a/PROJECT_RENAME_GUIDE.md b/docs/development/PROJECT_RENAME_GUIDE.md similarity index 100% rename from PROJECT_RENAME_GUIDE.md rename to docs/development/PROJECT_RENAME_GUIDE.md diff --git a/PROJECT_REVIEW_SUMMARY.md b/docs/development/PROJECT_REVIEW_SUMMARY.md similarity index 100% rename from PROJECT_REVIEW_SUMMARY.md rename to docs/development/PROJECT_REVIEW_SUMMARY.md diff --git a/TASK_5_COMPLETION.md b/docs/development/TASK_5_COMPLETION.md similarity index 100% rename from TASK_5_COMPLETION.md rename to docs/development/TASK_5_COMPLETION.md diff --git a/TESTING_SUMMARY.md b/docs/development/TESTING_SUMMARY.md similarity index 100% rename from TESTING_SUMMARY.md rename to docs/development/TESTING_SUMMARY.md diff --git a/starter-for-react/.env.example b/docs/examples/.env.example similarity index 100% rename from starter-for-react/.env.example rename to docs/examples/.env.example diff --git a/starter-for-react/.gitignore b/docs/examples/.gitignore similarity index 100% rename from starter-for-react/.gitignore rename to docs/examples/.gitignore diff --git a/starter-for-react/LICENSE b/docs/examples/LICENSE similarity index 100% rename from starter-for-react/LICENSE rename to docs/examples/LICENSE diff --git a/starter-for-react/README.md b/docs/examples/README.md similarity index 100% rename from starter-for-react/README.md rename to docs/examples/README.md diff --git a/starter-for-react/eslint.config.js b/docs/examples/eslint.config.js similarity index 100% rename from starter-for-react/eslint.config.js rename to docs/examples/eslint.config.js diff --git a/starter-for-react/index.html b/docs/examples/index.html similarity index 100% rename from starter-for-react/index.html rename to docs/examples/index.html diff --git a/starter-for-react/package-lock.json b/docs/examples/package-lock.json similarity index 100% rename from starter-for-react/package-lock.json rename to docs/examples/package-lock.json diff --git a/starter-for-react/package.json b/docs/examples/package.json similarity index 100% rename from starter-for-react/package.json rename to docs/examples/package.json diff --git a/starter-for-react/public/appwrite.svg b/docs/examples/public/appwrite.svg similarity index 100% rename from starter-for-react/public/appwrite.svg rename to docs/examples/public/appwrite.svg diff --git a/starter-for-react/public/react.svg b/docs/examples/public/react.svg similarity index 100% rename from starter-for-react/public/react.svg rename to docs/examples/public/react.svg diff --git a/starter-for-react/src/App.css b/docs/examples/src/App.css similarity index 100% rename from starter-for-react/src/App.css rename to docs/examples/src/App.css diff --git a/starter-for-react/src/App.jsx b/docs/examples/src/App.jsx similarity index 100% rename from starter-for-react/src/App.jsx rename to docs/examples/src/App.jsx diff --git a/starter-for-react/src/lib/appwrite.js b/docs/examples/src/lib/appwrite.js similarity index 100% rename from starter-for-react/src/lib/appwrite.js rename to docs/examples/src/lib/appwrite.js diff --git a/starter-for-react/src/main.jsx b/docs/examples/src/main.jsx similarity index 100% rename from starter-for-react/src/main.jsx rename to docs/examples/src/main.jsx diff --git a/starter-for-react/vite.config.js b/docs/examples/vite.config.js similarity index 100% rename from starter-for-react/vite.config.js rename to docs/examples/vite.config.js diff --git a/public/cancel.html b/docs/legacy/cancel.html similarity index 100% rename from public/cancel.html rename to docs/legacy/cancel.html diff --git a/public/index.html b/docs/legacy/index.html similarity index 100% rename from public/index.html rename to docs/legacy/index.html diff --git a/public/success.html b/docs/legacy/success.html similarity index 100% rename from public/success.html rename to docs/legacy/success.html diff --git a/server/CORRECTNESS_VALIDATION.md b/docs/server/CORRECTNESS_VALIDATION.md similarity index 100% rename from server/CORRECTNESS_VALIDATION.md rename to docs/server/CORRECTNESS_VALIDATION.md diff --git a/server/E2E_TEST_GUIDE.md b/docs/server/E2E_TEST_GUIDE.md similarity index 100% rename from server/E2E_TEST_GUIDE.md rename to docs/server/E2E_TEST_GUIDE.md diff --git a/server/ENDPOINT_VERIFICATION.md b/docs/server/ENDPOINT_VERIFICATION.md similarity index 100% rename from server/ENDPOINT_VERIFICATION.md rename to docs/server/ENDPOINT_VERIFICATION.md diff --git a/server/FRONTEND_VERIFICATION.md b/docs/server/FRONTEND_VERIFICATION.md similarity index 100% rename from server/FRONTEND_VERIFICATION.md rename to docs/server/FRONTEND_VERIFICATION.md diff --git a/server/MANUAL_TEST_CHECKLIST.md b/docs/server/MANUAL_TEST_CHECKLIST.md similarity index 100% rename from server/MANUAL_TEST_CHECKLIST.md rename to docs/server/MANUAL_TEST_CHECKLIST.md diff --git a/server/TASK_4_COMPLETION_SUMMARY.md b/docs/server/TASK_4_COMPLETION_SUMMARY.md similarity index 100% rename from server/TASK_4_COMPLETION_SUMMARY.md rename to docs/server/TASK_4_COMPLETION_SUMMARY.md diff --git a/APPWRITE_CORS_SETUP.md b/docs/setup/APPWRITE_CORS_SETUP.md similarity index 100% rename from APPWRITE_CORS_SETUP.md rename to docs/setup/APPWRITE_CORS_SETUP.md diff --git a/APPWRITE_SETUP.md b/docs/setup/APPWRITE_SETUP.md similarity index 100% rename from APPWRITE_SETUP.md rename to docs/setup/APPWRITE_SETUP.md diff --git a/client/FAVICON_SETUP.md b/docs/setup/FAVICON_SETUP.md similarity index 100% rename from client/FAVICON_SETUP.md rename to docs/setup/FAVICON_SETUP.md diff --git a/GOOGLE_OAUTH_SETUP.md b/docs/setup/GOOGLE_OAUTH_SETUP.md similarity index 100% rename from GOOGLE_OAUTH_SETUP.md rename to docs/setup/GOOGLE_OAUTH_SETUP.md diff --git a/SETUP_GUIDE.md b/docs/setup/SETUP_GUIDE.md similarity index 100% rename from SETUP_GUIDE.md rename to docs/setup/SETUP_GUIDE.md diff --git a/COMMIT_COMMANDS.txt b/scripts/COMMIT_COMMANDS.txt similarity index 100% rename from COMMIT_COMMANDS.txt rename to scripts/COMMIT_COMMANDS.txt diff --git a/COMMIT_MESSAGE.md b/scripts/COMMIT_MESSAGE.md similarity index 100% rename from COMMIT_MESSAGE.md rename to scripts/COMMIT_MESSAGE.md diff --git a/FINAL_COMMIT.bat b/scripts/FINAL_COMMIT.bat similarity index 100% rename from FINAL_COMMIT.bat rename to scripts/FINAL_COMMIT.bat diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..397470c --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,52 @@ +# Scripts + +Dieser Ordner enthält alle Hilfs-Scripts für das Projekt. + +## 🚀 Aktive Scripts + +### Deployment + +- **deploy-build.js** - Node.js Script für Build-Deployment (veraltet, wird durch Webhook ersetzt) +- **deploy-to-server.mjs** - Automatisches Deployment-Skript (wird vom Webhook aufgerufen) + +### Setup + +- **setup-appwrite.ps1** - Appwrite Setup-Script +- **setup-production.ps1** - Production Setup-Script + +## 📦 Veraltete Scripts (können entfernt werden) + +Die folgenden Scripts sind veraltet und werden nicht mehr benötigt: + +- `git-commit.bat` - Git-Commits sollten direkt über Git gemacht werden +- `git-commit.sh` - Git-Commits sollten direkt über Git gemacht werden +- `git-commit-fix.bat` - Git-Commits sollten direkt über Git gemacht werden +- `FINAL_COMMIT.bat` - Git-Commits sollten direkt über Git gemacht werden +- `run-git-commit.ps1` - Git-Commits sollten direkt über Git gemacht werden +- `COMMIT_COMMANDS.txt` - Temporäre Datei +- `COMMIT_MESSAGE.md` - Temporäre Datei + +**Empfehlung:** Diese Dateien können gelöscht werden, da Git-Commits direkt über `git commit` gemacht werden sollten. + +## 📝 Verwendung + +### Deployment-Script (automatisch) + +Das Deployment-Script wird automatisch vom Webhook-Handler aufgerufen. Siehe `docs/deployment/GITEA_WEBHOOK_SETUP.md` für Details. + +### Setup-Scripts + +```powershell +# Appwrite Setup +.\setup-appwrite.ps1 + +# Production Setup +.\setup-production.ps1 +``` + +## 🔧 Neue Scripts hinzufügen + +Wenn du neue Scripts hinzufügst: +1. Dokumentiere sie in dieser README +2. Füge sie zu `.gitignore` hinzu, falls sie sensible Daten enthalten +3. Stelle sicher, dass sie plattformübergreifend funktionieren (oder dokumentiere Plattform-Anforderungen) diff --git a/deploy-build.js b/scripts/deploy-build.js similarity index 100% rename from deploy-build.js rename to scripts/deploy-build.js diff --git a/git-commit-fix.bat b/scripts/git-commit-fix.bat similarity index 100% rename from git-commit-fix.bat rename to scripts/git-commit-fix.bat diff --git a/git-commit.bat b/scripts/git-commit.bat similarity index 100% rename from git-commit.bat rename to scripts/git-commit.bat diff --git a/git-commit.sh b/scripts/git-commit.sh similarity index 100% rename from git-commit.sh rename to scripts/git-commit.sh diff --git a/run-git-commit.ps1 b/scripts/run-git-commit.ps1 similarity index 87% rename from run-git-commit.ps1 rename to scripts/run-git-commit.ps1 index 2a8e06d..f595816 100644 --- a/run-git-commit.ps1 +++ b/scripts/run-git-commit.ps1 @@ -37,7 +37,7 @@ if (-not $gitExe) { Write-Host "Alternativ führe diese Befehle manuell in Git Bash aus:" -ForegroundColor Yellow Write-Host "cd c:\Users\User\Documents\GitHub\ANDJJJJJJ" -ForegroundColor Cyan Write-Host "git add ." -ForegroundColor Cyan - Write-Host "git commit -m `"feat: Control Panel Redesign v2.0 - Card-basiertes Layout, Side Panels, Dark Mode Fixes, Volle Breite Layout`"" -ForegroundColor Cyan + Write-Host "git commit -m `"feat: Control Panel v2.0 - Cards, Side Panels, Dark Mode, volle Breite`"" -ForegroundColor Cyan Write-Host "git push" -ForegroundColor Cyan exit 1 } @@ -58,7 +58,7 @@ if ($LASTEXITCODE -ne 0) { } Write-Host "Erstelle Commit..." -ForegroundColor Yellow -& $gitExe commit -m "feat: Control Panel Redesign v2.0 - Card-basiertes Layout, Side Panels, Dark Mode Fixes, Volle Breite Layout" +& $gitExe commit -m "feat: Control Panel v2.0 - Cards, Side Panels, Dark Mode, volle Breite" if ($LASTEXITCODE -ne 0) { Write-Host "❌ Fehler beim Commit" -ForegroundColor Red diff --git a/setup-appwrite.ps1 b/scripts/setup-appwrite.ps1 similarity index 100% rename from setup-appwrite.ps1 rename to scripts/setup-appwrite.ps1 diff --git a/setup-production.ps1 b/scripts/setup-production.ps1 similarity index 100% rename from setup-production.ps1 rename to scripts/setup-production.ps1