Files
RAPPORT-HOST/server/plans.js
T
karim 6290475ea3 Initial: RAPPORT-HOST Iteration 1 (proprietär)
Kommerzielle Hosting-/Abo-Plattform für Rapport-Instanzen.

- React-Frontend (Vite/JSX): Landing, Register, Login, Plans, Dashboard
- Node/Express-Backend: Auth (bcrypt+JWT), Stripe-Billing, Provisioning
- HOST-Postgres-Schema: accounts, subscriptions, instances
- Provisioning-Interface + Modell-A-Adapter (Studio im geteilten Stack)
- MOCK-Modus: voller End-to-End-Flow ohne Stripe/Rapport-Stack testbar
- Idempotentes Fulfillment (Upsert auf stripe_subscription_id)
- docker-compose für lokale host-db; identisch auf Hetzner deploybar

E2E lokal verifiziert: Register -> Checkout(mock) -> Instanz -> Idempotenz.

Lizenz: proprietär (kein AGPL-Code eingebunden, nur Netzwerk-API zur Familie).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 15:37:33 +02:00

44 lines
1.3 KiB
JavaScript

// Abo-Pläne — eine Quelle der Wahrheit für Frontend (Preisanzeige) und Backend
// (Stripe-Price-Mapping + Instanz-Limits beim Provisioning).
import { env } from "./env.js";
export const PLANS = [
{
id: "solo",
name: "Solo",
priceChf: 19,
interval: "Monat",
stripePriceId: env.stripe.prices.solo,
limits: { users: 1, projects: 25, storageGb: 2 },
features: ["1 Benutzer", "25 Projekte", "2 GB Speicher", "Eigene Instanz"],
},
{
id: "studio",
name: "Studio",
priceChf: 49,
interval: "Monat",
stripePriceId: env.stripe.prices.studio,
limits: { users: 5, projects: 200, storageGb: 20 },
features: ["Bis 5 Benutzer", "200 Projekte", "20 GB Speicher", "Eigene Instanz", "Support"],
recommended: true,
},
{
id: "business",
name: "Business",
priceChf: 99,
interval: "Monat",
stripePriceId: env.stripe.prices.business,
limits: { users: 20, projects: 1000, storageGb: 100 },
features: ["Bis 20 Benutzer", "1000 Projekte", "100 GB Speicher", "Eigene Instanz", "Prioritäts-Support"],
},
];
export function getPlan(id) {
return PLANS.find((p) => p.id === id) || null;
}
// Fürs Frontend: ohne interne Felder (Stripe-IDs müssen nicht raus).
export function publicPlans() {
return PLANS.map(({ stripePriceId, ...rest }) => rest);
}