mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:01:09 +02:00
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:
parent
725db638ea
commit
ef70a1af0b
198 changed files with 11113 additions and 3656 deletions
20
packages/shared-subscription-types/package.json
Normal file
20
packages/shared-subscription-types/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
39
packages/shared-subscription-types/src/index.ts
Normal file
39
packages/shared-subscription-types/src/index.ts
Normal 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';
|
||||
136
packages/shared-subscription-types/src/plans.ts
Normal file
136
packages/shared-subscription-types/src/plans.ts
Normal 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,
|
||||
};
|
||||
99
packages/shared-subscription-types/src/revenueCat.ts
Normal file
99
packages/shared-subscription-types/src/revenueCat.ts
Normal 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;
|
||||
}
|
||||
93
packages/shared-subscription-types/src/usage.ts
Normal file
93
packages/shared-subscription-types/src/usage.ts
Normal 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';
|
||||
}
|
||||
19
packages/shared-subscription-types/tsconfig.json
Normal file
19
packages/shared-subscription-types/tsconfig.json
Normal 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"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue