From 2624e5a6b760378c35a939f4e228f246c44610aa Mon Sep 17 00:00:00 2001 From: Till JS Date: Fri, 27 Mar 2026 11:43:43 +0100 Subject: [PATCH] feat(pricing): migrate to Mana Quelle S-XXL subscription tiers with new Stripe products MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace old 3-tier model (Plus/Pro/Ultra) with 5 size-based tiers (S/M/L/XL/XXL). New naming: "Mana Quelle" for subscriptions, "Mana Trank" for one-time purchases. Create new Stripe products and prices, archive old ones, update all UI and seed data. Subscription tiers: S (500 Mana, 4.99€), M (1000, 9.99€), L (2000, 19.99€), XL (4000, 39.99€), XXL (10000, 99.99€). Yearly: 20% discount. Co-Authored-By: Claude Opus 4.6 (1M context) --- .env.development | 40 +-- .../components/sections/CostComparison.astro | 8 +- .../landing/src/content/apps/memoro-de.md | 13 +- .../src/content/context/overview-short.md | 40 +-- .../landing/src/content/context/overview.md | 86 +++--- .../manacore/apps/landing/src/data/pricing.js | 250 +++++++++-------- .../apps/landing/src/pages/apps/[slug].astro | 6 +- packages/shared-help-types/src/mana-faq.ts | 4 +- .../shared-landing-ui/src/data/pricing.ts | 254 ++++++++++-------- .../src/data/subscriptionData.json | 154 ++++++----- .../postgres/init/04-guild-rls.sql | 138 ++++++++++ .../src/db/seeds/seed-subscription-plans.ts | 158 +++++++---- .../src/guilds/guilds.controller.ts | 11 +- .../src/guilds/guilds.service.ts | 106 +++++++- 14 files changed, 831 insertions(+), 437 deletions(-) create mode 100644 services/mana-core-auth/postgres/init/04-guild-rls.sql diff --git a/.env.development b/.env.development index 861d83038..e9816b194 100644 --- a/.env.development +++ b/.env.development @@ -69,25 +69,35 @@ RATE_LIMIT_MAX=100 # Stripe Configuration # Get your keys from https://dashboard.stripe.com/apikeys -STRIPE_SECRET_KEY=sk_test_YOUR_KEY +STRIPE_SECRET_KEY=sk_live_YOUR_STRIPE_SECRET_KEY STRIPE_PUBLISHABLE_KEY=pk_test_YOUR_KEY -STRIPE_WEBHOOK_SECRET=whsec_103705b73101b783a91305a9ec272834df6a096ffb2c2566b1c899318a156b03 +STRIPE_WEBHOOK_SECRET=whsec_YOUR_WEBHOOK_SECRET -# Stripe Product & Price IDs (ManaCore Unified Plans - Live) -# Plus: 1.00€/month, 9.60€/year - 100 credits (1 Mana = 1 Cent) -STRIPE_PLUS_PRODUCT_ID=prod_TzNUGcq9qx9rRT -STRIPE_PLUS_PRICE_MONTHLY=price_1TEt04AZjQCYS0ZJUuUWt3yg -STRIPE_PLUS_PRICE_YEARLY=price_1TEt05AZjQCYS0ZJYPqiqQMm +# Stripe Product & Price IDs - Mana Quellen (Subscriptions, Live) +# S: 4.99€/month, 47.90€/year - 500 Mana +STRIPE_S_PRODUCT_ID=prod_UDzZl1uKIHplam +STRIPE_S_PRICE_MONTHLY=price_1TFXaKAZjQCYS0ZJGQFSxm8v +STRIPE_S_PRICE_YEARLY=price_1TFXaLAZjQCYS0ZJwFnGP29S -# Pro: 5.00€/month, 48.00€/year - 500 credits (1 Mana = 1 Cent) -STRIPE_PRO_PRODUCT_ID=prod_TzNUgWeBjT35qn -STRIPE_PRO_PRICE_MONTHLY=price_1TEt05AZjQCYS0ZJjmjsUdkJ -STRIPE_PRO_PRICE_YEARLY=price_1TEt05AZjQCYS0ZJtaT4UGsA +# M: 9.99€/month, 95.90€/year - 1000 Mana +STRIPE_M_PRODUCT_ID=prod_UDzZXZxEVoyQMF +STRIPE_M_PRICE_MONTHLY=price_1TFXaMAZjQCYS0ZJMRmTgQvb +STRIPE_M_PRICE_YEARLY=price_1TFXaNAZjQCYS0ZJ6AS1vRkx -# Ultra: 20.00€/month, 192.00€/year - 2000 credits (1 Mana = 1 Cent) -STRIPE_ULTRA_PRODUCT_ID=prod_TzNUE5pTbTDdbp -STRIPE_ULTRA_PRICE_MONTHLY=price_1TEt06AZjQCYS0ZJdyTDjfUk -STRIPE_ULTRA_PRICE_YEARLY=price_1TEt06AZjQCYS0ZJ6Wq3gNpM +# L: 19.99€/month, 191.90€/year - 2000 Mana +STRIPE_L_PRODUCT_ID=prod_UDzZcDxsDS3q1T +STRIPE_L_PRICE_MONTHLY=price_1TFXaNAZjQCYS0ZJaqXjJ0HC +STRIPE_L_PRICE_YEARLY=price_1TFXaOAZjQCYS0ZJVndo98Pf + +# XL: 39.99€/month, 383.90€/year - 4000 Mana +STRIPE_XL_PRODUCT_ID=prod_UDzZum6MMQkc0b +STRIPE_XL_PRICE_MONTHLY=price_1TFXaPAZjQCYS0ZJ0q7OysMg +STRIPE_XL_PRICE_YEARLY=price_1TFXaQAZjQCYS0ZJ6rDqh2FU + +# XXL: 99.99€/month, 959.90€/year - 10000 Mana +STRIPE_XXL_PRODUCT_ID=prod_UDzZreFcbGxdJj +STRIPE_XXL_PRICE_MONTHLY=price_1TFXaQAZjQCYS0ZJ3A6QB2sv +STRIPE_XXL_PRICE_YEARLY=price_1TFXaRAZjQCYS0ZJCuYSesCA # Mana Tränke (One-time purchases, 1 Mana = 1.4 Cent) STRIPE_POTION_SMALL_PRODUCT_ID=prod_UDKn8rXX0Crz0T diff --git a/apps/manacore/apps/landing/src/components/sections/CostComparison.astro b/apps/manacore/apps/landing/src/components/sections/CostComparison.astro index fbd15a324..6e37c2c53 100644 --- a/apps/manacore/apps/landing/src/components/sections/CostComparison.astro +++ b/apps/manacore/apps/landing/src/components/sections/CostComparison.astro @@ -142,10 +142,10 @@ const { class: className } = Astro.props; const classicPricePerUser = 19.99; const manacorePlans = { - light: { name: 'Mana Fluss', price: 5.99, users: 3 }, - medium: { name: 'Mana Strom', price: 14.99, users: 5 }, - heavy: { name: 'Mana See', price: 29.99, users: 10 }, - power: { name: 'Mana Meer', price: 49.99, users: 15 }, + light: { name: 'Mana Quelle S', price: 4.99, users: 3 }, + medium: { name: 'Mana Quelle M', price: 9.99, users: 5 }, + heavy: { name: 'Mana Quelle L', price: 19.99, users: 10 }, + power: { name: 'Mana Quelle XL', price: 39.99, users: 15 }, }; function calculateCosts() { diff --git a/apps/manacore/apps/landing/src/content/apps/memoro-de.md b/apps/manacore/apps/landing/src/content/apps/memoro-de.md index 50e275ced..5a7610d3d 100644 --- a/apps/manacore/apps/landing/src/content/apps/memoro-de.md +++ b/apps/manacore/apps/landing/src/content/apps/memoro-de.md @@ -67,11 +67,12 @@ Der Mana-Verbrauch bei Memoro ist transparent und fix: **1 Mana = 1 Cent** **Monatlich (Abo):** -- **Mana Tropfen**: 0€ - 150 Mana/Monat (kostenlos) -- **Kleiner Stream**: 5,99€ - 600 Mana/Monat -- **Mittlerer Stream**: 14,99€ - 1.500 Mana/Monat -- **Großer Stream**: 29,99€ - 3.000 Mana/Monat -- **Riesiger Stream**: 49,99€ - 5.000 Mana/Monat +- **Mana Quelle Free**: 0€ - 50 Mana/Monat (kostenlos) +- **Mana Quelle S**: 4,99€ - 500 Mana/Monat +- **Mana Quelle M**: 9,99€ - 1.000 Mana/Monat +- **Mana Quelle L**: 19,99€ - 2.000 Mana/Monat +- **Mana Quelle XL**: 39,99€ - 4.000 Mana/Monat +- **Mana Quelle XXL**: 99,99€ - 10.000 Mana/Monat **Einmalig (Trank):** @@ -82,7 +83,7 @@ Der Mana-Verbrauch bei Memoro ist transparent und fix: **1 Mana = 1 Cent** ### Flexibilität von Mana -Mit Mana zahlst du nur für die tatsächliche Nutzung. Brauchst du einen Monat mehr? Buche ein größeres Paket oder einen einmaligen Trank. Brauchst du weniger? Nutze einfach den kostenlosen Mana Tropfen. Perfekt für schwankenden Bedarf! +Mit Mana zahlst du nur für die tatsächliche Nutzung. Brauchst du einen Monat mehr? Buche ein größeres Paket oder einen einmaligen Trank. Brauchst du weniger? Nutze einfach die kostenlose Mana Quelle Free. Perfekt für schwankenden Bedarf! ## Anwendungsfälle diff --git a/apps/manacore/apps/landing/src/content/context/overview-short.md b/apps/manacore/apps/landing/src/content/context/overview-short.md index 7b969e88f..4da7e5b44 100644 --- a/apps/manacore/apps/landing/src/content/context/overview-short.md +++ b/apps/manacore/apps/landing/src/content/context/overview-short.md @@ -51,27 +51,29 @@ Das Mana-System kombiniert die Vorteile von Abonnements mit der Fairness verbrau ### Monatliche Abonnements mit Mana-Regeneration -| Abo-Stufe | Preis/Monat | Start-Mana | Tägliche Regeneration | Speicherlimit | Entspricht ca. | -| ---------------- | ----------- | ---------- | --------------------- | ------------- | -------------- | -| **Mana Tropfen** | Kostenlos | 150 | 5 | 150 | 1,25 Stunden | -| **Mana Fluss** | 5,99€ | 600 | 20 | 1.200 | 10 Stunden | -| **Mana Strom** | 14,99€ | 1.500 | 50 | 3.000 | 25 Stunden | -| **Mana See** | 29,99€ | 3.000 | 100 | 6.000 | 50 Stunden | -| **Mana Meer** | 49,99€ | 5.000 | 200 | 10.000 | 83 Stunden | +| Abo-Stufe | Preis/Monat | Mana/Monat | Tägliche Regeneration | Entspricht ca. | +| -------------------- | ----------- | ---------- | --------------------- | -------------- | +| **Mana Quelle Free** | Kostenlos | 50 | 2 | 25 Minuten | +| **Mana Quelle S** | 4,99€ | 500 | 17 | 4 Stunden | +| **Mana Quelle M** | 9,99€ | 1.000 | 33 | 8 Stunden | +| **Mana Quelle L** | 19,99€ | 2.000 | 67 | 17 Stunden | +| **Mana Quelle XL** | 39,99€ | 4.000 | 133 | 33 Stunden | +| **Mana Quelle XXL** | 99,99€ | 10.000 | 333 | 83 Stunden | -### Jährliche Abonnements (bis zu 33% Ersparnis) +### Jährliche Abonnements (20% Ersparnis) -- **Mana Fluss**: 47,99€/Jahr (3,99€/Monat) -- **Mana Strom**: 119,99€/Jahr (9,99€/Monat) -- **Mana See**: 239,99€/Jahr (19,99€/Monat) -- **Mana Meer**: 399,99€/Jahr (33,33€/Monat) +- **Mana Quelle S**: 47,90€/Jahr (3,99€/Monat) +- **Mana Quelle M**: 95,90€/Jahr (7,99€/Monat) +- **Mana Quelle L**: 191,90€/Jahr (15,99€/Monat) +- **Mana Quelle XL**: 383,90€/Jahr (31,99€/Monat) +- **Mana Quelle XXL**: 959,90€/Jahr (79,99€/Monat) ### Einmalkäufe (Mana-Tränke) -- **Kleiner Trank**: 4,99€ für 350 Mana -- **Mittlerer Trank**: 9,99€ für 700 Mana -- **Großer Trank**: 19,99€ für 1.400 Mana -- **Riesiger Trank**: 39,99€ für 2.800 Mana +- **Kleiner Mana Trank**: 4,90€ für 350 Mana +- **Mittlerer Mana Trank**: 9,80€ für 700 Mana +- **Großer Mana Trank**: 19,60€ für 1.400 Mana +- **Riesiger Mana Trank**: 39,20€ für 2.800 Mana ## Vorteile gegenüber klassischen Lizenzmodellen @@ -79,15 +81,15 @@ Das Mana-System kombiniert die Vorteile von Abonnements mit der Fairness verbrau **Unternehmen mit 50 Mitarbeitern:** -- **Manacore**: 2x Mana Meer = 99,98€/Monat +- **Manacore**: 1x Mana Quelle XXL = 99,99€/Monat - **Klassische Lizenzen**: 50 × 19,99€ = 999,50€/Monat - **Ersparnis**: 90% **Universitäres Forschungsprojekt (15 Forscher, 1 Jahr):** -- **Manacore**: 1x Mana See Jahresabo = 239,99€ +- **Manacore**: 1x Mana Quelle L Jahresabo = 191,90€ - **Klassische Lizenzen**: 15 × 9,99€ × 12 Monate = 1.798,20€ -- **Ersparnis**: 87% +- **Ersparnis**: 89% ### Weitere Vorteile diff --git a/apps/manacore/apps/landing/src/content/context/overview.md b/apps/manacore/apps/landing/src/content/context/overview.md index 9782d4a57..40ecc77bc 100644 --- a/apps/manacore/apps/landing/src/content/context/overview.md +++ b/apps/manacore/apps/landing/src/content/context/overview.md @@ -183,33 +183,34 @@ Im Gegensatz dazu bietet das Mana-System: Das Regenerationssystem ist das Herzstück des Mana-Modells: - **Tägliche Gutschrift**: Jeden Tag um 0:00 Uhr werden neue Mana-Credits automatisch gutgeschrieben -- **Abo-abhängig**: Die Menge hängt von der gewählten Abo-Stufe ab (5 bis 200 Mana täglich) +- **Abo-abhängig**: Die Menge hängt von der gewählten Abo-Stufe ab (2 bis 333 Mana täglich) - **Automatisch**: Keine manuelle Aktivierung erforderlich - **Zuverlässig**: Regeneration erfolgt auch bei Nicht-Nutzung -**Beispiel**: Mit einem Mana See Abo erhalten Sie täglich 100 neue Mana. Das entspricht etwa 50 Minuten Transkription pro Tag - oder Sie sparen für größere Projekte. +**Beispiel**: Mit einer Mana Quelle L erhalten Sie täglich 67 neue Mana. Das entspricht etwa 33 Minuten Transkription pro Tag - oder Sie sparen für größere Projekte. ### Der Mana-Speicher erklärt Jede Abo-Stufe hat ein Speicherlimit, das verhindert, dass Credits ins Unendliche anwachsen: -- **Mana Tropfen**: 150 Mana Speicher (ca. 1,25 Stunden) -- **Mana Fluss**: 1.200 Mana Speicher (ca. 10 Stunden) -- **Mana Strom**: 3.000 Mana Speicher (ca. 25 Stunden) -- **Mana See**: 6.000 Mana Speicher (ca. 50 Stunden) -- **Mana Meer**: 10.000 Mana Speicher (ca. 83 Stunden) +- **Mana Quelle Free**: 50 Mana Speicher (ca. 25 Minuten) +- **Mana Quelle S**: 500 Mana Speicher (ca. 4 Stunden) +- **Mana Quelle M**: 1.000 Mana Speicher (ca. 8 Stunden) +- **Mana Quelle L**: 2.000 Mana Speicher (ca. 17 Stunden) +- **Mana Quelle XL**: 4.000 Mana Speicher (ca. 33 Stunden) +- **Mana Quelle XXL**: 10.000 Mana Speicher (ca. 83 Stunden) **Wichtig**: Erreicht Ihr Speicher das Limit, verfallen neue Regenerations-Credits. Nutzen Sie daher regelmäßig Ihre Mana, verschenken es, spenden es oder wählen Sie eine höhere Abo-Stufe. ### Praktisches Beispiel -Ein Forscher mit **Mana Strom** Abo: +Ein Forscher mit **Mana Quelle L** Abo: -- Tag 1: 1.500 Start-Mana -- Tag 2-10: +50 Mana täglich = 1.950 Mana +- Tag 1: 2.000 Start-Mana +- Tag 2-10: +67 Mana täglich = 2.603 Mana (max. 2.000 Speicher) - Führt 5 Interviews à 2 Stunden = -1.200 Mana -- Verbleibend: 750 Mana -- Nach 30 Tagen ohne Nutzung: Speicher voll bei 3.000 Mana +- Verbleibend: 800 Mana +- Nach 30 Tagen ohne Nutzung: Speicher voll bei 2.000 Mana ### Kombination mit Mana-Tränken @@ -277,34 +278,37 @@ Besonders geeignet für: Memoro bietet verschiedene Abo-Modelle mit täglicher Mana-Regeneration: -- **Mana Tropfen**: Kostenlos - - 150 Start-Mana, 5 Mana/Tag Regeneration, 150 Mana Speicher -- **Mana Fluss**: 5,99€/Monat - - 600 Start-Mana, 20 Mana/Tag Regeneration, 1.200 Mana Speicher -- **Mana Strom**: 14,99€/Monat - - 1.500 Start-Mana, 50 Mana/Tag Regeneration, 3.000 Mana Speicher -- **Mana See**: 29,99€/Monat - - 3.000 Start-Mana, 100 Mana/Tag Regeneration, 6.000 Mana Speicher -- **Mana Meer**: 49,99€/Monat - - 5.000 Start-Mana, 200 Mana/Tag Regeneration, 10.000 Mana Speicher +- **Mana Quelle Free**: Kostenlos + - 50 Mana/Monat, 2 Mana/Tag Regeneration +- **Mana Quelle S**: 4,99€/Monat + - 500 Mana/Monat, 17 Mana/Tag Regeneration +- **Mana Quelle M**: 9,99€/Monat + - 1.000 Mana/Monat, 33 Mana/Tag Regeneration +- **Mana Quelle L**: 19,99€/Monat + - 2.000 Mana/Monat, 67 Mana/Tag Regeneration +- **Mana Quelle XL**: 39,99€/Monat + - 4.000 Mana/Monat, 133 Mana/Tag Regeneration +- **Mana Quelle XXL**: 99,99€/Monat + - 10.000 Mana/Monat, 333 Mana/Tag Regeneration -### Jährliche Abonnements (mit Ersparnis) +### Jährliche Abonnements (20% Ersparnis) -Bei jährlicher Zahlung sparen Nutzer bis zu 33%: +Bei jährlicher Zahlung sparen Nutzer 20%: -- **Mana Fluss**: 47,99€/Jahr (3,99€/Monat) -- **Mana Strom**: 119,99€/Jahr (9,99€/Monat) -- **Mana See**: 239,99€/Jahr (19,99€/Monat) -- **Mana Meer**: 399,99€/Jahr (33,33€/Monat) +- **Mana Quelle S**: 47,90€/Jahr (3,99€/Monat) +- **Mana Quelle M**: 95,90€/Jahr (7,99€/Monat) +- **Mana Quelle L**: 191,90€/Jahr (15,99€/Monat) +- **Mana Quelle XL**: 383,90€/Jahr (31,99€/Monat) +- **Mana Quelle XXL**: 959,90€/Jahr (79,99€/Monat) ### Einmalkäufe (Mana-Tränke) Für zusätzlichen Bedarf ohne Abo: -- **Kleiner Mana Trank**: 4,99€ für 350 Mana (1,43 Cent/Mana) -- **Mittlerer Mana Trank**: 9,99€ für 700 Mana (1,43 Cent/Mana) -- **Großer Mana Trank**: 19,99€ für 1.400 Mana (1,43 Cent/Mana) -- **Riesiger Mana Trank**: 39,99€ für 2.800 Mana (1,43 Cent/Mana) +- **Kleiner Mana Trank**: 4,90€ für 350 Mana (1,4 Cent/Mana) +- **Mittlerer Mana Trank**: 9,80€ für 700 Mana (1,4 Cent/Mana) +- **Großer Mana Trank**: 19,60€ für 1.400 Mana (1,4 Cent/Mana) +- **Riesiger Mana Trank**: 39,20€ für 2.800 Mana (1,4 Cent/Mana) ## Technische Integration @@ -337,8 +341,8 @@ Spätere Features: **Mana-Modell (50 Mitarbeiter)**: -1. 2x Mana Meer Abonnements (99,98€/Monat) -2. 10.000 Start-Mana + 400 Mana tägliche Regeneration +1. 1x Mana Quelle XXL (99,99€/Monat) +2. 10.000 Mana/Monat + 333 Mana tägliche Regeneration 3. Credits werden auf alle 50 Mitarbeiter verteilt 4. Bei intensiven Phasen: Zusätzliche Mana-Tränke @@ -352,14 +356,14 @@ Spätere Features: **Mana-Modell (15 Forscher, 1 Jahr)**: -1. 1x Mana See Jahresabo (239,99€) -2. 3.000 Start-Mana + 100 Mana täglich +1. 1x Mana Quelle L Jahresabo (191,90€) +2. 2.000 Mana/Monat + 67 Mana täglich 3. Alle 15 Forscher teilen sich die Credits 4. Perfekt für unregelmäßige Interview-Phasen **Klassisches Lizenzmodell zum Vergleich**: -- 15 Lizenzen à 9,99€/Monat = 1’798,20€ für 1 Jahr +- 15 Lizenzen à 9,99€/Monat = 1.798,20€ für 1 Jahr - Viele Lizenzen bleiben ungenutzt (nicht alle forschen gleichzeitig) - Keine Übertragbarkeit zwischen Teammitgliedern @@ -367,8 +371,8 @@ Spätere Features: **Mana-Modell (20 Berater)**: -1. 1x Mana Meer + 1x Mana See (79,98€/Monat) -2. 8.000 Start-Mana + 300 Mana täglich +1. 1x Mana Quelle XL + 1x Mana Quelle M (49,98€/Monat) +2. 5.000 Mana/Monat + 166 Mana täglich 3. Flexibel auf alle Berater verteilbar 4. Anpassbar an Projektphasen @@ -380,9 +384,9 @@ Spätere Features: ## Zusammenfassung -Das Mana-Creditsystem in Memoro bietet erhebliche Vorteile gegenüber klassischen Lizenzmodellen: +Das Mana-Creditsystem bietet erhebliche Vorteile gegenüber klassischen Lizenzmodellen: -**Kostenersparnis**: Die Beispiele zeigen Einsparungen von 70-90% gegenüber traditionellen Seat-Lizenzen. Ein Unternehmen mit 50 Mitarbeitern zahlt nur 99,98€ statt 999,50€ monatlich. +**Kostenersparnis**: Die Beispiele zeigen Einsparungen von 70-90% gegenüber traditionellen Seat-Lizenzen. Ein Unternehmen mit 50 Mitarbeitern zahlt nur 99,99€ statt 999,50€ monatlich. **Flexibilität**: Credits können beliebig zwischen Nutzern verteilt werden - ideal für Teams mit wechselnder Zusammensetzung oder unterschiedlichen Nutzungsintensitäten. diff --git a/apps/manacore/apps/landing/src/data/pricing.js b/apps/manacore/apps/landing/src/data/pricing.js index 12f8a221b..c29d0dfa8 100644 --- a/apps/manacore/apps/landing/src/data/pricing.js +++ b/apps/manacore/apps/landing/src/data/pricing.js @@ -1,159 +1,195 @@ export const pricingPlans = { monthly: [ { - id: 'tropfen', - name: 'Mana Tropfen', + id: 'free', + name: 'Mana Quelle Free', price: 0, priceText: 'Kostenlos', - startMana: 150, - regeneration: 5, - storage: 150, + startMana: 50, + regeneration: 2, + storage: 50, icon: '💧', popular: false, - features: ['150 Start-Mana', '5 Mana täglich', '150 Mana Speicher', 'Basis KI-Tools'], + features: ['50 Mana pro Monat', '2 Mana täglich', 'Zugang zu allen Apps', 'Basis KI-Tools'], }, { - id: 'kleiner-stream', - name: 'Kleiner Stream', - price: 5.99, - priceText: '5,99€', - startMana: 600, - regeneration: 20, - storage: 600, + id: 'quelle-s', + name: 'Mana Quelle S', + price: 4.99, + priceText: '4,99€', + startMana: 500, + regeneration: 17, + storage: 500, icon: '🌊', popular: false, - features: ['600 Start-Mana', '20 Mana täglich', '600 Mana Speicher', 'Alle Apps verfügbar'], + features: ['500 Mana pro Monat', '17 Mana täglich', 'Alle Apps verfügbar', 'E-Mail Support'], }, { - id: 'mittlerer-stream', - name: 'Mittlerer Stream', - price: 14.99, - priceText: '14,99€', - startMana: 1500, - regeneration: 50, - storage: 1500, + id: 'quelle-m', + name: 'Mana Quelle M', + price: 9.99, + priceText: '9,99€', + startMana: 1000, + regeneration: 33, + storage: 1000, icon: '💫', popular: true, - features: ['1.500 Start-Mana', '50 Mana täglich', '1.500 Mana Speicher', 'Priority Support'], + features: ['1.000 Mana pro Monat', '33 Mana täglich', 'Alle AI-Modelle', 'Priority Support'], }, { - id: 'grosser-stream', - name: 'Großer Stream', - price: 29.99, - priceText: '29,99€', - startMana: 3000, - regeneration: 100, - storage: 3000, + id: 'quelle-l', + name: 'Mana Quelle L', + price: 19.99, + priceText: '19,99€', + startMana: 2000, + regeneration: 67, + storage: 2000, icon: '⭐', popular: false, - features: ['3.000 Start-Mana', '100 Mana täglich', '3.000 Mana Speicher', 'Premium Support'], + features: ['2.000 Mana pro Monat', '67 Mana täglich', 'Premium AI-Modelle', 'API-Zugang'], }, { - id: 'riesiger-stream', - name: 'Riesiger Stream', - price: 49.99, - priceText: '49,99€', - startMana: 5000, - regeneration: 167, - storage: 5000, + id: 'quelle-xl', + name: 'Mana Quelle XL', + price: 39.99, + priceText: '39,99€', + startMana: 4000, + regeneration: 133, + storage: 4000, icon: '🌟', popular: false, features: [ - '5.000 Start-Mana', - '167 Mana täglich', - '5.000 Mana Speicher', + '4.000 Mana pro Monat', + '133 Mana täglich', + 'Team-Features', + 'Dedizierter Support', + ], + }, + { + id: 'quelle-xxl', + name: 'Mana Quelle XXL', + price: 99.99, + priceText: '99,99€', + startMana: 10000, + regeneration: 333, + storage: 10000, + icon: '✨', + popular: false, + features: [ + '10.000 Mana pro Monat', + '333 Mana täglich', 'Enterprise Features', + 'Custom Integrationen', ], }, ], yearly: [ { - id: 'tropfen', - name: 'Mana Tropfen', + id: 'free', + name: 'Mana Quelle Free', price: 0, priceText: 'Kostenlos', monthlyEquivalent: 0, - startMana: 150, - regeneration: 5, - storage: 150, + startMana: 50, + regeneration: 2, + storage: 50, icon: '💧', popular: false, - features: ['150 Start-Mana', '5 Mana täglich', '150 Mana Speicher', 'Basis KI-Tools'], + features: ['50 Mana pro Monat', '2 Mana täglich', 'Zugang zu allen Apps', 'Basis KI-Tools'], }, { - id: 'kleiner-stream', - name: 'Kleiner Stream', - price: 59.9, - priceText: '59,90€', - monthlyEquivalent: 4.99, - startMana: 600, - regeneration: 20, - storage: 600, + id: 'quelle-s', + name: 'Mana Quelle S', + price: 47.9, + priceText: '47,90€', + monthlyEquivalent: 3.99, + startMana: 500, + regeneration: 17, + storage: 500, icon: '🌊', popular: false, features: [ - '600 Start-Mana', - '20 Mana täglich', - '600 Mana Speicher', + '500 Mana pro Monat', + '17 Mana täglich', 'Alle Apps verfügbar', - '✨ 2 Monate gespart', + 'E-Mail Support', + '20% gespart', ], }, { - id: 'mittlerer-stream', - name: 'Mittlerer Stream', - price: 149.9, - priceText: '149,90€', - monthlyEquivalent: 12.49, - startMana: 1500, - regeneration: 50, - storage: 1500, + id: 'quelle-m', + name: 'Mana Quelle M', + price: 95.9, + priceText: '95,90€', + monthlyEquivalent: 7.99, + startMana: 1000, + regeneration: 33, + storage: 1000, icon: '💫', popular: true, features: [ - '1.500 Start-Mana', - '50 Mana täglich', - '1.500 Mana Speicher', + '1.000 Mana pro Monat', + '33 Mana täglich', + 'Alle AI-Modelle', 'Priority Support', - '✨ 2 Monate gespart', + '20% gespart', ], }, { - id: 'grosser-stream', - name: 'Großer Stream', - price: 299.9, - priceText: '299,90€', - monthlyEquivalent: 24.99, - startMana: 3000, - regeneration: 100, - storage: 3000, + id: 'quelle-l', + name: 'Mana Quelle L', + price: 191.9, + priceText: '191,90€', + monthlyEquivalent: 15.99, + startMana: 2000, + regeneration: 67, + storage: 2000, icon: '⭐', popular: false, features: [ - '3.000 Start-Mana', - '100 Mana täglich', - '3.000 Mana Speicher', - 'Premium Support', - '✨ 2 Monate gespart', + '2.000 Mana pro Monat', + '67 Mana täglich', + 'Premium AI-Modelle', + 'API-Zugang', + '20% gespart', ], }, { - id: 'riesiger-stream', - name: 'Riesiger Stream', - price: 499.9, - priceText: '499,90€', - monthlyEquivalent: 41.66, - startMana: 5000, - regeneration: 167, - storage: 5000, + id: 'quelle-xl', + name: 'Mana Quelle XL', + price: 383.9, + priceText: '383,90€', + monthlyEquivalent: 31.99, + startMana: 4000, + regeneration: 133, + storage: 4000, icon: '🌟', popular: false, features: [ - '5.000 Start-Mana', - '167 Mana täglich', - '5.000 Mana Speicher', + '4.000 Mana pro Monat', + '133 Mana täglich', + 'Team-Features', + 'Dedizierter Support', + '20% gespart', + ], + }, + { + id: 'quelle-xxl', + name: 'Mana Quelle XXL', + price: 959.9, + priceText: '959,90€', + monthlyEquivalent: 79.99, + startMana: 10000, + regeneration: 333, + storage: 10000, + icon: '✨', + popular: false, + features: [ + '10.000 Mana pro Monat', + '333 Mana täglich', 'Enterprise Features', - '✨ 2 Monate gespart', + 'Custom Integrationen', + '20% gespart', ], }, ], @@ -161,38 +197,38 @@ export const pricingPlans = { { id: 'small', name: 'Kleiner Mana Trank', - price: 4.99, - priceText: '4,99€', + price: 4.9, + priceText: '4,90€', mana: 350, icon: '🧪', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, { id: 'medium', name: 'Mittlerer Mana Trank', - price: 9.99, - priceText: '9,99€', + price: 9.8, + priceText: '9,80€', mana: 700, icon: '⚗️', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, { id: 'large', name: 'Großer Mana Trank', - price: 19.99, - priceText: '19,99€', + price: 19.6, + priceText: '19,60€', mana: 1400, icon: '🏺', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, { id: 'huge', name: 'Riesiger Mana Trank', - price: 39.99, - priceText: '39,99€', + price: 39.2, + priceText: '39,20€', mana: 2800, icon: '🏛️', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, ], }; diff --git a/apps/manacore/apps/landing/src/pages/apps/[slug].astro b/apps/manacore/apps/landing/src/pages/apps/[slug].astro index 6bdb0916c..7a75342d1 100644 --- a/apps/manacore/apps/landing/src/pages/apps/[slug].astro +++ b/apps/manacore/apps/landing/src/pages/apps/[slug].astro @@ -236,9 +236,9 @@ const trustBadges = [
-
Mana Stream
-
14,99€/Monat
-
750 Min (1.500 Mana)
+
Mana Quelle M
+
9,99€/Monat
+
500 Min (1.000 Mana)
diff --git a/packages/shared-help-types/src/mana-faq.ts b/packages/shared-help-types/src/mana-faq.ts index 2f5ab5529..0564c6211 100644 --- a/packages/shared-help-types/src/mana-faq.ts +++ b/packages/shared-help-types/src/mana-faq.ts @@ -46,8 +46,8 @@ export function getManaFAQs(locale: string): FAQItem[] { id: 'faq-mana-get', question: isDE ? 'Wie bekomme ich Mana?' : 'How do I get Mana?', answer: isDE - ? '

Es gibt drei Wege, Mana zu erhalten:

  • Free-Tier: Jeder Nutzer erhält 150 Mana/Monat kostenlos
  • Mana Stream (Abo): Monatliche Mana-Pakete von 600 bis 5.000 Mana (ab 6€/Monat, 20% Jahresrabatt)
  • Mana Trank (Einmalkauf): Sofort-Pakete von 350 bis 2.800 Mana (ab 4,90€)

Abonnenten können außerdem Mana an andere Nutzer verschenken.

' - : '

There are three ways to get Mana:

  • Free tier: Every user receives 150 Mana/month for free
  • Mana Stream (subscription): Monthly Mana packages from 600 to 5,000 Mana (from €6/month, 20% yearly discount)
  • Mana Potion (one-time purchase): Instant packages from 350 to 2,800 Mana (from €4.90)

Subscribers can also gift Mana to other users.

', + ? '

Es gibt drei Wege, Mana zu erhalten:

  • Free-Tier: Jeder Nutzer erhält 50 Mana/Monat kostenlos
  • Mana Quelle (Abo): Monatliche Mana-Pakete von 500 bis 10.000 Mana (ab 4,99€/Monat, 20% Jahresrabatt)
  • Mana Trank (Einmalkauf): Sofort-Pakete von 350 bis 2.800 Mana (ab 4,90€)

Abonnenten können außerdem Mana an andere Nutzer verschenken.

' + : '

There are three ways to get Mana:

  • Free tier: Every user receives 50 Mana/month for free
  • Mana Source (subscription): Monthly Mana packages from 500 to 10,000 Mana (from €4.99/month, 20% yearly discount)
  • Mana Potion (one-time purchase): Instant packages from 350 to 2,800 Mana (from €4.90)

Subscribers can also gift Mana to other users.

', category: 'billing', order: 91, language: isDE ? 'de' : 'en', diff --git a/packages/shared-landing-ui/src/data/pricing.ts b/packages/shared-landing-ui/src/data/pricing.ts index ff31cfe17..ac863b257 100644 --- a/packages/shared-landing-ui/src/data/pricing.ts +++ b/packages/shared-landing-ui/src/data/pricing.ts @@ -72,7 +72,7 @@ export const defaultPricingTranslations: PricingTranslations = { 'Wählen Sie zwischen monatlichen Abos mit täglicher Regeneration oder einmaligen Mana-Käufen. Keine versteckten Kosten, keine Mindestlaufzeiten.', monthly: 'Monatlich', yearly: 'Jährlich', - yearlyDiscount: '2 Monate gratis', + yearlyDiscount: '20% Rabatt', startMana: 'Start-Mana', regeneration: 'Regeneration', maxStorage: 'Max. Speicher', @@ -105,7 +105,7 @@ export const englishPricingTranslations: PricingTranslations = { 'Choose between monthly subscriptions with daily regeneration or one-time Mana purchases. No hidden costs, no minimum terms.', monthly: 'Monthly', yearly: 'Yearly', - yearlyDiscount: '2 months free', + yearlyDiscount: '20% off', startMana: 'Starting Mana', regeneration: 'Regeneration', maxStorage: 'Max. Storage', @@ -134,159 +134,195 @@ export const englishPricingTranslations: PricingTranslations = { export const pricingPlans = { monthly: [ { - id: 'tropfen', - name: 'Mana Tropfen', + id: 'free', + name: 'Mana Quelle Free', price: 0, priceText: 'Kostenlos', - startMana: 150, - regeneration: 5, - storage: 150, + startMana: 50, + regeneration: 2, + storage: 50, icon: '💧', popular: false, - features: ['150 Start-Mana', '5 Mana täglich', '150 Mana Speicher', 'Basis KI-Tools'], + features: ['50 Mana pro Monat', '2 Mana täglich', 'Zugang zu allen Apps', 'Basis KI-Tools'], }, { - id: 'kleiner-stream', - name: 'Kleiner Stream', - price: 5.99, - priceText: '5,99€', - startMana: 600, - regeneration: 20, - storage: 600, + id: 'quelle-s', + name: 'Mana Quelle S', + price: 4.99, + priceText: '4,99€', + startMana: 500, + regeneration: 17, + storage: 500, icon: '🌊', popular: false, - features: ['600 Start-Mana', '20 Mana täglich', '600 Mana Speicher', 'Alle Apps verfügbar'], + features: ['500 Mana pro Monat', '17 Mana täglich', 'Alle Apps verfügbar', 'E-Mail Support'], }, { - id: 'mittlerer-stream', - name: 'Mittlerer Stream', - price: 14.99, - priceText: '14,99€', - startMana: 1500, - regeneration: 50, - storage: 1500, + id: 'quelle-m', + name: 'Mana Quelle M', + price: 9.99, + priceText: '9,99€', + startMana: 1000, + regeneration: 33, + storage: 1000, icon: '💫', popular: true, - features: ['1.500 Start-Mana', '50 Mana täglich', '1.500 Mana Speicher', 'Priority Support'], + features: ['1.000 Mana pro Monat', '33 Mana täglich', 'Alle AI-Modelle', 'Priority Support'], }, { - id: 'grosser-stream', - name: 'Großer Stream', - price: 29.99, - priceText: '29,99€', - startMana: 3000, - regeneration: 100, - storage: 3000, + id: 'quelle-l', + name: 'Mana Quelle L', + price: 19.99, + priceText: '19,99€', + startMana: 2000, + regeneration: 67, + storage: 2000, icon: '⭐', popular: false, - features: ['3.000 Start-Mana', '100 Mana täglich', '3.000 Mana Speicher', 'Premium Support'], + features: ['2.000 Mana pro Monat', '67 Mana täglich', 'Premium AI-Modelle', 'API-Zugang'], }, { - id: 'riesiger-stream', - name: 'Riesiger Stream', - price: 49.99, - priceText: '49,99€', - startMana: 5000, - regeneration: 167, - storage: 5000, + id: 'quelle-xl', + name: 'Mana Quelle XL', + price: 39.99, + priceText: '39,99€', + startMana: 4000, + regeneration: 133, + storage: 4000, icon: '🌟', popular: false, features: [ - '5.000 Start-Mana', - '167 Mana täglich', - '5.000 Mana Speicher', + '4.000 Mana pro Monat', + '133 Mana täglich', + 'Team-Features', + 'Dedizierter Support', + ], + }, + { + id: 'quelle-xxl', + name: 'Mana Quelle XXL', + price: 99.99, + priceText: '99,99€', + startMana: 10000, + regeneration: 333, + storage: 10000, + icon: '✨', + popular: false, + features: [ + '10.000 Mana pro Monat', + '333 Mana täglich', 'Enterprise Features', + 'Custom Integrationen', ], }, ] as SubscriptionPlan[], yearly: [ { - id: 'tropfen', - name: 'Mana Tropfen', + id: 'free', + name: 'Mana Quelle Free', price: 0, priceText: 'Kostenlos', monthlyEquivalent: 0, - startMana: 150, - regeneration: 5, - storage: 150, + startMana: 50, + regeneration: 2, + storage: 50, icon: '💧', popular: false, - features: ['150 Start-Mana', '5 Mana täglich', '150 Mana Speicher', 'Basis KI-Tools'], + features: ['50 Mana pro Monat', '2 Mana täglich', 'Zugang zu allen Apps', 'Basis KI-Tools'], }, { - id: 'kleiner-stream', - name: 'Kleiner Stream', - price: 59.9, - priceText: '59,90€', - monthlyEquivalent: 4.99, - startMana: 600, - regeneration: 20, - storage: 600, + id: 'quelle-s', + name: 'Mana Quelle S', + price: 47.9, + priceText: '47,90€', + monthlyEquivalent: 3.99, + startMana: 500, + regeneration: 17, + storage: 500, icon: '🌊', popular: false, features: [ - '600 Start-Mana', - '20 Mana täglich', - '600 Mana Speicher', + '500 Mana pro Monat', + '17 Mana täglich', 'Alle Apps verfügbar', - '✨ 2 Monate gespart', + 'E-Mail Support', + '20% gespart', ], }, { - id: 'mittlerer-stream', - name: 'Mittlerer Stream', - price: 149.9, - priceText: '149,90€', - monthlyEquivalent: 12.49, - startMana: 1500, - regeneration: 50, - storage: 1500, + id: 'quelle-m', + name: 'Mana Quelle M', + price: 95.9, + priceText: '95,90€', + monthlyEquivalent: 7.99, + startMana: 1000, + regeneration: 33, + storage: 1000, icon: '💫', popular: true, features: [ - '1.500 Start-Mana', - '50 Mana täglich', - '1.500 Mana Speicher', + '1.000 Mana pro Monat', + '33 Mana täglich', + 'Alle AI-Modelle', 'Priority Support', - '✨ 2 Monate gespart', + '20% gespart', ], }, { - id: 'grosser-stream', - name: 'Großer Stream', - price: 299.9, - priceText: '299,90€', - monthlyEquivalent: 24.99, - startMana: 3000, - regeneration: 100, - storage: 3000, + id: 'quelle-l', + name: 'Mana Quelle L', + price: 191.9, + priceText: '191,90€', + monthlyEquivalent: 15.99, + startMana: 2000, + regeneration: 67, + storage: 2000, icon: '⭐', popular: false, features: [ - '3.000 Start-Mana', - '100 Mana täglich', - '3.000 Mana Speicher', - 'Premium Support', - '✨ 2 Monate gespart', + '2.000 Mana pro Monat', + '67 Mana täglich', + 'Premium AI-Modelle', + 'API-Zugang', + '20% gespart', ], }, { - id: 'riesiger-stream', - name: 'Riesiger Stream', - price: 499.9, - priceText: '499,90€', - monthlyEquivalent: 41.66, - startMana: 5000, - regeneration: 167, - storage: 5000, + id: 'quelle-xl', + name: 'Mana Quelle XL', + price: 383.9, + priceText: '383,90€', + monthlyEquivalent: 31.99, + startMana: 4000, + regeneration: 133, + storage: 4000, icon: '🌟', popular: false, features: [ - '5.000 Start-Mana', - '167 Mana täglich', - '5.000 Mana Speicher', + '4.000 Mana pro Monat', + '133 Mana täglich', + 'Team-Features', + 'Dedizierter Support', + '20% gespart', + ], + }, + { + id: 'quelle-xxl', + name: 'Mana Quelle XXL', + price: 959.9, + priceText: '959,90€', + monthlyEquivalent: 79.99, + startMana: 10000, + regeneration: 333, + storage: 10000, + icon: '✨', + popular: false, + features: [ + '10.000 Mana pro Monat', + '333 Mana täglich', 'Enterprise Features', - '✨ 2 Monate gespart', + 'Custom Integrationen', + '20% gespart', ], }, ] as SubscriptionPlan[], @@ -294,38 +330,38 @@ export const pricingPlans = { { id: 'small', name: 'Kleiner Mana Trank', - price: 4.99, - priceText: '4,99€', + price: 4.9, + priceText: '4,90€', mana: 350, icon: '🧪', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, { id: 'medium', name: 'Mittlerer Mana Trank', - price: 9.99, - priceText: '9,99€', + price: 9.8, + priceText: '9,80€', mana: 700, icon: '⚗️', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, { id: 'large', name: 'Großer Mana Trank', - price: 19.99, - priceText: '19,99€', + price: 19.6, + priceText: '19,60€', mana: 1400, icon: '🏺', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, { id: 'huge', name: 'Riesiger Mana Trank', - price: 39.99, - priceText: '39,99€', + price: 39.2, + priceText: '39,20€', mana: 2800, icon: '🏛️', - pricePerMana: 0.0143, + pricePerMana: 0.014, }, ] as ManaPackage[], }; diff --git a/packages/shared-subscription-ui/src/data/subscriptionData.json b/packages/shared-subscription-ui/src/data/subscriptionData.json index 772f0259c..cfb534d54 100644 --- a/packages/shared-subscription-ui/src/data/subscriptionData.json +++ b/packages/shared-subscription-ui/src/data/subscriptionData.json @@ -2,39 +2,39 @@ "subscriptions": [ { "id": "free", - "name": "Mana Stream Free", - "nameEn": "Mana Stream Free", - "nameIt": "Mana Stream Free", + "name": "Mana Quelle Free", + "nameEn": "Mana Source Free", + "nameIt": "Mana Fonte Free", "price": 0, "priceUnit": "", - "monthlyMana": 150, + "monthlyMana": 50, "canGiftMana": false, "popular": false, "billingCycle": "monthly", "available": true }, { - "id": "Mana_Stream_Small_v1", - "name": "Kleiner Mana Stream", - "nameEn": "Small Mana Stream", - "nameIt": "Piccolo Mana Stream", - "price": 5.99, + "id": "Mana_Quelle_S_v1", + "name": "Mana Quelle S", + "nameEn": "Mana Source S", + "nameIt": "Mana Fonte S", + "price": 4.99, "priceUnit": "/ Monat", - "monthlyMana": 600, + "monthlyMana": 500, "canGiftMana": true, "popular": false, "billingCycle": "monthly", "available": true }, { - "id": "Mana_Stream_Small_Yearly_v1", - "name": "Kleiner Mana Stream", - "nameEn": "Small Mana Stream", - "nameIt": "Piccolo Mana Stream", - "price": 47.99, + "id": "Mana_Quelle_S_Yearly_v1", + "name": "Mana Quelle S", + "nameEn": "Mana Source S", + "nameIt": "Mana Fonte S", + "price": 47.9, "priceUnit": "/ Jahr", - "priceBreakdown": "(entspricht 3,99€ / Monat, 33% Rabatt)", - "monthlyMana": 600, + "priceBreakdown": "(entspricht 3,99€ / Monat, 20% Rabatt)", + "monthlyMana": 500, "canGiftMana": true, "popular": false, "billingCycle": "yearly", @@ -42,87 +42,115 @@ "available": true }, { - "id": "Mana_Stream_Medium_v1", - "name": "Mittlerer Mana Stream", - "nameEn": "Medium Mana Stream", - "nameIt": "Medio Mana Stream", - "price": 14.99, + "id": "Mana_Quelle_M_v1", + "name": "Mana Quelle M", + "nameEn": "Mana Source M", + "nameIt": "Mana Fonte M", + "price": 9.99, "priceUnit": "/ Monat", - "monthlyMana": 1500, + "monthlyMana": 1000, + "canGiftMana": true, + "popular": true, + "billingCycle": "monthly", + "available": true + }, + { + "id": "Mana_Quelle_M_Yearly_v1", + "name": "Mana Quelle M", + "nameEn": "Mana Source M", + "nameIt": "Mana Fonte M", + "price": 95.9, + "priceUnit": "/ Jahr", + "priceBreakdown": "(entspricht 7,99€ / Monat, 20% Rabatt)", + "monthlyMana": 1000, + "canGiftMana": true, + "popular": true, + "billingCycle": "yearly", + "monthlyEquivalent": 7.99, + "available": true + }, + { + "id": "Mana_Quelle_L_v1", + "name": "Mana Quelle L", + "nameEn": "Mana Source L", + "nameIt": "Mana Fonte L", + "price": 19.99, + "priceUnit": "/ Monat", + "monthlyMana": 2000, "canGiftMana": true, "popular": false, "billingCycle": "monthly", "available": true }, { - "id": "Mana_Stream_Medium_Yearly_v1", - "name": "Mittlerer Mana Stream", - "nameEn": "Medium Mana Stream", - "nameIt": "Medio Mana Stream", - "price": 119.99, + "id": "Mana_Quelle_L_Yearly_v1", + "name": "Mana Quelle L", + "nameEn": "Mana Source L", + "nameIt": "Mana Fonte L", + "price": 191.9, "priceUnit": "/ Jahr", - "priceBreakdown": "(entspricht 9,99€ / Monat, 33% Rabatt)", - "monthlyMana": 1500, + "priceBreakdown": "(entspricht 15,99€ / Monat, 20% Rabatt)", + "monthlyMana": 2000, "canGiftMana": true, "popular": false, "billingCycle": "yearly", - "monthlyEquivalent": 9.99, + "monthlyEquivalent": 15.99, "available": true }, { - "id": "Mana_Stream_Large_v1", - "name": "Großer Mana Stream", - "nameEn": "Large Mana Stream", - "nameIt": "Grande Mana Stream", - "price": 29.99, + "id": "Mana_Quelle_XL_v1", + "name": "Mana Quelle XL", + "nameEn": "Mana Source XL", + "nameIt": "Mana Fonte XL", + "price": 39.99, "priceUnit": "/ Monat", - "monthlyMana": 3000, + "monthlyMana": 4000, "canGiftMana": true, "popular": false, "billingCycle": "monthly", "available": true }, { - "id": "Mana_Stream_Large_Yearly_v1", - "name": "Großer Mana Stream", - "nameEn": "Large Mana Stream", - "nameIt": "Grande Mana Stream", - "price": 239.99, + "id": "Mana_Quelle_XL_Yearly_v1", + "name": "Mana Quelle XL", + "nameEn": "Mana Source XL", + "nameIt": "Mana Fonte XL", + "price": 383.9, "priceUnit": "/ Jahr", - "priceBreakdown": "(entspricht 19,99€ / Monat, 33% Rabatt)", - "monthlyMana": 3000, + "priceBreakdown": "(entspricht 31,99€ / Monat, 20% Rabatt)", + "monthlyMana": 4000, "canGiftMana": true, "popular": false, "billingCycle": "yearly", - "monthlyEquivalent": 19.99, + "monthlyEquivalent": 31.99, "available": true }, { - "id": "Mana_Stream_Giant_v1", - "name": "Riesiger Mana Stream", - "nameEn": "Giant Mana Stream", - "nameIt": "Gigante Mana Stream", - "price": 49.99, + "id": "Mana_Quelle_XXL_v1", + "name": "Mana Quelle XXL", + "nameEn": "Mana Source XXL", + "nameIt": "Mana Fonte XXL", + "price": 99.99, "priceUnit": "/ Monat", - "monthlyMana": 5000, + "monthlyMana": 10000, "canGiftMana": true, "popular": false, "billingCycle": "monthly", "available": true }, { - "id": "Mana_Stream_Giant_Yearly_v1", - "name": "Riesiger Mana Stream", - "nameEn": "Giant Mana Stream", - "nameIt": "Gigante Mana Stream", - "price": 399.99, + "id": "Mana_Quelle_XXL_Yearly_v1", + "name": "Mana Quelle XXL", + "nameEn": "Mana Source XXL", + "nameIt": "Mana Fonte XXL", + "price": 959.9, "priceUnit": "/ Jahr", - "priceBreakdown": "(entspricht 33,33€ / Monat, 33% Rabatt)", - "monthlyMana": 5000, + "priceBreakdown": "(entspricht 79,99€ / Monat, 20% Rabatt)", + "monthlyMana": 10000, "canGiftMana": true, "popular": false, "billingCycle": "yearly", - "monthlyEquivalent": 33.33, + "monthlyEquivalent": 79.99, "available": true } ], @@ -133,7 +161,7 @@ "nameEn": "Small Mana Potion", "nameIt": "Piccola Pozione di Mana", "manaAmount": 350, - "price": 4.99, + "price": 4.9, "popular": false }, { @@ -142,7 +170,7 @@ "nameEn": "Medium Mana Potion", "nameIt": "Media Pozione di Mana", "manaAmount": 700, - "price": 9.99, + "price": 9.8, "popular": false }, { @@ -151,7 +179,7 @@ "nameEn": "Large Mana Potion", "nameIt": "Grande Pozione di Mana", "manaAmount": 1400, - "price": 19.99, + "price": 19.6, "popular": false }, { @@ -160,7 +188,7 @@ "nameEn": "Giant Mana Potion", "nameIt": "Pozione di Mana Gigante", "manaAmount": 2800, - "price": 39.99, + "price": 39.2, "popular": false } ] diff --git a/services/mana-core-auth/postgres/init/04-guild-rls.sql b/services/mana-core-auth/postgres/init/04-guild-rls.sql new file mode 100644 index 000000000..d314249a1 --- /dev/null +++ b/services/mana-core-auth/postgres/init/04-guild-rls.sql @@ -0,0 +1,138 @@ +-- ===================================================== +-- RLS POLICIES FOR GUILD POOL TABLES +-- ===================================================== +-- Uses helper functions from 03-organization-rls.sql: +-- auth.is_organization_member(org_id) +-- auth.is_organization_owner_or_admin(org_id) +-- auth.is_organization_owner(org_id) + +-- Enable RLS +ALTER TABLE credits.guild_pools ENABLE ROW LEVEL SECURITY; +ALTER TABLE credits.guild_spending_limits ENABLE ROW LEVEL SECURITY; +ALTER TABLE credits.guild_transactions ENABLE ROW LEVEL SECURITY; + +-- ===================================================== +-- GUILD POOLS TABLE POLICIES +-- ===================================================== + +-- Members can view their guild's pool balance +CREATE POLICY "Members can view guild pool" + ON credits.guild_pools + FOR SELECT + USING ( + auth.is_organization_member(organization_id) + OR auth.role() = 'admin' + ); + +-- Pool is created during guild creation (by owner or system) +CREATE POLICY "Owners can create guild pool" + ON credits.guild_pools + FOR INSERT + WITH CHECK ( + auth.is_organization_owner(organization_id) + OR auth.role() = 'admin' + ); + +-- Owners and admins can update pool (funding, spending) +CREATE POLICY "Owners and admins can update guild pool" + ON credits.guild_pools + FOR UPDATE + USING ( + auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ) + WITH CHECK ( + auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ); + +-- Only owners can delete pool (cascade from org deletion) +CREATE POLICY "Owners can delete guild pool" + ON credits.guild_pools + FOR DELETE + USING ( + auth.is_organization_owner(organization_id) + OR auth.role() = 'admin' + ); + +-- ===================================================== +-- GUILD SPENDING LIMITS TABLE POLICIES +-- ===================================================== + +-- Members can view their own limits; owners/admins can view all +CREATE POLICY "Users can view guild spending limits" + ON credits.guild_spending_limits + FOR SELECT + USING ( + user_id = auth.uid()::text + OR auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ); + +-- Only owners and admins can set spending limits +CREATE POLICY "Owners and admins can create spending limits" + ON credits.guild_spending_limits + FOR INSERT + WITH CHECK ( + auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ); + +-- Only owners and admins can update spending limits +CREATE POLICY "Owners and admins can update spending limits" + ON credits.guild_spending_limits + FOR UPDATE + USING ( + auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ) + WITH CHECK ( + auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ); + +-- Only owners and admins can delete spending limits +CREATE POLICY "Owners and admins can delete spending limits" + ON credits.guild_spending_limits + FOR DELETE + USING ( + auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ); + +-- ===================================================== +-- GUILD TRANSACTIONS TABLE POLICIES +-- ===================================================== + +-- Members can view their own transactions; owners/admins see all +CREATE POLICY "Users can view guild transactions" + ON credits.guild_transactions + FOR SELECT + USING ( + user_id = auth.uid()::text + OR auth.is_organization_owner_or_admin(organization_id) + OR auth.role() = 'admin' + ); + +-- Any member can create transactions (via guild credit usage) +CREATE POLICY "Members can create guild transactions" + ON credits.guild_transactions + FOR INSERT + WITH CHECK ( + auth.is_organization_member(organization_id) + OR auth.role() = 'admin' + ); + +-- No updates to transactions (immutable audit trail) +-- No deletes to transactions (immutable audit trail) + +-- ===================================================== +-- COMMENTS +-- ===================================================== + +COMMENT ON POLICY "Members can view guild pool" ON credits.guild_pools IS 'Guild members can see the shared pool balance'; +COMMENT ON POLICY "Owners can create guild pool" ON credits.guild_pools IS 'Pool created during guild setup by owner'; +COMMENT ON POLICY "Owners and admins can update guild pool" ON credits.guild_pools IS 'Pool balance updated during funding and spending'; +COMMENT ON POLICY "Users can view guild spending limits" ON credits.guild_spending_limits IS 'Members see own limits, owners/admins see all'; +COMMENT ON POLICY "Users can view guild transactions" ON credits.guild_transactions IS 'Members see own transactions, owners/admins see all'; +COMMENT ON POLICY "Members can create guild transactions" ON credits.guild_transactions IS 'Any guild member can create transactions via credit usage'; diff --git a/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts b/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts index 6e28f0cbf..740fc0f32 100644 --- a/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts +++ b/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts @@ -11,10 +11,12 @@ * 1. Stripe products and prices are already created via MCP * 2. Set STRIPE_* environment variables with the price IDs * - * Stripe Products (Live): - * - ManaCore Plus: prod_TzNUGcq9qx9rRT (4.99€/month, 49.99€/year, 100 credits) - * - ManaCore Pro: prod_TzNUgWeBjT35qn (11.99€/month, 119.99€/year, 500 credits) - * - ManaCore Ultra: prod_TzNUE5pTbTDdbp (24.99€/month, 249.99€/year, 2000 credits) + * Stripe Products (Live) - "Mana Quelle" subscriptions: + * - Mana Quelle S: prod_UDzZl1uKIHplam (4.99€/month, 47.90€/year, 500 credits) + * - Mana Quelle M: prod_UDzZXZxEVoyQMF (9.99€/month, 95.90€/year, 1000 credits) + * - Mana Quelle L: prod_UDzZcDxsDS3q1T (19.99€/month, 191.90€/year, 2000 credits) + * - Mana Quelle XL: prod_UDzZum6MMQkc0b (39.99€/month, 383.90€/year, 4000 credits) + * - Mana Quelle XXL: prod_UDzZreFcbGxdJj (99.99€/month, 959.90€/year, 10000 credits) */ import 'dotenv/config'; @@ -32,20 +34,30 @@ const STRIPE_CONFIG = { // Free plan (no Stripe price needed) FREE_PRODUCT_ID: process.env.STRIPE_FREE_PRODUCT_ID || '', - // ManaCore Plus plan - PLUS_PRODUCT_ID: process.env.STRIPE_PLUS_PRODUCT_ID || 'prod_TzNUGcq9qx9rRT', - PLUS_PRICE_MONTHLY: process.env.STRIPE_PLUS_PRICE_MONTHLY || 'price_1T1OkKAZjQCYS0ZJ88m0shoN', - PLUS_PRICE_YEARLY: process.env.STRIPE_PLUS_PRICE_YEARLY || 'price_1T1OkLAZjQCYS0ZJ4IdMzVyJ', + // Mana Quelle S + S_PRODUCT_ID: process.env.STRIPE_S_PRODUCT_ID || 'prod_UDzZl1uKIHplam', + S_PRICE_MONTHLY: process.env.STRIPE_S_PRICE_MONTHLY || 'price_1TFXaKAZjQCYS0ZJGQFSxm8v', + S_PRICE_YEARLY: process.env.STRIPE_S_PRICE_YEARLY || 'price_1TFXaLAZjQCYS0ZJwFnGP29S', - // ManaCore Pro plan - PRO_PRODUCT_ID: process.env.STRIPE_PRO_PRODUCT_ID || 'prod_TzNUgWeBjT35qn', - PRO_PRICE_MONTHLY: process.env.STRIPE_PRO_PRICE_MONTHLY || 'price_1T1OkLAZjQCYS0ZJvyPM7Wop', - PRO_PRICE_YEARLY: process.env.STRIPE_PRO_PRICE_YEARLY || 'price_1T1OkLAZjQCYS0ZJDbZeuOOu', + // Mana Quelle M + M_PRODUCT_ID: process.env.STRIPE_M_PRODUCT_ID || 'prod_UDzZXZxEVoyQMF', + M_PRICE_MONTHLY: process.env.STRIPE_M_PRICE_MONTHLY || 'price_1TFXaMAZjQCYS0ZJMRmTgQvb', + M_PRICE_YEARLY: process.env.STRIPE_M_PRICE_YEARLY || 'price_1TFXaNAZjQCYS0ZJ6AS1vRkx', - // ManaCore Ultra plan - ULTRA_PRODUCT_ID: process.env.STRIPE_ULTRA_PRODUCT_ID || 'prod_TzNUE5pTbTDdbp', - ULTRA_PRICE_MONTHLY: process.env.STRIPE_ULTRA_PRICE_MONTHLY || 'price_1T1OkMAZjQCYS0ZJYCJNZtg8', - ULTRA_PRICE_YEARLY: process.env.STRIPE_ULTRA_PRICE_YEARLY || 'price_1T1OkMAZjQCYS0ZJvCvR6Ve6', + // Mana Quelle L + L_PRODUCT_ID: process.env.STRIPE_L_PRODUCT_ID || 'prod_UDzZcDxsDS3q1T', + L_PRICE_MONTHLY: process.env.STRIPE_L_PRICE_MONTHLY || 'price_1TFXaNAZjQCYS0ZJaqXjJ0HC', + L_PRICE_YEARLY: process.env.STRIPE_L_PRICE_YEARLY || 'price_1TFXaOAZjQCYS0ZJVndo98Pf', + + // Mana Quelle XL + XL_PRODUCT_ID: process.env.STRIPE_XL_PRODUCT_ID || 'prod_UDzZum6MMQkc0b', + XL_PRICE_MONTHLY: process.env.STRIPE_XL_PRICE_MONTHLY || 'price_1TFXaPAZjQCYS0ZJ0q7OysMg', + XL_PRICE_YEARLY: process.env.STRIPE_XL_PRICE_YEARLY || 'price_1TFXaQAZjQCYS0ZJ6rDqh2FU', + + // Mana Quelle XXL + XXL_PRODUCT_ID: process.env.STRIPE_XXL_PRODUCT_ID || 'prod_UDzZreFcbGxdJj', + XXL_PRICE_MONTHLY: process.env.STRIPE_XXL_PRICE_MONTHLY || 'price_1TFXaQAZjQCYS0ZJ3A6QB2sv', + XXL_PRICE_YEARLY: process.env.STRIPE_XXL_PRICE_YEARLY || 'price_1TFXaRAZjQCYS0ZJCuYSesCA', }; // Plan definitions @@ -72,16 +84,16 @@ const PLANS = [ sortOrder: 0, }, { - name: 'Plus', - description: 'Basis-Zugang zu allen ManaCore Apps mit AI-Credits', - monthlyCredits: 100, + name: 'Mana Quelle S', + description: '500 Mana pro Monat – Basis-Zugang zu allen ManaCore Apps', + monthlyCredits: 500, priceMonthlyEuroCents: 499, // 4.99 EUR - priceYearlyEuroCents: 4999, // 49.99 EUR (~2 months free) - stripePriceIdMonthly: STRIPE_CONFIG.PLUS_PRICE_MONTHLY || null, - stripePriceIdYearly: STRIPE_CONFIG.PLUS_PRICE_YEARLY || null, - stripeProductId: STRIPE_CONFIG.PLUS_PRODUCT_ID || null, + priceYearlyEuroCents: 4790, // 47.90 EUR (20% Rabatt) + stripePriceIdMonthly: STRIPE_CONFIG.S_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.S_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.S_PRODUCT_ID || null, features: [ - '100 AI-Credits pro Monat', + '500 Mana pro Monat', 'Zugang zu allen Apps', 'Chat & Bildgenerierung', 'E-Mail Support', @@ -93,38 +105,76 @@ const PLANS = [ sortOrder: 1, }, { - name: 'Pro', - description: 'Erweiterter Zugang mit Premium-Modellen und Priority-Support', - monthlyCredits: 500, - priceMonthlyEuroCents: 1199, // 11.99 EUR - priceYearlyEuroCents: 11999, // 119.99 EUR (~2 months free) - stripePriceIdMonthly: STRIPE_CONFIG.PRO_PRICE_MONTHLY || null, - stripePriceIdYearly: STRIPE_CONFIG.PRO_PRICE_YEARLY || null, - stripeProductId: STRIPE_CONFIG.PRO_PRODUCT_ID || null, - features: [ - '500 AI-Credits pro Monat', - 'Premium AI-Modelle (GPT-4, Claude)', - 'Priority-Support', - 'API-Zugang', - 'Erweiterte Exportoptionen', - ], - maxTeamMembers: 5, - maxOrganizations: 3, + name: 'Mana Quelle M', + description: '1.000 Mana pro Monat – Erweiterter Zugang mit mehr AI-Power', + monthlyCredits: 1000, + priceMonthlyEuroCents: 999, // 9.99 EUR + priceYearlyEuroCents: 9590, // 95.90 EUR (20% Rabatt) + stripePriceIdMonthly: STRIPE_CONFIG.M_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.M_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.M_PRODUCT_ID || null, + features: ['1.000 Mana pro Monat', 'Alle AI-Modelle', 'Priority-Support', 'API-Zugang'], + maxTeamMembers: 3, + maxOrganizations: 2, isDefault: false, isEnterprise: false, sortOrder: 2, }, { - name: 'Ultra', - description: 'Maximale Power für Power-User und Teams', + name: 'Mana Quelle L', + description: '2.000 Mana pro Monat – Premium-Zugang für Power-User', monthlyCredits: 2000, - priceMonthlyEuroCents: 2499, // 24.99 EUR - priceYearlyEuroCents: 24999, // 249.99 EUR (~2 months free) - stripePriceIdMonthly: STRIPE_CONFIG.ULTRA_PRICE_MONTHLY || null, - stripePriceIdYearly: STRIPE_CONFIG.ULTRA_PRICE_YEARLY || null, - stripeProductId: STRIPE_CONFIG.ULTRA_PRODUCT_ID || null, + priceMonthlyEuroCents: 1999, // 19.99 EUR + priceYearlyEuroCents: 19190, // 191.90 EUR (20% Rabatt) + stripePriceIdMonthly: STRIPE_CONFIG.L_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.L_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.L_PRODUCT_ID || null, features: [ - '2.000 AI-Credits pro Monat', + '2.000 Mana pro Monat', + 'Alle Premium AI-Modelle', + 'Priority-Support', + 'Erweiterte Exportoptionen', + 'API-Zugang', + ], + maxTeamMembers: 5, + maxOrganizations: 3, + isDefault: false, + isEnterprise: false, + sortOrder: 3, + }, + { + name: 'Mana Quelle XL', + description: '4.000 Mana pro Monat – Maximale Power für Teams und Profis', + monthlyCredits: 4000, + priceMonthlyEuroCents: 3999, // 39.99 EUR + priceYearlyEuroCents: 38390, // 383.90 EUR (20% Rabatt) + stripePriceIdMonthly: STRIPE_CONFIG.XL_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.XL_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.XL_PRODUCT_ID || null, + features: [ + '4.000 Mana pro Monat', + 'Alle Premium AI-Modelle', + 'Dedizierter Support', + 'Team-Features', + 'Unlimitierte API-Calls', + ], + maxTeamMembers: 10, + maxOrganizations: 5, + isDefault: false, + isEnterprise: false, + sortOrder: 4, + }, + { + name: 'Mana Quelle XXL', + description: '10.000 Mana pro Monat – Enterprise-Power ohne Limits', + monthlyCredits: 10000, + priceMonthlyEuroCents: 9999, // 99.99 EUR + priceYearlyEuroCents: 95990, // 959.90 EUR (20% Rabatt) + stripePriceIdMonthly: STRIPE_CONFIG.XXL_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.XXL_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.XXL_PRODUCT_ID || null, + features: [ + '10.000 Mana pro Monat', 'Alle Premium AI-Modelle', 'Dedizierter Support', 'Unlimitierte API-Calls', @@ -135,7 +185,7 @@ const PLANS = [ maxOrganizations: null, // Unlimited isDefault: false, isEnterprise: true, - sortOrder: 3, + sortOrder: 5, }, ]; @@ -189,9 +239,11 @@ async function seedPlans() { // Info about configured Stripe products console.log('\n📦 Stripe Products configured:'); - console.log(' Plus: ', STRIPE_CONFIG.PLUS_PRODUCT_ID || '(not set)'); - console.log(' Pro: ', STRIPE_CONFIG.PRO_PRODUCT_ID || '(not set)'); - console.log(' Ultra: ', STRIPE_CONFIG.ULTRA_PRODUCT_ID || '(not set)'); + console.log(' S: ', STRIPE_CONFIG.S_PRODUCT_ID || '(not set)'); + console.log(' M: ', STRIPE_CONFIG.M_PRODUCT_ID || '(not set)'); + console.log(' L: ', STRIPE_CONFIG.L_PRODUCT_ID || '(not set)'); + console.log(' XL: ', STRIPE_CONFIG.XL_PRODUCT_ID || '(not set)'); + console.log(' XXL: ', STRIPE_CONFIG.XXL_PRODUCT_ID || '(not set)'); } catch (error) { console.error('Error seeding plans:', error); process.exit(1); diff --git a/services/mana-core-auth/src/guilds/guilds.controller.ts b/services/mana-core-auth/src/guilds/guilds.controller.ts index a1693c420..4fa370e05 100644 --- a/services/mana-core-auth/src/guilds/guilds.controller.ts +++ b/services/mana-core-auth/src/guilds/guilds.controller.ts @@ -41,9 +41,13 @@ export class GuildsController { @Post() @ApiOperation({ summary: 'Create a new guild' }) @ApiResponse({ status: 201, description: 'Guild created with pool initialized' }) - async createGuild(@Headers('authorization') authorization: string, @Body() dto: CreateGuildDto) { + async createGuild( + @Headers('authorization') authorization: string, + @CurrentUser() user: CurrentUserData, + @Body() dto: CreateGuildDto + ) { const token = this.extractToken(authorization); - return this.guildsService.createGuild(token, dto); + return this.guildsService.createGuild(token, user.userId, dto); } @Get() @@ -101,10 +105,11 @@ export class GuildsController { async inviteMember( @Param('id') guildId: string, @Headers('authorization') authorization: string, + @CurrentUser() user: CurrentUserData, @Body() dto: InviteMemberDto ) { const token = this.extractToken(authorization); - return this.guildsService.inviteMember(guildId, dto.email, dto.role, token); + return this.guildsService.inviteMember(guildId, dto.email, dto.role, user.userId, token); } @Post('accept-invitation') diff --git a/services/mana-core-auth/src/guilds/guilds.service.ts b/services/mana-core-auth/src/guilds/guilds.service.ts index 1f1b006e6..018eb7352 100644 --- a/services/mana-core-auth/src/guilds/guilds.service.ts +++ b/services/mana-core-auth/src/guilds/guilds.service.ts @@ -1,14 +1,12 @@ -import { Injectable, ForbiddenException, Logger } from '@nestjs/common'; +import { Injectable, BadRequestException, ForbiddenException, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { eq, and } from 'drizzle-orm'; +import { eq, and, sql } from 'drizzle-orm'; import { getDb } from '../db/connection'; import { members, organizations } from '../db/schema'; +import { subscriptions, plans } from '../db/schema/subscriptions.schema'; import { BetterAuthService } from '../auth/services/better-auth.service'; import { GuildPoolService } from '../credits/guild-pool.service'; -import { InviteEmployeeDto } from '../auth/dto/invite-employee.dto'; -import { AcceptInvitationDto } from '../auth/dto/accept-invitation.dto'; import { UpdateOrganizationDto } from '../auth/dto/update-organization.dto'; -import { UpdateMemberRoleDto } from '../auth/dto/update-member-role.dto'; export class CreateGuildDto { name: string; @@ -16,6 +14,12 @@ export class CreateGuildDto { logo?: string; } +// Default limits for users without a subscription (free tier) +const FREE_TIER_LIMITS = { + maxOrganizations: 1, + maxTeamMembers: 1, // Just themselves +}; + @Injectable() export class GuildsService { private readonly logger = new Logger(GuildsService.name); @@ -32,10 +36,71 @@ export class GuildsService { } /** - * Create a new guild (organization + pool). - * Checks subscription limits for maxOrganizations. + * Get the user's subscription plan limits. + * Falls back to free tier defaults if no active subscription. */ - async createGuild(token: string, dto: CreateGuildDto) { + private async getUserPlanLimits(userId: string) { + const db = this.getDb(); + + const [sub] = await db + .select({ + maxTeamMembers: plans.maxTeamMembers, + maxOrganizations: plans.maxOrganizations, + }) + .from(subscriptions) + .innerJoin(plans, eq(subscriptions.planId, plans.id)) + .where(and(eq(subscriptions.userId, userId), eq(subscriptions.status, 'active'))) + .limit(1); + + return { + maxOrganizations: sub?.maxOrganizations ?? FREE_TIER_LIMITS.maxOrganizations, + maxTeamMembers: sub?.maxTeamMembers ?? FREE_TIER_LIMITS.maxTeamMembers, + }; + } + + /** + * Count how many guilds/organizations the user owns. + */ + private async countUserOwnedGuilds(userId: string): Promise { + const db = this.getDb(); + + const [result] = await db + .select({ count: sql`count(*)` }) + .from(members) + .where(and(eq(members.userId, userId), eq(members.role, 'owner'))); + + return Number(result.count); + } + + /** + * Count current members of a guild. + */ + private async countGuildMembers(guildId: string): Promise { + const db = this.getDb(); + + const [result] = await db + .select({ count: sql`count(*)` }) + .from(members) + .where(eq(members.organizationId, guildId)); + + return Number(result.count); + } + + /** + * Create a new guild (organization + pool). + * Enforces subscription limit for maxOrganizations. + */ + async createGuild(token: string, userId: string, dto: CreateGuildDto) { + // Check subscription limit + const limits = await this.getUserPlanLimits(userId); + const ownedGuilds = await this.countUserOwnedGuilds(userId); + + if (limits.maxOrganizations !== null && ownedGuilds >= limits.maxOrganizations) { + throw new BadRequestException( + `Guild limit reached. Your plan allows ${limits.maxOrganizations} guild(s). Upgrade to create more.` + ); + } + // Create organization via Better Auth const result = await this.betterAuthService.createOrganizationDirect(token, { name: dto.name, @@ -70,11 +135,9 @@ export class GuildsService { async listGuilds(token: string, userId: string) { const result = await this.betterAuthService.listOrganizations(token); - const db = this.getDb(); const guilds = []; for (const org of result.organizations || []) { - // Get pool balance for each guild try { const pool = await this.guildPoolService.getGuildPoolBalance(org.id, userId); guilds.push({ @@ -89,7 +152,6 @@ export class GuildsService { role: (org as any).role, }); } catch { - // Pool might not exist for legacy orgs guilds.push({ gilde: { id: org.id, @@ -150,8 +212,28 @@ export class GuildsService { /** * Invite a member to the guild. + * Enforces subscription limit for maxTeamMembers. */ - async inviteMember(guildId: string, email: string, role: string, token: string) { + async inviteMember(guildId: string, email: string, role: string, inviterUserId: string, token: string) { + // Find guild owner to check their subscription limits + const db = this.getDb(); + const [owner] = await db + .select() + .from(members) + .where(and(eq(members.organizationId, guildId), eq(members.role, 'owner'))) + .limit(1); + + if (owner) { + const limits = await this.getUserPlanLimits(owner.userId); + const memberCount = await this.countGuildMembers(guildId); + + if (limits.maxTeamMembers !== null && memberCount >= limits.maxTeamMembers) { + throw new BadRequestException( + `Member limit reached. The guild owner's plan allows ${limits.maxTeamMembers} member(s). Upgrade to invite more.` + ); + } + } + return this.betterAuthService.inviteEmployee({ organizationId: guildId, employeeEmail: email,