Add subcription feature
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
TenantSearchParams,
|
||||
TenantNearbyParams,
|
||||
AddMemberWithUserCreate,
|
||||
BakeryRegistrationWithSubscription,
|
||||
} from '../types/tenant';
|
||||
import { ApiError } from '../client';
|
||||
|
||||
@@ -170,6 +171,24 @@ export const useRegisterBakery = (
|
||||
});
|
||||
};
|
||||
|
||||
export const useRegisterBakeryWithSubscription = (
|
||||
options?: UseMutationOptions<TenantResponse, ApiError, BakeryRegistrationWithSubscription>
|
||||
) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<TenantResponse, ApiError, BakeryRegistrationWithSubscription>({
|
||||
mutationFn: (bakeryData: BakeryRegistrationWithSubscription) => tenantService.registerBakeryWithSubscription(bakeryData),
|
||||
onSuccess: (data, variables) => {
|
||||
// Invalidate user tenants to include the new one
|
||||
queryClient.invalidateQueries({ queryKey: tenantKeys.userTenants('') });
|
||||
queryClient.invalidateQueries({ queryKey: tenantKeys.userOwnedTenants('') });
|
||||
// Set the tenant data in cache
|
||||
queryClient.setQueryData(tenantKeys.detail(data.id), data);
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateTenant = (
|
||||
options?: UseMutationOptions<TenantResponse, ApiError, { tenantId: string; updateData: TenantUpdate }>
|
||||
) => {
|
||||
|
||||
@@ -37,6 +37,10 @@ export class AuthService {
|
||||
return apiClient.post<TokenResponse>(`${this.baseUrl}/register`, userData);
|
||||
}
|
||||
|
||||
async registerWithSubscription(userData: UserRegistration): Promise<UserRegistrationWithSubscriptionResponse> {
|
||||
return apiClient.post<UserRegistrationWithSubscriptionResponse>(`${this.baseUrl}/register-with-subscription`, userData);
|
||||
}
|
||||
|
||||
async login(loginData: UserLogin): Promise<TokenResponse> {
|
||||
return apiClient.post<TokenResponse>(`${this.baseUrl}/login`, loginData);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
import { apiClient } from '../client';
|
||||
import {
|
||||
BakeryRegistration,
|
||||
BakeryRegistrationWithSubscription,
|
||||
TenantResponse,
|
||||
TenantAccessResponse,
|
||||
TenantUpdate,
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
TenantSearchParams,
|
||||
TenantNearbyParams,
|
||||
AddMemberWithUserCreate,
|
||||
SubscriptionLinkingResponse,
|
||||
} from '../types/tenant';
|
||||
|
||||
export class TenantService {
|
||||
@@ -35,6 +37,21 @@ export class TenantService {
|
||||
return apiClient.post<TenantResponse>(`${this.baseUrl}/register`, bakeryData);
|
||||
}
|
||||
|
||||
async registerBakeryWithSubscription(bakeryData: BakeryRegistrationWithSubscription): Promise<TenantResponse> {
|
||||
return apiClient.post<TenantResponse>(`${this.baseUrl}/register`, bakeryData);
|
||||
}
|
||||
|
||||
async linkSubscriptionToTenant(
|
||||
tenantId: string,
|
||||
subscriptionId: string,
|
||||
userId: string
|
||||
): Promise<SubscriptionLinkingResponse> {
|
||||
return apiClient.post<SubscriptionLinkingResponse>(
|
||||
`${this.baseUrl}/subscriptions/link`,
|
||||
{ tenant_id: tenantId, subscription_id: subscriptionId, user_id: userId }
|
||||
);
|
||||
}
|
||||
|
||||
async getTenant(tenantId: string): Promise<TenantResponse> {
|
||||
return apiClient.get<TenantResponse>(`${this.baseUrl}/${tenantId}`);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,30 @@
|
||||
// frontend/src/api/types/auth.ts
|
||||
// ================================================================
|
||||
/**
|
||||
* Authentication Type Definitions
|
||||
*
|
||||
* Aligned with backend schemas:
|
||||
* - services/auth/app/schemas/auth.py
|
||||
* - services/auth/app/schemas/users.py
|
||||
*
|
||||
* Last Updated: 2025-10-05
|
||||
* Status: ✅ Complete - Zero drift with backend
|
||||
*/
|
||||
=======
|
||||
// ================================================================
|
||||
// frontend/src/api/types/auth.ts
|
||||
// ================================================================
|
||||
/**
|
||||
* Authentication Type Definitions
|
||||
*
|
||||
* Aligned with backend schemas:
|
||||
* - services/auth/app/schemas/auth.py
|
||||
* - services/auth/app/schemas/users.py
|
||||
*
|
||||
* Last Updated: 2025-10-13
|
||||
* Status: ✅ Complete - Zero drift with backend
|
||||
* Changes: Removed use_trial, added payment_customer_id and default_payment_method_id
|
||||
*/================================================================
|
||||
// frontend/src/api/types/auth.ts
|
||||
// ================================================================
|
||||
/**
|
||||
@@ -27,7 +53,7 @@ export interface UserRegistration {
|
||||
tenant_name?: string | null; // max_length=255
|
||||
role?: string | null; // Default: "admin", pattern: ^(user|admin|manager|super_admin)$
|
||||
subscription_plan?: string | null; // Default: "starter", options: starter, professional, enterprise
|
||||
use_trial?: boolean | null; // Default: false - Whether to use trial period
|
||||
billing_cycle?: 'monthly' | 'yearly' | null; // Default: "monthly" - Billing cycle preference
|
||||
payment_method_id?: string | null; // Stripe payment method ID
|
||||
coupon_code?: string | null; // Promotional coupon code for discounts/trial extensions
|
||||
// GDPR Consent fields
|
||||
@@ -35,6 +61,20 @@ export interface UserRegistration {
|
||||
privacy_accepted?: boolean; // Default: true - Accept privacy policy
|
||||
marketing_consent?: boolean; // Default: false - Consent to marketing communications
|
||||
analytics_consent?: boolean; // Default: false - Consent to analytics cookies
|
||||
// NEW: Billing address fields for subscription creation
|
||||
address?: string | null; // Billing address
|
||||
postal_code?: string | null; // Billing postal code
|
||||
city?: string | null; // Billing city
|
||||
country?: string | null; // Billing country
|
||||
}
|
||||
|
||||
/**
|
||||
* User registration with subscription response
|
||||
* Extended token response for registration with subscription
|
||||
* Backend: services/auth/app/schemas/auth.py:70-80 (TokenResponse with subscription_id)
|
||||
*/
|
||||
export interface UserRegistrationWithSubscriptionResponse extends TokenResponse {
|
||||
subscription_id?: string | null; // ID of the created subscription (returned if subscription was created during registration)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,6 +205,8 @@ export interface UserResponse {
|
||||
timezone?: string | null;
|
||||
tenant_id?: string | null;
|
||||
role?: string | null; // Default: "admin"
|
||||
payment_customer_id?: string | null; // Payment provider customer ID (Stripe, etc.)
|
||||
default_payment_method_id?: string | null; // Default payment method ID
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -255,3 +255,38 @@ export interface TenantNearbyParams {
|
||||
radius_km?: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// NEW ARCHITECTURE: TENANT-INDEPENDENT SUBSCRIPTION TYPES
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Subscription linking request for new registration flow
|
||||
* Backend: services/tenant/app/api/tenant_operations.py
|
||||
*/
|
||||
export interface SubscriptionLinkingRequest {
|
||||
tenant_id: string; // Tenant ID to link subscription to
|
||||
subscription_id: string; // Subscription ID to link
|
||||
user_id: string; // User ID performing the linking
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscription linking response
|
||||
*/
|
||||
export interface SubscriptionLinkingResponse {
|
||||
success: boolean;
|
||||
message: string;
|
||||
data?: {
|
||||
tenant_id: string;
|
||||
subscription_id: string;
|
||||
status: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended BakeryRegistration with subscription linking support
|
||||
*/
|
||||
export interface BakeryRegistrationWithSubscription extends BakeryRegistration {
|
||||
subscription_id?: string | null; // Optional subscription ID to link
|
||||
link_existing_subscription?: boolean | null; // Flag to link existing subscription
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user