-
Notifications
You must be signed in to change notification settings - Fork 0
Implement Company & Product Management with JWT Authentication and PostgreSQL Integration #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
| from fastapi.security import HTTPAuthorizationCredentials | ||
|
|
||
|
|
||
| SECRET_KEY = "af3287c8391bb9f4f7a72feb3b85f72e1d5bd07cbf4fa4ad9497c78412923312" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this must be in .env file not here jut import this here
| @router.post("/register", response_model=UserResponse) | ||
| def register(user: UserCreate, db: Session = Depends(get_db)): | ||
| service = UserService(db) | ||
| try: | ||
| return service.create_user(user) | ||
| except ValueError as e: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
insterad of passing session in args do it like you have used service here
| def login(user: UserCreate, db: Session = Depends(get_db)): | ||
| # ✅ Query using database model | ||
| db_user = db.query(User).filter(User.username == user.username).first() | ||
|
|
||
| if not db_user or not verify_password(user.password, db_user.password): | ||
| raise HTTPException( | ||
| status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials") | ||
|
|
||
| token = create_access_token(db_user.id) | ||
| return {"access_token": token, "token_type": "bearer"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
| @router.get("/me", response_model=CompanyResponse) | ||
| def get_my_company( | ||
| db: Session = Depends(get_db), | ||
| current_user=Depends(get_current_user) | ||
| ): | ||
| service = CompanyService(db) | ||
| return service.get_my_company(current_user.id) | ||
|
|
||
|
|
||
| @router.put("/me", response_model=CompanyResponse) | ||
| def edit_my_company( | ||
| company: CompanyCreate, | ||
| db: Session = Depends(get_db), | ||
| current_user=Depends(get_current_user) | ||
| ): | ||
| service = CompanyService(db) | ||
| return service.edit_company(current_user.id, company) | ||
|
|
||
|
|
||
| @router.delete("/me", dependencies=[Depends(get_current_user)]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
define routes properly there is not a thing ever used which says me in routes
|
|
||
|
|
||
| class Company(Base): | ||
| __tablename__ = "companies" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
table name must be singular
| class UserCreate(BaseModel): | ||
| username: str | ||
| password: str | ||
|
|
||
|
|
||
| class UserResponse(BaseModel): | ||
| id: int | ||
| username: str | ||
| password: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
| existing = self.db.query(Company).filter( | ||
| Company.user_id == user_id).first() | ||
| if existing: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_400_BAD_REQUEST, detail="user already has a company") | ||
|
|
||
| new_company = Company( | ||
| name=company_data.name, | ||
| location=company_data.location, | ||
| user_id=user_id | ||
| ) | ||
| self.db.add(new_company) | ||
| self.db.commit() | ||
| self.db.refresh(new_company) | ||
| return new_company |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of doing data base related functionality in service do it in repository here in service we will only have the logic need scenarios only
why you are using db.refresh here also
|
|
||
| def get_my_company(self, user_id: int): | ||
| company = self.db.query(Company).filter( | ||
| Company.user_id == user_id).first() | ||
| if not company: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_404_NOT_FOUND, detail="Company not found") | ||
| return company | ||
|
|
||
| def edit_company(self, user_id: int, company_data: CompanyCreate): | ||
| company = self.db.query(Company).filter( | ||
| Company.user_id == user_id | ||
| ).first() | ||
| if not company: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_404_NOT_FOUND, detail="company not found" | ||
| ) | ||
| company.name = company_data.name | ||
| company.location = company_data.location | ||
| self.db.commit() | ||
| self.db.refresh(company) | ||
| return company | ||
|
|
||
| def delete_company(self, user_id: int): | ||
| company = self.db.query(Company).filter( | ||
| Company.user_id == user_id | ||
| ).first() | ||
| if not company: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_404_NOT_FOUND, detail="company not found" | ||
| ) | ||
| self.db.delete(company) | ||
| self.db.commit() | ||
| return {"detail": "company deleted"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
dont do hard code return response
| def create_product(self, company_id: int, product_data: ProductCreate): | ||
| new_product = Product( | ||
| name=product_data.name, | ||
| price=product_data.price, | ||
| description=product_data.description, | ||
| company_id=company_id | ||
| ) | ||
| self.db.add(new_product) | ||
| self.db.commit() | ||
| self.db.refresh(new_product) | ||
| return new_product | ||
|
|
||
| def list_products(self): | ||
| products = self.db.query(Product).all() | ||
| return products | ||
|
|
||
| def get_product(self, product_id: int): | ||
| product = self.db.query(Product).filter( | ||
| Product.id == product_id).first() | ||
| if not product: | ||
| raise HTTPException(status_code=404, detail="Product not found") | ||
| return product | ||
|
|
||
| def update_product(self, product_id: int, product_data: ProductCreate): | ||
| product = self.get_product(product_id) | ||
| product.name = product_data.name | ||
| product.price = product_data.price | ||
| product.description = product_data.description | ||
| self.db.commit() | ||
| self.db.refresh(product) | ||
| return product | ||
|
|
||
| def delete_product(self, product_id: int): | ||
| product = self.get_product(product_id) | ||
| self.db.delete(product) | ||
| self.db.commit() | ||
| return {"detail": "Product deleted"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
| def create_user(self, user: UserCreate): | ||
| db_user = self.db.query(User).filter( | ||
| User.username == user.username).first() | ||
| if db_user: | ||
| raise ValueError("Username already registered") | ||
| hashed_pw = get_password_hash(user.password) | ||
| new_user = User(username=user.username, password=hashed_pw) | ||
| self.db.add(new_user) | ||
| self.db.commit() | ||
| self.db.refresh(new_user) | ||
| return new_user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
Key Features:
Users can register and log in using secure JWT authentication with Bearer tokens.
Each user can create only one company linked to their account.
Users (through their company) can create and manage multiple products.
Fully configured with PostgreSQL for persistent data storage.
Introduced service classes for clean separation of business logic.
Used HTTPBearer with JWT for secure access to protected routes.