ALwrity onboarding final step
This commit is contained in:
215
docs/PERSONA_DATA_MIGRATION_GUIDE.md
Normal file
215
docs/PERSONA_DATA_MIGRATION_GUIDE.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# Persona Data Table Migration Guide
|
||||
|
||||
## Overview
|
||||
This guide explains how to create the `persona_data` table for storing Step 4 (Persona Generation) data from the onboarding flow.
|
||||
|
||||
## Background
|
||||
The `persona_data` table was missing from the database schema, causing Step 4 onboarding data to only be saved to JSON files instead of the database. This migration adds the required table with proper user isolation.
|
||||
|
||||
## Migration Methods
|
||||
|
||||
### Method 1: Automatic Migration (Recommended)
|
||||
The easiest way is to restart your backend server. The table will be created automatically when the application starts.
|
||||
|
||||
```bash
|
||||
# Stop the backend if running (Ctrl+C)
|
||||
# Then restart it:
|
||||
python backend/start_alwrity_backend.py --dev
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
- The `init_database()` function in `backend/services/database.py` (line 69) calls `OnboardingBase.metadata.create_all(bind=engine)`
|
||||
- This automatically creates all missing tables defined in the `OnboardingBase` models
|
||||
- Since we added the `PersonaData` model, it will be created on startup
|
||||
|
||||
### Method 2: Manual Migration Script
|
||||
If you prefer to run the migration manually without restarting the backend:
|
||||
|
||||
```bash
|
||||
# From the project root directory:
|
||||
python backend/scripts/create_persona_data_table.py
|
||||
```
|
||||
|
||||
**What this script does:**
|
||||
1. Checks if the `persona_data` table already exists
|
||||
2. Creates the table if it doesn't exist
|
||||
3. Verifies the table was created successfully
|
||||
4. Shows the table structure (columns and types)
|
||||
5. Lists all onboarding-related tables and their status
|
||||
|
||||
### Method 3: SQL Migration (Production/Manual)
|
||||
For production environments or manual database management:
|
||||
|
||||
```bash
|
||||
# Connect to your PostgreSQL database and run:
|
||||
psql -U your_username -d your_database -f backend/database/migrations/add_persona_data_table.sql
|
||||
```
|
||||
|
||||
**Or using psql command:**
|
||||
```sql
|
||||
-- Connect to your database
|
||||
\c your_database
|
||||
|
||||
-- Run the migration
|
||||
\i backend/database/migrations/add_persona_data_table.sql
|
||||
|
||||
-- Verify the table was created
|
||||
\dt persona_data
|
||||
\d persona_data
|
||||
```
|
||||
|
||||
## Table Structure
|
||||
|
||||
The `persona_data` table includes:
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `id` | SERIAL | Primary key |
|
||||
| `session_id` | INTEGER | Foreign key to `onboarding_sessions.id` |
|
||||
| `core_persona` | JSONB | Core persona data (demographics, psychographics, etc.) |
|
||||
| `platform_personas` | JSONB | Platform-specific personas (LinkedIn, Twitter, etc.) |
|
||||
| `quality_metrics` | JSONB | Quality assessment metrics |
|
||||
| `selected_platforms` | JSONB | Array of selected platforms |
|
||||
| `created_at` | TIMESTAMP | When the record was created |
|
||||
| `updated_at` | TIMESTAMP | When the record was last updated |
|
||||
|
||||
**Indexes:**
|
||||
- `idx_persona_data_session_id` - For efficient session lookups
|
||||
- `idx_persona_data_created_at` - For time-based queries
|
||||
|
||||
**Constraints:**
|
||||
- Foreign key to `onboarding_sessions.id` with `ON DELETE CASCADE`
|
||||
|
||||
## Verification
|
||||
|
||||
After running the migration, verify it was successful:
|
||||
|
||||
### Using Python:
|
||||
```python
|
||||
from services.database import engine
|
||||
from sqlalchemy import inspect
|
||||
|
||||
inspector = inspect(engine)
|
||||
tables = inspector.get_table_names()
|
||||
|
||||
if 'persona_data' in tables:
|
||||
print("✅ persona_data table exists")
|
||||
columns = inspector.get_columns('persona_data')
|
||||
for col in columns:
|
||||
print(f" - {col['name']}: {col['type']}")
|
||||
else:
|
||||
print("❌ persona_data table not found")
|
||||
```
|
||||
|
||||
### Using SQL:
|
||||
```sql
|
||||
-- Check if table exists
|
||||
SELECT EXISTS (
|
||||
SELECT FROM information_schema.tables
|
||||
WHERE table_name = 'persona_data'
|
||||
);
|
||||
|
||||
-- Show table structure
|
||||
\d persona_data
|
||||
```
|
||||
|
||||
### Using the Backend Logs:
|
||||
After restarting the backend, look for this log message:
|
||||
```
|
||||
Database initialized successfully with all models including subscription system and business info
|
||||
```
|
||||
|
||||
Then, when a user completes Step 4, you should see:
|
||||
```
|
||||
✅ DATABASE: Persona data saved to database for user user_xxxxx
|
||||
```
|
||||
|
||||
## Expected Behavior After Migration
|
||||
|
||||
Once the table is created and the backend is running with the updated code:
|
||||
|
||||
1. **Step 4 Completion:**
|
||||
- Persona data (corePersona, platformPersonas, qualityMetrics, selectedPlatforms) is saved to the database
|
||||
- Database logs confirm: `✅ DATABASE: Persona data saved to database for user {user_id}`
|
||||
|
||||
2. **User Isolation:**
|
||||
- Each user's persona data is stored separately using their `user_id`
|
||||
- Data is linked to the user's onboarding session
|
||||
|
||||
3. **Data Persistence:**
|
||||
- Persona data is no longer lost when JSON files are deleted
|
||||
- Data survives backend restarts
|
||||
- Data is accessible across different sessions
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Table Already Exists Error
|
||||
If you see "table already exists" errors:
|
||||
- This is normal! It means the table was already created
|
||||
- The migration scripts use `CREATE TABLE IF NOT EXISTS` to handle this
|
||||
- No action needed
|
||||
|
||||
### Permission Denied
|
||||
If you get permission errors:
|
||||
```
|
||||
ERROR: permission denied for schema public
|
||||
```
|
||||
**Solution:** Ensure your database user has CREATE TABLE permissions:
|
||||
```sql
|
||||
GRANT CREATE ON SCHEMA public TO your_database_user;
|
||||
```
|
||||
|
||||
### Foreign Key Constraint Fails
|
||||
If the `onboarding_sessions` table doesn't exist:
|
||||
1. Run the full database initialization first:
|
||||
```python
|
||||
from services.database import init_database
|
||||
init_database()
|
||||
```
|
||||
2. Then create the `persona_data` table
|
||||
|
||||
### Missing Database Connection
|
||||
If you see "database connection" errors:
|
||||
1. Check your `DATABASE_URL` environment variable
|
||||
2. Ensure PostgreSQL/SQLite is running
|
||||
3. Verify database credentials
|
||||
|
||||
## Rollback (If Needed)
|
||||
|
||||
To remove the `persona_data` table:
|
||||
|
||||
```sql
|
||||
DROP TABLE IF EXISTS persona_data CASCADE;
|
||||
```
|
||||
|
||||
**Warning:** This will delete all persona data. Use with caution!
|
||||
|
||||
## Related Files
|
||||
|
||||
- **Model:** `backend/models/onboarding.py` - `PersonaData` class (lines 149-183)
|
||||
- **Service:** `backend/services/onboarding_database_service.py` - `save_persona_data()` method (lines 298-338)
|
||||
- **Migration:** `backend/database/migrations/add_persona_data_table.sql`
|
||||
- **Script:** `backend/scripts/create_persona_data_table.py`
|
||||
- **Database Init:** `backend/services/database.py` - `init_database()` function (line 63-80)
|
||||
|
||||
## Summary
|
||||
|
||||
**Recommended approach for local development:**
|
||||
```bash
|
||||
# Just restart the backend - the table will be created automatically!
|
||||
python backend/start_alwrity_backend.py --dev
|
||||
```
|
||||
|
||||
**For production deployment:**
|
||||
- The table will be created automatically on first deployment
|
||||
- Or run the SQL migration manually before deployment
|
||||
- No downtime required - the migration is additive only
|
||||
|
||||
## Questions?
|
||||
|
||||
If you encounter issues:
|
||||
1. Check the backend logs for detailed error messages
|
||||
2. Verify all onboarding tables exist using the verification script
|
||||
3. Ensure your database user has proper permissions
|
||||
4. Check that the `PersonaData` model is imported correctly in `backend/services/onboarding_database_service.py`
|
||||
|
||||
Reference in New Issue
Block a user