Update registration Step
This commit is contained in:
Binary file not shown.
Binary file not shown.
69
migrate_multistep_registration.py
Normal file
69
migrate_multistep_registration.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
"""
|
||||||
|
Migration script to add multi-step registration fields to users table.
|
||||||
|
Run this once to update the database schema.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from database import engine
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
|
def add_multistep_registration_columns():
|
||||||
|
"""Add newsletter, volunteer, scholarship, and directory columns to users table"""
|
||||||
|
|
||||||
|
migrations = [
|
||||||
|
# Newsletter preferences
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS newsletter_publish_name BOOLEAN NOT NULL DEFAULT FALSE",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS newsletter_publish_photo BOOLEAN NOT NULL DEFAULT FALSE",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS newsletter_publish_birthday BOOLEAN NOT NULL DEFAULT FALSE",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS newsletter_publish_none BOOLEAN NOT NULL DEFAULT FALSE",
|
||||||
|
|
||||||
|
# Volunteer interests
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS volunteer_interests JSON DEFAULT '[]'::json",
|
||||||
|
|
||||||
|
# Scholarship
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS scholarship_requested BOOLEAN NOT NULL DEFAULT FALSE",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS scholarship_reason TEXT",
|
||||||
|
|
||||||
|
# Directory settings
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS show_in_directory BOOLEAN NOT NULL DEFAULT FALSE",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS directory_email VARCHAR",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS directory_bio TEXT",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS directory_address VARCHAR",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS directory_phone VARCHAR",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS directory_dob TIMESTAMP",
|
||||||
|
"ALTER TABLE users ADD COLUMN IF NOT EXISTS directory_partner_name VARCHAR"
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("Adding multi-step registration columns to users table...")
|
||||||
|
with engine.connect() as conn:
|
||||||
|
for sql in migrations:
|
||||||
|
print(f" Executing: {sql[:70]}...")
|
||||||
|
conn.execute(text(sql))
|
||||||
|
conn.commit()
|
||||||
|
print("✅ Migration completed successfully!")
|
||||||
|
print("\nAdded columns:")
|
||||||
|
print(" Newsletter Preferences:")
|
||||||
|
print(" - newsletter_publish_name (BOOLEAN)")
|
||||||
|
print(" - newsletter_publish_photo (BOOLEAN)")
|
||||||
|
print(" - newsletter_publish_birthday (BOOLEAN)")
|
||||||
|
print(" - newsletter_publish_none (BOOLEAN)")
|
||||||
|
print(" Volunteer:")
|
||||||
|
print(" - volunteer_interests (JSON)")
|
||||||
|
print(" Scholarship:")
|
||||||
|
print(" - scholarship_requested (BOOLEAN)")
|
||||||
|
print(" - scholarship_reason (TEXT)")
|
||||||
|
print(" Directory:")
|
||||||
|
print(" - show_in_directory (BOOLEAN)")
|
||||||
|
print(" - directory_email (VARCHAR)")
|
||||||
|
print(" - directory_bio (TEXT)")
|
||||||
|
print(" - directory_address (VARCHAR)")
|
||||||
|
print(" - directory_phone (VARCHAR)")
|
||||||
|
print(" - directory_dob (TIMESTAMP)")
|
||||||
|
print(" - directory_partner_name (VARCHAR)")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Migration failed: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
add_multistep_registration_columns()
|
||||||
23
models.py
23
models.py
@@ -54,6 +54,29 @@ class User(Base):
|
|||||||
email_verified = Column(Boolean, default=False)
|
email_verified = Column(Boolean, default=False)
|
||||||
email_verification_token = Column(String, nullable=True)
|
email_verification_token = Column(String, nullable=True)
|
||||||
newsletter_subscribed = Column(Boolean, default=False)
|
newsletter_subscribed = Column(Boolean, default=False)
|
||||||
|
|
||||||
|
# Newsletter Publication Preferences (Step 2)
|
||||||
|
newsletter_publish_name = Column(Boolean, default=False, nullable=False)
|
||||||
|
newsletter_publish_photo = Column(Boolean, default=False, nullable=False)
|
||||||
|
newsletter_publish_birthday = Column(Boolean, default=False, nullable=False)
|
||||||
|
newsletter_publish_none = Column(Boolean, default=False, nullable=False)
|
||||||
|
|
||||||
|
# Volunteer Interests (Step 2)
|
||||||
|
volunteer_interests = Column(JSON, default=list)
|
||||||
|
|
||||||
|
# Scholarship Request (Step 2)
|
||||||
|
scholarship_requested = Column(Boolean, default=False, nullable=False)
|
||||||
|
scholarship_reason = Column(Text, nullable=True)
|
||||||
|
|
||||||
|
# Directory Settings (Step 3)
|
||||||
|
show_in_directory = Column(Boolean, default=False, nullable=False)
|
||||||
|
directory_email = Column(String, nullable=True)
|
||||||
|
directory_bio = Column(Text, nullable=True)
|
||||||
|
directory_address = Column(String, nullable=True)
|
||||||
|
directory_phone = Column(String, nullable=True)
|
||||||
|
directory_dob = Column(DateTime, nullable=True)
|
||||||
|
directory_partner_name = Column(String, nullable=True)
|
||||||
|
|
||||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||||
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||||
|
|
||||||
|
|||||||
75
server.py
75
server.py
@@ -59,8 +59,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# Pydantic Models
|
# Pydantic Models
|
||||||
class RegisterRequest(BaseModel):
|
class RegisterRequest(BaseModel):
|
||||||
email: EmailStr
|
# Step 1: Personal & Partner Information
|
||||||
password: str = Field(min_length=6)
|
|
||||||
first_name: str
|
first_name: str
|
||||||
last_name: str
|
last_name: str
|
||||||
phone: str
|
phone: str
|
||||||
@@ -74,7 +73,48 @@ class RegisterRequest(BaseModel):
|
|||||||
partner_last_name: Optional[str] = None
|
partner_last_name: Optional[str] = None
|
||||||
partner_is_member: Optional[bool] = False
|
partner_is_member: Optional[bool] = False
|
||||||
partner_plan_to_become_member: Optional[bool] = False
|
partner_plan_to_become_member: Optional[bool] = False
|
||||||
|
|
||||||
|
# Step 2: Newsletter, Volunteer & Scholarship
|
||||||
referred_by_member_name: Optional[str] = None
|
referred_by_member_name: Optional[str] = None
|
||||||
|
newsletter_publish_name: bool
|
||||||
|
newsletter_publish_photo: bool
|
||||||
|
newsletter_publish_birthday: bool
|
||||||
|
newsletter_publish_none: bool
|
||||||
|
volunteer_interests: List[str] = []
|
||||||
|
scholarship_requested: bool = False
|
||||||
|
scholarship_reason: Optional[str] = None
|
||||||
|
|
||||||
|
# Step 3: Directory Settings
|
||||||
|
show_in_directory: bool = False
|
||||||
|
directory_email: Optional[str] = None
|
||||||
|
directory_bio: Optional[str] = None
|
||||||
|
directory_address: Optional[str] = None
|
||||||
|
directory_phone: Optional[str] = None
|
||||||
|
directory_dob: Optional[datetime] = None
|
||||||
|
directory_partner_name: Optional[str] = None
|
||||||
|
|
||||||
|
# Step 4: Account Credentials
|
||||||
|
email: EmailStr
|
||||||
|
password: str = Field(min_length=6)
|
||||||
|
|
||||||
|
@validator('newsletter_publish_none')
|
||||||
|
def validate_newsletter_preferences(cls, v, values):
|
||||||
|
"""At least one newsletter preference must be selected"""
|
||||||
|
name = values.get('newsletter_publish_name', False)
|
||||||
|
photo = values.get('newsletter_publish_photo', False)
|
||||||
|
birthday = values.get('newsletter_publish_birthday', False)
|
||||||
|
|
||||||
|
if not (name or photo or birthday or v):
|
||||||
|
raise ValueError('At least one newsletter publication preference must be selected')
|
||||||
|
return v
|
||||||
|
|
||||||
|
@validator('scholarship_reason')
|
||||||
|
def validate_scholarship_reason(cls, v, values):
|
||||||
|
"""If scholarship requested, reason must be provided"""
|
||||||
|
requested = values.get('scholarship_requested', False)
|
||||||
|
if requested and not v:
|
||||||
|
raise ValueError('Scholarship reason is required when requesting scholarship')
|
||||||
|
return v
|
||||||
|
|
||||||
class LoginRequest(BaseModel):
|
class LoginRequest(BaseModel):
|
||||||
email: EmailStr
|
email: EmailStr
|
||||||
@@ -179,8 +219,11 @@ async def register(request: RegisterRequest, db: Session = Depends(get_db)):
|
|||||||
|
|
||||||
# Create user
|
# Create user
|
||||||
user = User(
|
user = User(
|
||||||
|
# Account credentials (Step 4)
|
||||||
email=request.email,
|
email=request.email,
|
||||||
password_hash=get_password_hash(request.password),
|
password_hash=get_password_hash(request.password),
|
||||||
|
|
||||||
|
# Personal information (Step 1)
|
||||||
first_name=request.first_name,
|
first_name=request.first_name,
|
||||||
last_name=request.last_name,
|
last_name=request.last_name,
|
||||||
phone=request.phone,
|
phone=request.phone,
|
||||||
@@ -190,11 +233,39 @@ async def register(request: RegisterRequest, db: Session = Depends(get_db)):
|
|||||||
zipcode=request.zipcode,
|
zipcode=request.zipcode,
|
||||||
date_of_birth=request.date_of_birth,
|
date_of_birth=request.date_of_birth,
|
||||||
lead_sources=request.lead_sources,
|
lead_sources=request.lead_sources,
|
||||||
|
|
||||||
|
# Partner information (Step 1)
|
||||||
partner_first_name=request.partner_first_name,
|
partner_first_name=request.partner_first_name,
|
||||||
partner_last_name=request.partner_last_name,
|
partner_last_name=request.partner_last_name,
|
||||||
partner_is_member=request.partner_is_member,
|
partner_is_member=request.partner_is_member,
|
||||||
partner_plan_to_become_member=request.partner_plan_to_become_member,
|
partner_plan_to_become_member=request.partner_plan_to_become_member,
|
||||||
|
|
||||||
|
# Referral (Step 2)
|
||||||
referred_by_member_name=request.referred_by_member_name,
|
referred_by_member_name=request.referred_by_member_name,
|
||||||
|
|
||||||
|
# Newsletter publication preferences (Step 2)
|
||||||
|
newsletter_publish_name=request.newsletter_publish_name,
|
||||||
|
newsletter_publish_photo=request.newsletter_publish_photo,
|
||||||
|
newsletter_publish_birthday=request.newsletter_publish_birthday,
|
||||||
|
newsletter_publish_none=request.newsletter_publish_none,
|
||||||
|
|
||||||
|
# Volunteer interests (Step 2)
|
||||||
|
volunteer_interests=request.volunteer_interests,
|
||||||
|
|
||||||
|
# Scholarship (Step 2)
|
||||||
|
scholarship_requested=request.scholarship_requested,
|
||||||
|
scholarship_reason=request.scholarship_reason,
|
||||||
|
|
||||||
|
# Directory settings (Step 3)
|
||||||
|
show_in_directory=request.show_in_directory,
|
||||||
|
directory_email=request.directory_email,
|
||||||
|
directory_bio=request.directory_bio,
|
||||||
|
directory_address=request.directory_address,
|
||||||
|
directory_phone=request.directory_phone,
|
||||||
|
directory_dob=request.directory_dob,
|
||||||
|
directory_partner_name=request.directory_partner_name,
|
||||||
|
|
||||||
|
# Status fields
|
||||||
status=UserStatus.pending_email,
|
status=UserStatus.pending_email,
|
||||||
role=UserRole.guest,
|
role=UserRole.guest,
|
||||||
email_verified=False,
|
email_verified=False,
|
||||||
|
|||||||
Reference in New Issue
Block a user