Merge pull request #19 from abhi1693/jarvis/default-reviewer-to-manager

Default reviewer = assignee manager; remove reviewer from task create UI
This commit is contained in:
Abhimanyu Saharan
2026-02-02 17:58:04 +05:30
committed by GitHub
2 changed files with 8 additions and 9 deletions

View File

@@ -8,6 +8,7 @@ from sqlalchemy.exc import IntegrityError
from app.api.utils import log_activity, get_actor_employee_id
from app.db.session import get_session
from app.models.org import Employee
from app.models.work import Task, TaskComment
from app.schemas.work import TaskCommentCreate, TaskCreate, TaskUpdate
from app.integrations.notify import NotifyContext, notify_openclaw
@@ -30,6 +31,12 @@ def create_task(payload: TaskCreate, background: BackgroundTasks, session: Sessi
if payload.created_by_employee_id is None:
payload = TaskCreate(**{**payload.model_dump(), "created_by_employee_id": actor_employee_id})
# Default reviewer to the manager of the assignee (if not explicitly provided).
if payload.reviewer_employee_id is None and payload.assignee_employee_id is not None:
assignee = session.get(Employee, payload.assignee_employee_id)
if assignee is not None and assignee.manager_id is not None:
payload = TaskCreate(**{**payload.model_dump(), "reviewer_employee_id": assignee.manager_id})
task = Task(**payload.model_dump())
if task.status not in ALLOWED_STATUSES:
raise HTTPException(status_code=400, detail="Invalid status")

View File

@@ -79,7 +79,6 @@ export default function ProjectDetailPage() {
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [assigneeId, setAssigneeId] = useState<string>("");
const [reviewerId, setReviewerId] = useState<string>("");
const [commentTaskId, setCommentTaskId] = useState<number | null>(null);
const [replyToCommentId, setReplyToCommentId] = useState<number | null>(null);
@@ -152,19 +151,13 @@ export default function ProjectDetailPage() {
{createTask.error ? <div className="text-sm text-destructive">{(createTask.error as Error).message}</div> : null}
<Input placeholder="Title" value={title} onChange={(e) => setTitle(e.target.value)} />
<Textarea placeholder="Description" value={description} onChange={(e) => setDescription(e.target.value)} />
<div className="grid grid-cols-2 gap-2">
<div className="grid grid-cols-1 gap-2">
<Select value={assigneeId} onChange={(e) => setAssigneeId(e.target.value)}>
<option value="">Assignee</option>
{employeeList.map((e) => (
<option key={e.id ?? e.name} value={e.id ?? ""}>{e.name}</option>
))}
</Select>
<Select value={reviewerId} onChange={(e) => setReviewerId(e.target.value)}>
<option value="">Reviewer</option>
{employeeList.map((e) => (
<option key={e.id ?? e.name} value={e.id ?? ""}>{e.name}</option>
))}
</Select>
</div>
<Button
onClick={() =>
@@ -175,7 +168,6 @@ export default function ProjectDetailPage() {
description: description.trim() ? description : null,
status: "backlog",
assignee_employee_id: assigneeId ? Number(assigneeId) : null,
reviewer_employee_id: reviewerId ? Number(reviewerId) : null,
},
})
}