- First Name - Required on creation, read-only after
- Surname - Required on creation, read-only after
- Date of Birth - Required on creation, read-only after
- Address - Can be updated anytime
- PPSN - Optional for testing, read-only after creation
- Civic Interests - Can be updated anytime (multi-select)
- ✅ Name, Surname, PPSN cannot be changed after initial creation
- ✅ Address and Civic Interests can be updated anytime
- ✅ All profile operations require authentication
The user_profiles table needs to be created:
npm run migrateThis will create the user_profiles table in your database.
After running migrations, restart your server:
# In server terminal
# Press Ctrl+C to stop, then:
npm run dev- User registers → Redirected to
/profile - User fills in all fields:
- First Name (required)
- Surname (required)
- Date of Birth (required)
- Address (required)
- PPSN (optional for testing)
- Civic Interests (select multiple)
- Clicks "Save Profile"
- Profile created in database
- User clicks "Profile" in navbar
- Sees their existing profile
- Name, Surname, PPSN, Date of Birth are disabled/read-only
- Can only update:
- Address
- Civic Interests
- Clicks "Save Profile"
- Only address and interests are updated
Solution: Run migrations:
npm run migrateCheck:
- PostgreSQL is running
DATABASE_URLinserver/.envis correct- Database
civicfixexists
Check:
- Profile was successfully created
- Browser cache (try hard refresh: Ctrl+F5)
- Check browser console for errors
- Register a new user
- Fill in profile (all fields)
- Save - Should see success message
- Navigate away and come back
- Check that Name, Surname, PPSN are disabled
- Update Address and Interests
- Save - Should work!
GET /api/profile
Headers: Authorization: Bearer <token>
Response: { profile: {...} | null }
PUT /api/profile
Headers: Authorization: Bearer <token>
Body: {
firstName, surname, dateOfBirth, address, ppsn, civicInterests
}
Note: On update, only address and civicInterests are actually updated. Other fields are ignored.
The profile system is ready! Just run the migration first! 🚀