From 415206ad1af4761ceb8c6dbaa516826f45adc0f4 Mon Sep 17 00:00:00 2001
From: pmoharana-cmd <pmoharana032474@gmail.com>
Date: Sat, 4 Jan 2025 16:10:09 -0500
Subject: [PATCH] Add create user endpoint and update model/entity

---
 backend/api/user.py             | 13 ++++++++++--
 backend/entities/user_entity.py |  4 ++--
 backend/models/user_model.py    |  8 ++++----
 backend/services/user.py        | 35 ++++++++++++++-------------------
 4 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/backend/api/user.py b/backend/api/user.py
index b7ec372..cda0a58 100644
--- a/backend/api/user.py
+++ b/backend/api/user.py
@@ -16,8 +16,8 @@ openapi_tags = {
 # TODO: Enable authorization by passing user uuid to API
 # TODO: Create custom exceptions
 @api.get("/all", response_model=List[User], tags=["Users"])
-def get_all(user_id: str, user_svc: UserService = Depends()):
-    subject = user_svc.get_user_by_uuid(user_id)
+def get_all(uuid: str, user_svc: UserService = Depends()):
+    subject = user_svc.get_user_by_uuid(uuid)
 
     if subject.role != UserTypeEnum.ADMIN:
         raise Exception(f"Insufficient permissions for user {subject.uuid}")
@@ -28,3 +28,12 @@ def get_all(user_id: str, user_svc: UserService = Depends()):
 @api.get("/{user_id}", response_model=User, tags=["Users"])
 def get_by_uuid(user_id: str, user_svc: UserService = Depends()):
     return user_svc.get_user_by_uuid(user_id)
+
+
+@api.post("/create", response_model=User, tags=["Users"])
+def create_user(uuid: str, user: User, user_svc: UserService = Depends()):
+    subject = user_svc.get_user_by_uuid(uuid)
+    if subject.role != UserTypeEnum.ADMIN:
+        raise Exception(f"Insufficient permissions for user {subject.uuid}")
+
+    return user_svc.create(user)
diff --git a/backend/entities/user_entity.py b/backend/entities/user_entity.py
index ca66ee9..3d4cdd7 100644
--- a/backend/entities/user_entity.py
+++ b/backend/entities/user_entity.py
@@ -38,8 +38,8 @@ class UserEntity(EntityBase):
     program: Mapped[list[ProgramTypeEnum]] = mapped_column(
         ARRAY(Enum(ProgramTypeEnum)), nullable=False
     )
-    experience: Mapped[int] = mapped_column(Integer, nullable=False)
-    group: Mapped[str] = mapped_column(String(50))
+    experience: Mapped[int] = mapped_column(Integer, nullable=True)
+    group: Mapped[str] = mapped_column(String(50), nullable=True)
     uuid: Mapped[str] = mapped_column(String, nullable=True)
 
     @classmethod
diff --git a/backend/models/user_model.py b/backend/models/user_model.py
index e2c25da..60c3007 100644
--- a/backend/models/user_model.py
+++ b/backend/models/user_model.py
@@ -10,9 +10,9 @@ class User(BaseModel):
     id: int | None = None
     username: str = Field(..., description="The username of the user")
     email: str = Field(..., description="The e-mail of the user")
-    experience: int = Field(..., description="Years of Experience of the User")
-    group: str
-    program: List[ProgramTypeEnum]
-    role: UserTypeEnum
+    experience: int | None = Field(None, description="Years of Experience of the User")
+    group: str | None = Field(None, description="The group of the user")
+    program: List[ProgramTypeEnum] | None = None
+    role: UserTypeEnum | None = None
     created_at: Optional[datetime] = datetime.now()
     uuid: str | None = None
diff --git a/backend/services/user.py b/backend/services/user.py
index 360db01..59bc5c4 100644
--- a/backend/services/user.py
+++ b/backend/services/user.py
@@ -61,22 +61,21 @@ class UserService:
 
         """
         try:
-            if (user.id != None):
+            if user.id != None:
                 user = self.get_user_by_id(user.id)
+            else:
+                user_entity = UserEntity.from_model(user)
+                # add new user to table
+                self._session.add(user_entity)
+                self._session.commit()
         except:
-            # if does not exist, create new object
-            user_entity = UserEntity.from_model(user)
+            raise Exception(f"Failed to create user")
 
-            # add new user to table
-            self._session.add(user_entity)
-            self._session.commit()
-        finally:
-            # return added object
-            return user
-        
-    def delete(self, user: User) -> None:   
+        return user
+
+    def delete(self, user: User) -> None:
         """
-        Delete a user 
+        Delete a user
 
         Args: the user to delete
 
@@ -86,25 +85,23 @@ class UserService:
 
         if obj is None:
             raise Exception(f"No matching user found")
-        
+
         self._session.delete(obj)
         self._session.commit()
 
-
-
-    def update(self, user: User) -> User: 
+    def update(self, user: User) -> User:
         """
         Updates a user
 
         Args: User to be updated
 
         Returns: The updated User
-        """   
+        """
         obj = self._session.get(UserEntity, user.id)
 
         if obj is None:
             raise Exception(f"No matching user found")
-        
+
         obj.username = user.username
         obj.role = user.role
         obj.email = user.email
@@ -115,5 +112,3 @@ class UserService:
         self._session.commit()
 
         return obj.to_model()
-
-