feat: add Go models for User and UserProfile

- Create models/user.go with bcrypt password hashing
- Create models/user_profile.go with foreign key relationship
- Add GORM hooks for automatic profile creation
- Include proper JSON tags and database constraints
This commit is contained in:
Cipher Vance 2025-09-18 20:06:36 -05:00
parent e40a119bdc
commit 3ed698918b
5 changed files with 52 additions and 75 deletions

View file

@ -1,40 +0,0 @@
from models.UserProfile.user_profile import UserProfile
from werkzeug.security import generate_password_hash, check_password_hash
from models import db
from sqlalchemy import event
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False) # Add email field
_password = db.Column("password", db.String(255), nullable=False)
profile = db.relationship('UserProfile', back_populates='user', uselist=False, cascade="all, delete-orphan")
@property
def password(self):
return self._password
@password.setter
def password(self, raw_password):
if not raw_password.startswith("pbkdf2:sha256:"):
self._password = generate_password_hash(raw_password)
else:
self._password = raw_password
def check_password(self, password):
return check_password_hash(self._password, password)
@event.listens_for(User, 'after_insert')
def create_user_profile(mapper, connection, target):
connection.execute(
UserProfile.__table__.insert().values(
user_id=target.id,
first_name="",
last_name="",
bio="",
profile_picture=""
)
)

View file

@ -1,13 +0,0 @@
from models import db
class UserProfile(db.Model):
__tablename__ = 'user_profiles'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
first_name = db.Column(db.String(50), nullable=False, default="")
last_name = db.Column(db.String(50), nullable=False, default="")
bio = db.Column(db.Text, default="")
profile_picture = db.Column(db.String(255), default="")
user = db.relationship('User', back_populates='profile')

View file

@ -1,22 +0,0 @@
import os
from flask_sqlalchemy import SQLAlchemy
from dotenv import load_dotenv
from urllib.parse import quote_plus
load_dotenv()
PG_USER = quote_plus(os.getenv("PG_USER", "postgres"))
PG_PASSWORD = quote_plus(os.getenv("PG_PASSWORD", "postgres"))
PG_HOST = os.getenv("PG_HOST", "localhost")
PG_PORT = os.getenv("PG_PORT", "5432")
PG_DATABASE = os.getenv("PG_DATABASE", "rideaware")
DATABASE_URI = f"postgresql+psycopg2://{PG_USER}:{PG_PASSWORD}@{PG_HOST}:{PG_PORT}/{PG_DATABASE}"
db = SQLAlchemy()
def init_db(app):
"""Initialize the SQLAlchemy app with the configuration."""
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)

40
models/user.go Normal file
View file

@ -0,0 +1,40 @@
package models
import (
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"unique;not null;size:80" json:"username"`
Email string `gorm:"unique;not null;size:255" json:"email"` // Add this line
Password string `gorm:"not null;size:255" json:"-"`
Profile *UserProfile `gorm:"constraint:OnDelete:CASCADE;" json:"profile,omitempty"`
}
func (u *User) SetPassword(password string) error {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return err
}
u.Password = string(hashedPassword)
return nil
}
func (u *User) CheckPassword(password string) bool {
err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
return err == nil
}
func (u *User) AfterCreate(tx *gorm.DB) error {
profile := UserProfile{
UserID: u.ID,
FirstName: "",
LastName: "",
Bio: "",
ProfilePicture: "",
}
return tx.Create(&profile).Error
}

12
models/user_profile.go Normal file
View file

@ -0,0 +1,12 @@
package models
type UserProfile struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"not null" json:"user_id"`
FirstName string `gorm:"size:80;not null" json:"first_name"`
LastName string `gorm:"size:80;not null" json:"last_name"`
Bio string `gorm:"type:text" json:"bio"`
ProfilePicture string `gorm:"size:255" json:"profile_picture"`
User *User `gorm:"foreignKey:UserID" json:"user,omitempty"`
}