Commit Message feat: implement comprehensive shared packages architecture for monorepo SUMMARY: Introduce 10 shared packages to unify common code across all 4 web apps, reducing ~3,000 lines of duplicated code and establishing consistent patterns for authentication, UI components, theming, and utilities. NEW SHARED PACKAGES: - @manacore/shared-auth: Unified auth logic (token management, JWT utils, fetch interceptor, storage/device/network adapters) - @manacore/shared-auth-ui: Reusable auth UI (LoginPage, RegisterPage, OAuth buttons for Google/Apple) - @manacore/shared-tailwind: Unified Tailwind config with 4 themes (lume, nature, stone, ocean) and light/dark mode support - @manacore/shared-icons: Phosphor-based icon library (40+ icons) - @manacore/shared-ui: Atomic design system (Text, Button, Badge, Toggle, Input, Modal) - @manacore/shared-i18n: Unified i18n setup with locale detection - @manacore/shared-config: Environment validation with Zod - @manacore/shared-subscriptio n-types: Subscription type definitions - @manacore/shared-subscriptio n-ui: Subscription UI components (planned) EXTENDED PACKAGES: - @manacore/shared-types: Added auth.ts, theme.ts, ui.ts, common.ts - @manacore/shared-utils: Added format.ts, validation.ts APP MIGRATIONS: - memoro/web: Migrated login (549→46 LOC), tailwind (165→12 LOC), removed 15+ duplicate components - manacore/web: Migrated to client-side auth with shared-auth, added new components (Icon, ThemeToggle, Logo) - manadeck/web: Replaced local authService/tokenManager with shared-auth, migrated auth pages - maerchenzauber/web: Added auth setup, stores, components, routes DELETED FILES (migrated to shared packages): - OAuth buttons (Google/Apple) from memoro, manacore, manadeck - Local authService, tokenManager, deviceManager, jwt utils - Duplicate Modal, Toggle, Text components - iconPaths and ManaIcon components - Subscription-related components (CostCard, PackageCard, etc.) BENEFITS: - 92% reduction in login page code - 93% reduction in tailwind config code - Consistent theming across all apps - Single source of truth for auth logic - Easier maintenance and updates BREAKING CHANGES: - Icon imports now from @manacore/shared-icons - Modal imports from @manacore/shared-ui - OAuth config via setGoogleCl ientId()/setAppleConfig()

This commit is contained in:
Till-JS 2025-11-24 21:09:20 +01:00
parent 725db638ea
commit ef70a1af0b
198 changed files with 11113 additions and 3656 deletions

View file

@ -0,0 +1,20 @@
{
"name": "@manacore/shared-subscription-types",
"version": "1.0.0",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts",
"./plans": "./src/plans.ts",
"./usage": "./src/usage.ts",
"./revenueCat": "./src/revenueCat.ts"
},
"scripts": {
"type-check": "tsc --noEmit"
},
"devDependencies": {
"typescript": "^5.7.3"
}
}

View file

@ -0,0 +1,39 @@
/**
* Shared subscription types for Manacore monorepo
*
* This package contains TypeScript types for subscription plans,
* mana packages, usage tracking, and RevenueCat integration.
*/
// Plan types
export {
type BillingCycle,
type PlanCategory,
type SubscriptionPlan,
type ManaPackage,
type ProductMapping,
type PackageMapping,
type FreeTierConfig,
DEFAULT_FREE_TIER,
} from './plans';
// Usage types
export {
type UsageData,
type UsageHistoryEntry,
type CostItem,
type ManaBalance,
type CreditTransaction,
type OperationPricing,
} from './usage';
// RevenueCat types
export {
type RevenueCatSubscriptionPlan,
type RevenueCatManaPackage,
type SubscriptionServiceData,
type PurchaseResult,
type CustomerSubscriptionStatus,
type RestorePurchasesResult,
type RevenueCatOffering,
} from './revenueCat';

View file

@ -0,0 +1,136 @@
/**
* Subscription plan and package types
*/
/**
* Billing cycle options
*/
export type BillingCycle = 'monthly' | 'yearly';
/**
* Subscription plan category
*/
export type PlanCategory = 'individual' | 'team' | 'enterprise';
/**
* Base subscription plan interface
*/
export interface SubscriptionPlan {
/** Unique identifier */
id: string;
/** Display name (localized) */
name: string;
/** English name */
nameEn?: string;
/** German name */
nameDe?: string;
/** Italian name */
nameIt?: string;
/** Price in local currency */
price: number;
/** Formatted price string (e.g., "5,99€") */
priceString?: string;
/** Currency code (e.g., "EUR") */
currencyCode?: string;
/** Price breakdown text */
priceBreakdown?: string;
/** Monthly equivalent for yearly plans */
monthlyEquivalent?: number;
/** Mana amount per month */
monthlyMana: number;
/** Initial mana grant on signup */
initialMana?: number;
/** Daily mana regeneration */
dailyMana?: number;
/** Maximum mana capacity */
maxMana?: number;
/** Whether user can gift mana */
canGiftMana: boolean;
/** Mark as popular/recommended */
popular?: boolean;
/** Billing frequency */
billingCycle: BillingCycle;
/** Team subscription flag */
isTeamSubscription?: boolean;
/** Enterprise subscription flag */
isEnterpriseSubscription?: boolean;
/** Plan features list */
features?: string[];
}
/**
* One-time mana package interface
*/
export interface ManaPackage {
/** Unique identifier */
id: string;
/** Display name (localized) */
name: string;
/** English name */
nameEn?: string;
/** German name */
nameDe?: string;
/** Italian name */
nameIt?: string;
/** Mana amount */
manaAmount: number;
/** Price in local currency */
price: number;
/** Formatted price string */
priceString?: string;
/** Currency code */
currencyCode?: string;
/** Team package flag */
isTeamPackage?: boolean;
/** Enterprise package flag */
isEnterprisePackage?: boolean;
/** Mark as popular */
popular?: boolean;
}
/**
* Product mapping for RevenueCat
*/
export interface ProductMapping {
/** Internal subscription ID */
subscriptionId: string;
/** App Store/Play Store product ID */
productId: string;
/** Billing cycle */
billingCycle: BillingCycle;
/** Category */
category: PlanCategory;
}
/**
* Package mapping for RevenueCat
*/
export interface PackageMapping {
/** Internal package ID */
packageId: string;
/** App Store/Play Store product ID */
productId: string;
/** Category */
category: PlanCategory;
}
/**
* Free tier configuration
*/
export interface FreeTierConfig {
/** Initial mana for free users */
initialMana: number;
/** Daily mana regeneration */
dailyMana: number;
/** Maximum mana capacity */
maxMana: number;
}
/**
* Default free tier configuration
*/
export const DEFAULT_FREE_TIER: FreeTierConfig = {
initialMana: 150,
dailyMana: 5,
maxMana: 150,
};

