# Launch Plan – dgray.io ## Release-Phasen | Phase | Preis pro Anzeige | Dauer | Zugang | |-------|-------------------|-------|--------| | **Closed Alpha** | 0,01 € / 0,01 USD / 0,01 CHF | 4–6 Wochen | Nur mit Invite-Code | | **Open Beta** | 0,10 € / 0,10 USD / 0,10 CHF | 3 Monate | Öffentlich, Beta-Banner | | **Launch** | 1 € / 1 USD / 1 CHF | Dauerhaft | Öffentlich | **Pricing-Philosophie:** Die Zahl **1** als magische Zahl — einfach, einprägsam, international gleich. `1 listing = 1 month = 1` --- ## Phase 1: Closed Alpha ### Ziel - Feedback von Crypto/Privacy-Enthusiasten - Payment-Flow testen (1 Cent = echte Transaktion, minimale Kosten) - Bugs finden, UX validieren ### Invite-Code System #### Directus: Collection `invite_codes` | Feld | Typ | Hinweise | |------|-----|----------| | `id` | UUID (auto) | Primary Key | | `code` | String, unique | z.B. `ALPHA-XMR-2026` | | `max_uses` | Integer | Max. Einlösungen (0 = unbegrenzt) | | `used_count` | Integer, default 0 | Aktuelle Einlösungen | | `expires_at` | DateTime, nullable | Optional: Ablaufdatum | | `status` | String, default `active` | `active` / `disabled` | | `date_created` | Timestamp (auto) | | #### Directus: Permissions für `invite_codes` | Rolle | Read | Create | Update | |-------|------|--------|--------| | Public | Nein | Nein | Nein | | Admin | Ja | Ja | Ja | Die Validierung passiert **serverseitig** im PoW-Server (PHP), nicht im Frontend. #### PHP: Invite-Code Validierung Neuer Endpoint: `POST /invite/validate` ```php // pow.dgray.io/invite/validate.php 'Method not allowed']); exit; } $input = json_decode(file_get_contents('php://input'), true); $code = trim($input['code'] ?? ''); if (!$code) { http_response_code(400); echo json_encode(['valid' => false, 'error' => 'Missing invite code']); exit; } // Query Directus for invite code $url = DIRECTUS_URL . '/items/invite_codes?filter[code][_eq]=' . urlencode($code) . '&filter[status][_eq]=active&limit=1'; $context = stream_context_create([ 'http' => [ 'header' => "Authorization: Bearer " . DIRECTUS_TOKEN . "\r\n", 'ignore_errors' => true, ], ]); $response = file_get_contents($url, false, $context); $data = json_decode($response, true); $invite = $data['data'][0] ?? null; if (!$invite) { echo json_encode(['valid' => false, 'error' => 'Invalid or expired invite code']); exit; } // Check max uses if ($invite['max_uses'] > 0 && $invite['used_count'] >= $invite['max_uses']) { echo json_encode(['valid' => false, 'error' => 'Invite code fully redeemed']); exit; } // Check expiry if ($invite['expires_at'] && strtotime($invite['expires_at']) < time()) { echo json_encode(['valid' => false, 'error' => 'Invite code expired']); exit; } // Increment used_count $updateUrl = DIRECTUS_URL . '/items/invite_codes/' . $invite['id']; $updateContext = stream_context_create([ 'http' => [ 'method' => 'PATCH', 'header' => "Content-Type: application/json\r\nAuthorization: Bearer " . DIRECTUS_TOKEN . "\r\n", 'content' => json_encode(['used_count' => $invite['used_count'] + 1]), 'ignore_errors' => true, ], ]); file_get_contents($updateUrl, false, $updateContext); echo json_encode(['valid' => true]); ``` #### Frontend: Invite-Code bei Registrierung In `js/components/auth-modal.js` — im Registrierungs-Flow ein Textfeld hinzufügen: ``` [Invite Code: _________ ] ← nur in Alpha-Phase sichtbar [UUID generieren] ``` Vor `createAccount()` den Code serverseitig validieren: ```js const res = await fetch('https://pow.dgray.io/invite/validate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: inviteCode }) }) const { valid, error } = await res.json() if (!valid) { /* Fehlermeldung anzeigen */ return } ``` #### Feature-Flag In `config.php` ein Flag, um Alpha-Modus zu steuern: ```php define('REQUIRE_INVITE_CODE', true); // false für Open Beta / Launch ``` Im Invoice-Endpoint kann optional der Invite-Code mitgesendet werden, um Alpha-User zu tracken. ### Pricing-Änderung für Alpha In `docs/pow-server/config.php`: ```php // Alpha: 1 Cent define('LISTING_FEE', ['EUR' => 0.01, 'USD' => 0.01, 'CHF' => 0.01, 'GBP' => 0.01, 'JPY' => 2]); ``` ### Verteilung der Invite-Codes - Manuell in Directus erstellen (Admin-Panel) - Verteilen über: - r/Monero, r/privacy - Monero Matrix/IRC Channels - Persönliche Kontakte - **10–20 Codes** mit je 5–10 max_uses → 50–200 Alpha-Tester --- ## Phase 2: Open Beta ### Änderungen 1. **Pricing**: `config.php` → `LISTING_FEE` auf 0,10 setzen 2. **Invite-Code**: `REQUIRE_INVITE_CODE` → `false` 3. **Beta-Banner**: Hinweis auf der Seite ("Beta — Feedback willkommen") 4. **Feedback-Kanal**: Link zu Matrix-Raum oder einfaches Kontaktformular ### Marketing - **Show HN** Post auf Hacker News - r/Monero, r/privacy, r/degoogle — organische Posts - Privacy-Newsletter (PrivacyGuides, Techlore) - Monero-Community (Matrix, IRC) ### Metriken tracken - Anzahl Registrierungen - Anzahl veröffentlichter Anzeigen - Payment Completion Rate - Chat-Nutzung (nur Anzahl, nicht Inhalt) --- ## Phase 3: Launch ### Änderungen 1. **Pricing**: `config.php` → `LISTING_FEE` auf 1 setzen (bereits Standard) 2. **Beta-Banner** entfernen 3. **Invite-Code-System** kann aktiv bleiben (für spätere Promo-Codes nutzbar) ### Kommunikation **"1 listing = 1 month = 1"** — so simpel wie möglich. --- ## Meta-Tags (pro Sprache) Die statischen Meta-Tags in `index.html` sind deutsch (Fallback). Der OG-Proxy (`pow.dgray.io/og-proxy.php`) liefert Listing-spezifische Tags. ### Umgesetzte Texte **Title:** `dgray.io – [Sprache]` | Sprache | Title | Description | |---------|-------|-------------| | **de** | dgray.io – Anonyme Kleinanzeigen | Kaufen und verkaufen ohne Konto, ohne E-Mail. Bezahlung mit Monero. Ende-zu-Ende verschlüsselter Chat. | | **en** | dgray.io – Private Classifieds | Buy and sell without an account, without email. Pay with Monero. End-to-end encrypted chat. | | **fr** | dgray.io – Petites annonces anonymes | Achetez et vendez sans compte, sans e-mail. Paiement en Monero. Chat chiffré de bout en bout. | | **it** | dgray.io – Annunci anonimi | Compra e vendi senza account, senza email. Pagamento in Monero. Chat crittografata end-to-end. | | **es** | dgray.io – Clasificados anónimos | Compra y vende sin cuenta, sin email. Pago con Monero. Chat cifrado de extremo a extremo. | | **pt** | dgray.io – Classificados anônimos | Compre e venda sem conta, sem email. Pagamento com Monero. Chat criptografado ponta a ponta. | | **ru** | dgray.io – Анонимные объявления | Покупайте и продавайте без аккаунта, без email. Оплата Monero. Сквозное шифрование чата. | ### Umsetzung Die `index.html` enthält die Standard-Meta-Tags (de). Für sprachspezifische OG-Tags bei Social-Media-Shares: Der OG-Proxy kann um einen `?lang=` Parameter erweitert werden. Die `i18n.js` `updateDOM()` Methode aktualisiert `document.title`, `og:title/description` und `twitter:title/description` dynamisch bei jedem Sprachwechsel (i18n-Keys `meta.title`, `meta.description`). --- ## Checkliste vor Alpha-Start - [ ] Directus: Collection `invite_codes` anlegen (Schema siehe oben) - [ ] PHP: `invite/validate.php` deployen auf `pow.dgray.io` - [ ] PHP: `config.php` → `LISTING_FEE` auf 0.01 setzen - [ ] PHP: `config.php` → `REQUIRE_INVITE_CODE = true` - [ ] Frontend: Invite-Code-Feld in `auth-modal.js` einbauen - [x] Frontend: Meta-Description i18n-Keys in alle 7 Sprachen - [x] Frontend: Impressum-Seite (Entwurf, alle 7 Sprachen, Platzhalter für Adressdaten) - [x] Frontend: Datenschutz, AGB, Über uns — alle 7 Sprachen - [ ] Rechtliches: Impressum-Platzhalter ausfüllen (Name, Adresse, UID) - [ ] Rechtliches: AGB + Datenschutz durch Fachperson prüfen lassen - [ ] Rechtliches: Gewerbeanmeldung / Einzelunternehmen - [ ] 10–20 Invite-Codes in Directus erstellen - [ ] Codes verteilen (r/Monero, Matrix, persönlich) - [ ] Feedback-Kanal einrichten (Matrix-Raum)