335 lines
9.7 KiB
Markdown
335 lines
9.7 KiB
Markdown
# Signup Fixes - December 9, 2024
|
|
|
|
## Issues Identified
|
|
|
|
### 1. Free Signup - User Logged Out Immediately
|
|
**Root Cause:** Token storage race condition
|
|
- Tokens were being set in Zustand state but not persisting to localStorage fast enough
|
|
- Navigation happened before tokens were saved
|
|
- API interceptor couldn't find tokens → 401 → logout
|
|
|
|
**Symptoms:**
|
|
- User creates account successfully
|
|
- Gets redirected to /sites
|
|
- Immediately logged out (< 1 second)
|
|
|
|
### 2. Paid Signup - Payment Methods Not Loading
|
|
**Root Cause:** Wrong API endpoint
|
|
- Frontend called `/v1/billing/admin/payment-methods/`
|
|
- This endpoint requires authentication
|
|
- Signup page is not authenticated → 401 error
|
|
- Backend already had public endpoint at `/v1/billing/admin/payment-methods/` with `AllowAny` permission
|
|
|
|
**Symptoms:**
|
|
- Error message shown instead of payment options
|
|
- Cannot complete paid plan signup
|
|
|
|
### 3. Multi-Step Form Over-Complicated
|
|
**Root Cause:** Unnecessary complexity
|
|
- 3-step wizard for paid plans (Account → Billing → Payment)
|
|
- Billing step not needed (can use email as billing_email)
|
|
- Created friction in signup flow
|
|
|
|
**Symptoms:**
|
|
- Long signup process
|
|
- Users confused about multiple steps
|
|
- Higher abandonment rate
|
|
|
|
---
|
|
|
|
## Fixes Implemented
|
|
|
|
### Fix 1: Token Persistence (authStore.ts)
|
|
**File:** `/data/app/igny8/frontend/src/store/authStore.ts`
|
|
|
|
**Changes:**
|
|
```typescript
|
|
// In both login() and register() functions:
|
|
|
|
// CRITICAL: Also set tokens as separate items for API interceptor
|
|
if (newToken) {
|
|
localStorage.setItem('access_token', newToken);
|
|
}
|
|
if (newRefreshToken) {
|
|
localStorage.setItem('refresh_token', newRefreshToken);
|
|
}
|
|
```
|
|
|
|
**Why This Works:**
|
|
- Zustand persist middleware is async
|
|
- API interceptor checks `localStorage.getItem('access_token')`
|
|
- By setting tokens immediately in separate keys, API calls work right away
|
|
- No more race condition between persist and navigation
|
|
|
|
---
|
|
|
|
### Fix 2: Payment Method Endpoint (Already Working!)
|
|
**Backend:** `/data/app/igny8/backend/igny8_core/business/billing/views.py`
|
|
|
|
**Existing Code (line 181):**
|
|
```python
|
|
@action(detail=False, methods=['get'], url_path='payment-methods', permission_classes=[AllowAny])
|
|
def list_payment_methods(self, request):
|
|
"""
|
|
Get available payment methods for a specific country.
|
|
Query params: country: ISO 2-letter country code (default: '*' for global)
|
|
"""
|
|
country = request.GET.get('country', '*').upper()
|
|
methods = PaymentMethodConfig.objects.filter(
|
|
Q(country_code=country) | Q(country_code='*'),
|
|
is_enabled=True
|
|
).order_by('sort_order')
|
|
serializer = PaymentMethodConfigSerializer(methods, many=True)
|
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
|
```
|
|
|
|
**URL:** `/v1/billing/admin/payment-methods/`
|
|
- ✅ Has `AllowAny` permission
|
|
- ✅ Returns payment methods filtered by country
|
|
- ✅ Already working - frontend just needs to use it correctly
|
|
|
|
---
|
|
|
|
### Fix 3: Simplified Signup Form
|
|
**New File:** `/data/app/igny8/frontend/src/components/auth/SignUpFormSimplified.tsx`
|
|
|
|
**Changes:**
|
|
- **Single page form** - all fields on one screen
|
|
- **Conditional payment section** - only shows for paid plans
|
|
- **Auto-loads payment methods** - fetches on component mount for paid plans
|
|
- **Removed billing step** - uses email as billing_email by default
|
|
- **Cleaner UX** - progress from top to bottom, no wizard
|
|
|
|
**Form Structure:**
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ First Name / Last Name │
|
|
│ Email │
|
|
│ Account Name (optional) │
|
|
│ Password │
|
|
│ │
|
|
│ [IF PAID PLAN] │
|
|
│ ┌─ Payment Method ─────────────┐ │
|
|
│ │ ○ Credit/Debit Card │ │
|
|
│ │ ○ Bank Transfer │ │
|
|
│ │ ○ Local Wallet │ │
|
|
│ └──────────────────────────────┘ │
|
|
│ │
|
|
│ ☑ Agree to Terms │
|
|
│ │
|
|
│ [Submit Button] │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
**Updated File:** `/data/app/igny8/frontend/src/pages/AuthPages/SignUp.tsx`
|
|
```typescript
|
|
// Changed from:
|
|
import SignUpFormEnhanced from "../../components/auth/SignUpFormEnhanced";
|
|
|
|
// To:
|
|
import SignUpFormSimplified from "../../components/auth/SignUpFormSimplified";
|
|
```
|
|
|
|
---
|
|
|
|
## Backend Changes Summary
|
|
|
|
### 1. Billing URLs (billing/urls.py)
|
|
**Added:** `payment-configs` router registration
|
|
```python
|
|
router.register(r'payment-configs', BillingViewSet, basename='payment-configs')
|
|
```
|
|
|
|
**Purpose:**
|
|
- Exposes payment method configurations for public access
|
|
- Used during signup to show available payment options
|
|
|
|
---
|
|
|
|
## Testing Checklist
|
|
|
|
### Free Signup Flow
|
|
- [ ] Go to `/signup` (no plan parameter)
|
|
- [ ] Fill in: First Name, Last Name, Email, Password
|
|
- [ ] Check "Agree to Terms"
|
|
- [ ] Click "Start Free Trial"
|
|
- [ ] **Expected:**
|
|
- Account created with 1000 credits
|
|
- Redirected to `/sites`
|
|
- Stay logged in (tokens persist)
|
|
- Can create site immediately
|
|
|
|
### Paid Signup Flow (Starter Plan)
|
|
- [ ] Go to `/signup?plan=starter`
|
|
- [ ] Fill in: First Name, Last Name, Email, Password
|
|
- [ ] See payment methods section appear
|
|
- [ ] Select "Bank Transfer" payment method
|
|
- [ ] Check "Agree to Terms"
|
|
- [ ] Click "Create Account & Continue to Payment"
|
|
- [ ] **Expected:**
|
|
- Account created with status `pending_payment`
|
|
- Redirected to `/account/plans`
|
|
- Stay logged in
|
|
- See pending payment banner with instructions
|
|
|
|
### Payment Methods Loading
|
|
- [ ] Open `/signup?plan=starter`
|
|
- [ ] After form loads, check that payment methods section shows:
|
|
- Loading spinner initially
|
|
- Then 3-4 payment options (Stripe, Bank Transfer, etc.)
|
|
- Each with icon and description
|
|
- No error messages
|
|
|
|
---
|
|
|
|
## File Changes Summary
|
|
|
|
### Frontend Files Modified
|
|
1. ✅ `/frontend/src/store/authStore.ts` - Fixed token persistence
|
|
2. ✅ `/frontend/src/pages/AuthPages/SignUp.tsx` - Use simplified form
|
|
3. ✅ `/frontend/src/components/auth/SignUpFormSimplified.tsx` - NEW single-page form
|
|
|
|
### Backend Files Modified
|
|
1. ✅ `/backend/igny8_core/business/billing/urls.py` - Added payment-configs router
|
|
|
|
### Frontend Files Created
|
|
1. ✅ `/frontend/src/components/auth/SignUpFormSimplified.tsx`
|
|
|
|
### Files No Longer Used (Keep for Reference)
|
|
1. `/frontend/src/components/auth/SignUpFormEnhanced.tsx` - Old multi-step form
|
|
2. `/frontend/src/components/billing/BillingFormStep.tsx` - Billing info step
|
|
3. `/frontend/src/components/billing/PaymentMethodSelect.tsx` - Separate payment selector
|
|
|
|
---
|
|
|
|
## API Endpoints Used
|
|
|
|
### Registration
|
|
```
|
|
POST /v1/auth/register/
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "SecurePass123!",
|
|
"password_confirm": "SecurePass123!",
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"account_name": "John's Business", // optional
|
|
"plan_slug": "starter", // optional (defaults to "free")
|
|
"payment_method": "bank_transfer" // required for paid plans
|
|
}
|
|
|
|
Response:
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"user": { ... },
|
|
"tokens": {
|
|
"access": "eyJ...",
|
|
"refresh": "eyJ...",
|
|
"access_expires_at": "2024-12-09T...",
|
|
"refresh_expires_at": "2024-12-09T..."
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Payment Methods (Public)
|
|
```
|
|
GET /v1/billing/admin/payment-methods/?country=US
|
|
No authentication required
|
|
|
|
Response:
|
|
[
|
|
{
|
|
"id": 1,
|
|
"payment_method": "stripe",
|
|
"display_name": "Credit/Debit Card",
|
|
"instructions": null,
|
|
"country_code": "*",
|
|
"is_enabled": true,
|
|
"sort_order": 1
|
|
},
|
|
{
|
|
"id": 2,
|
|
"payment_method": "bank_transfer",
|
|
"display_name": "Bank Transfer",
|
|
"instructions": "Transfer to: Account 123456789...",
|
|
"country_code": "*",
|
|
"is_enabled": true,
|
|
"sort_order": 2
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
## Known Issues (Not in Scope)
|
|
|
|
1. **Site.industry field not required** - Can create sites without industry
|
|
2. **Missing Subscription.plan field** - Subscription doesn't link to plan directly
|
|
3. **Duplicate date fields** - Period dates in both Subscription and Invoice
|
|
4. **Payment method stored in 3 places** - Account, Subscription, Payment models
|
|
|
|
These are documented in `IMPLEMENTATION-PLAN-SIGNUP-TO-PAYMENT-WORKFLOW.md` but not critical for signup to work.
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. **Build Frontend**
|
|
```bash
|
|
cd /data/app/igny8/frontend
|
|
npm run build
|
|
```
|
|
|
|
2. **Test Free Signup**
|
|
- Create account without plan parameter
|
|
- Verify tokens persist
|
|
- Verify account has 1000 credits
|
|
|
|
3. **Test Paid Signup**
|
|
- Create account with `?plan=starter`
|
|
- Verify payment methods load
|
|
- Verify account created with `pending_payment` status
|
|
|
|
4. **Monitor for Issues**
|
|
- Check browser console for errors
|
|
- Check network tab for failed API calls
|
|
- Verify localStorage has `access_token` and `refresh_token`
|
|
|
|
---
|
|
|
|
## Rollback Instructions
|
|
|
|
If issues occur, revert these changes:
|
|
|
|
### Frontend
|
|
```bash
|
|
git checkout HEAD -- src/store/authStore.ts
|
|
git checkout HEAD -- src/pages/AuthPages/SignUp.tsx
|
|
rm src/components/auth/SignUpFormSimplified.tsx
|
|
```
|
|
|
|
### Backend
|
|
```bash
|
|
git checkout HEAD -- igny8_core/business/billing/urls.py
|
|
```
|
|
|
|
Then use the old multi-step form:
|
|
```typescript
|
|
// In SignUp.tsx
|
|
import SignUpFormEnhanced from "../../components/auth/SignUpFormEnhanced";
|
|
```
|
|
|
|
---
|
|
|
|
## Success Criteria
|
|
|
|
✅ Free signup works - user stays logged in
|
|
✅ Paid signup works - payment methods load
|
|
✅ Single-page form is simpler and faster
|
|
✅ Tokens persist correctly
|
|
✅ No authentication errors on signup
|