View file

@ -0,0 +1,99 @@
/**
* RevenueCat integration types
*/
import type { SubscriptionPlan, ManaPackage } from './plans';
/**
* RevenueCat-enhanced subscription plan
*/
export interface RevenueCatSubscriptionPlan extends SubscriptionPlan {
/** RevenueCat package object */
revenueCatPackage?: unknown;
/** RevenueCat product object */
revenueCatProduct?: unknown;
/** App Store/Play Store product ID */
productId: string;
}
/**
* RevenueCat-enhanced mana package
*/
export interface RevenueCatManaPackage extends ManaPackage {
/** RevenueCat package object */
revenueCatPackage?: unknown;
/** RevenueCat product object */
revenueCatProduct?: unknown;
/** App Store/Play Store product ID */
productId: string;
}
/**
* Subscription service data response
*/
export interface SubscriptionServiceData {
/** All available subscription plans */
subscriptions: RevenueCatSubscriptionPlan[];
/** All available one-time packages */
packages: RevenueCatManaPackage[];
/** Whether data is from RevenueCat or fallback */
isFromRevenueCat: boolean;
/** Last update timestamp */
lastUpdated: Date;
}
/**
* Purchase result
*/
export interface PurchaseResult {
/** Whether purchase was successful */
success: boolean;
/** Customer info from RevenueCat */
customerInfo?: unknown;
/** Error message if failed */
error?: string;
}
/**
* Customer subscription status
*/
export interface CustomerSubscriptionStatus {
/** Whether user has active subscription */
hasActiveSubscription: boolean;
/** Current plan ID */
currentPlanId?: string;
/** Subscription expiration date */
expirationDate?: Date;
/** Whether in grace period */
isInGracePeriod?: boolean;
/** Whether subscription will renew */
willRenew?: boolean;
}
/**
* Restore purchases result
*/
export interface RestorePurchasesResult {
/** Whether restore was successful */
success: boolean;
/** Restored subscription plan ID */
restoredPlanId?: string;
/** Error message if failed */
error?: string;
}
/**
* Offering from RevenueCat
*/
export interface RevenueCatOffering {
/** Offering identifier */
identifier: string;
/** Available packages in this offering */
availablePackages: RevenueCatSubscriptionPlan[];
/** Lifetime package (if available) */
lifetime?: RevenueCatManaPackage;
/** Annual package */
annual?: RevenueCatSubscriptionPlan;
/** Monthly package */
monthly?: RevenueCatSubscriptionPlan;
}

View file

@ -0,0 +1,93 @@
/**
* Usage and cost tracking types
*/
/**
* Usage data for displaying user's mana consumption
*/
export interface UsageData {
/** Total mana consumed all time */
total: number;
/** Mana consumed last week */
lastWeek: number;
/** Mana consumed last month */
lastMonth: number;
/** Current mana balance */
currentMana: number;
/** Maximum mana capacity */
maxMana: number;
/** Usage history */
history?: UsageHistoryEntry[];
}
/**
* Single usage history entry
*/
export interface UsageHistoryEntry {
/** Date of usage (ISO string) */
date: string;
/** Amount consumed */
amount: number;
/** Action type (optional) */
action?: string;
}
/**
* Cost item for displaying operation costs
*/
export interface CostItem {
/** Action description */
action: string;
/** Translation key for action */
actionKey?: string;
/** Mana cost */
cost: number;
/** Icon name */
icon: string;
}
/**
* User's credit/mana balance
*/
export interface ManaBalance {
/** Current mana amount */
current: number;
/** Maximum capacity */
max: number;
/** Last updated timestamp */
lastUpdated: string;
}
/**
* Credit transaction record
*/
export interface CreditTransaction {
/** Transaction ID */
id: string;
/** User ID */
userId: string;
/** Amount (positive = credit, negative = debit) */
amount: number;
/** Transaction type */
type: 'purchase' | 'subscription' | 'usage' | 'gift' | 'refund' | 'bonus';
/** Description */
description: string;
/** Timestamp */
createdAt: string;
/** Related operation ID (if applicable) */
operationId?: string;
}
/**
* Pricing information for operations
*/
export interface OperationPricing {
/** Operation key */
operation: string;
/** Base cost in mana */
baseCost: number;
/** Per-unit cost (e.g., per minute, per token) */
perUnitCost?: number;
/** Unit type */
unitType?: 'minute' | 'token' | 'request';
}

View file

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}